test_detection.py 42.8 KB
Newer Older
1
#   Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
2 3 4 5 6 7 8 9 10 11 12 13 14
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

15 16
import paddle.fluid as fluid
import paddle.fluid.layers as layers
17
from paddle.fluid.layers import detection
18
from paddle.fluid.framework import Program, program_guard
C
chengduoZH 已提交
19
import unittest
20 21 22 23 24
import contextlib
import numpy as np
from unittests.test_imperative_base import new_program_scope
from paddle.fluid.dygraph import base
from paddle.fluid import core
P
pangyoki 已提交
25 26 27
import paddle

paddle.enable_static()
28 29 30


class LayerTest(unittest.TestCase):
31

32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
    @classmethod
    def setUpClass(cls):
        cls.seed = 111

    @classmethod
    def tearDownClass(cls):
        pass

    def _get_place(self, force_to_use_cpu=False):
        # this option for ops that only have cpu kernel
        if force_to_use_cpu:
            return core.CPUPlace()
        else:
            if core.is_compiled_with_cuda():
                return core.CUDAPlace(0)
            return core.CPUPlace()

    @contextlib.contextmanager
    def static_graph(self):
        with new_program_scope():
            fluid.default_startup_program().random_seed = self.seed
            fluid.default_main_program().random_seed = self.seed
            yield

    def get_static_graph_result(self,
                                feed,
                                fetch_list,
                                with_lod=False,
                                force_to_use_cpu=False):
        exe = fluid.Executor(self._get_place(force_to_use_cpu))
        exe.run(fluid.default_startup_program())
        return exe.run(fluid.default_main_program(),
                       feed=feed,
                       fetch_list=fetch_list,
                       return_numpy=(not with_lod))

    @contextlib.contextmanager
    def dynamic_graph(self, force_to_use_cpu=False):
        with fluid.dygraph.guard(
                self._get_place(force_to_use_cpu=force_to_use_cpu)):
            fluid.default_startup_program().random_seed = self.seed
            fluid.default_main_program().random_seed = self.seed
            yield
75 76


77
class TestDetection(unittest.TestCase):
78

79 80 81
    def test_detection_output(self):
        program = Program()
        with program_guard(program):
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
            pb = layers.data(name='prior_box',
                             shape=[10, 4],
                             append_batch_size=False,
                             dtype='float32')
            pbv = layers.data(name='prior_box_var',
                              shape=[10, 4],
                              append_batch_size=False,
                              dtype='float32')
            loc = layers.data(name='target_box',
                              shape=[2, 10, 4],
                              append_batch_size=False,
                              dtype='float32')
            scores = layers.data(name='scores',
                                 shape=[2, 10, 20],
                                 append_batch_size=False,
                                 dtype='float32')
            out = layers.detection_output(scores=scores,
                                          loc=loc,
                                          prior_box=pb,
                                          prior_box_var=pbv)
            out2, index = layers.detection_output(scores=scores,
                                                  loc=loc,
                                                  prior_box=pb,
                                                  prior_box_var=pbv,
                                                  return_index=True)
107
            self.assertIsNotNone(out)
108 109
            self.assertIsNotNone(out2)
            self.assertIsNotNone(index)
110
            self.assertEqual(out.shape[-1], 6)
111
        print(str(program))
112

J
jerrywgz 已提交
113 114 115 116 117
    def test_box_coder_api(self):
        program = Program()
        with program_guard(program):
            x = layers.data(name='x', shape=[4], dtype='float32')
            y = layers.data(name='z', shape=[4], dtype='float32', lod_level=1)
118 119 120 121
            bcoder = layers.box_coder(prior_box=x,
                                      prior_box_var=[0.1, 0.2, 0.1, 0.2],
                                      target_box=y,
                                      code_type='encode_center_size')
J
jerrywgz 已提交
122 123 124
            self.assertIsNotNone(bcoder)
        print(str(program))

125 126 127 128
    def test_box_coder_error(self):
        program = Program()
        with program_guard(program):
            x1 = fluid.data(name='x1', shape=[10, 4], dtype='int32')
129 130 131 132
            y1 = fluid.data(name='y1',
                            shape=[10, 4],
                            dtype='float32',
                            lod_level=1)
133
            x2 = fluid.data(name='x2', shape=[10, 4], dtype='float32')
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
            y2 = fluid.data(name='y2',
                            shape=[10, 4],
                            dtype='int32',
                            lod_level=1)

            self.assertRaises(TypeError,
                              layers.box_coder,
                              prior_box=x1,
                              prior_box_var=[0.1, 0.2, 0.1, 0.2],
                              target_box=y1,
                              code_type='encode_center_size')
            self.assertRaises(TypeError,
                              layers.box_coder,
                              prior_box=x2,
                              prior_box_var=[0.1, 0.2, 0.1, 0.2],
                              target_box=y2,
                              code_type='encode_center_size')
151

152 153 154 155 156 157 158
    def test_detection_api(self):
        program = Program()
        with program_guard(program):
            x = layers.data(name='x', shape=[4], dtype='float32')
            y = layers.data(name='y', shape=[4], dtype='float32')
            z = layers.data(name='z', shape=[4], dtype='float32', lod_level=1)
            iou = layers.iou_similarity(x=x, y=y)
159 160 161 162
            bcoder = layers.box_coder(prior_box=x,
                                      prior_box_var=y,
                                      target_box=z,
                                      code_type='encode_center_size')
163 164 165 166 167 168 169
            self.assertIsNotNone(iou)
            self.assertIsNotNone(bcoder)

            matched_indices, matched_dist = layers.bipartite_match(iou)
            self.assertIsNotNone(matched_indices)
            self.assertIsNotNone(matched_dist)

170 171 172 173 174 175 176
            gt = layers.data(name='gt',
                             shape=[1, 1],
                             dtype='int32',
                             lod_level=1)
            trg, trg_weight = layers.target_assign(gt,
                                                   matched_indices,
                                                   mismatch_value=0)
177 178 179
            self.assertIsNotNone(trg)
            self.assertIsNotNone(trg_weight)

180 181 182 183 184 185 186
            gt2 = layers.data(name='gt2',
                              shape=[10, 4],
                              dtype='float32',
                              lod_level=1)
            trg, trg_weight = layers.target_assign(gt2,
                                                   matched_indices,
                                                   mismatch_value=0)
187 188 189
            self.assertIsNotNone(trg)
            self.assertIsNotNone(trg_weight)

190
        print(str(program))
191 192 193 194

    def test_ssd_loss(self):
        program = Program()
        with program_guard(program):
195 196 197 198 199 200 201 202
            pb = layers.data(name='prior_box',
                             shape=[10, 4],
                             append_batch_size=False,
                             dtype='float32')
            pbv = layers.data(name='prior_box_var',
                              shape=[10, 4],
                              append_batch_size=False,
                              dtype='float32')
203 204
            loc = layers.data(name='target_box', shape=[10, 4], dtype='float32')
            scores = layers.data(name='scores', shape=[10, 21], dtype='float32')
205 206 207 208 209 210 211 212
            gt_box = layers.data(name='gt_box',
                                 shape=[4],
                                 lod_level=1,
                                 dtype='float32')
            gt_label = layers.data(name='gt_label',
                                   shape=[1],
                                   lod_level=1,
                                   dtype='int32')
213 214 215
            loss = layers.ssd_loss(loc, scores, gt_box, gt_label, pb, pbv)
            self.assertIsNotNone(loss)
            self.assertEqual(loss.shape[-1], 1)
216
        print(str(program))
217 218


219
class TestPriorBox(unittest.TestCase):
220

221
    def test_prior_box(self):
222 223 224
        program = Program()
        with program_guard(program):
            data_shape = [3, 224, 224]
225 226 227
            images = fluid.layers.data(name='pixel',
                                       shape=data_shape,
                                       dtype='float32')
228
            conv1 = fluid.layers.conv2d(images, 3, 3, 2)
229 230 231 232 233 234
            box, var = layers.prior_box(input=conv1,
                                        image=images,
                                        min_sizes=[100.0],
                                        aspect_ratios=[1.],
                                        flip=True,
                                        clip=True)
235 236 237 238 239 240
            assert len(box.shape) == 4
            assert box.shape == var.shape
            assert box.shape[3] == 4


class TestPriorBox2(unittest.TestCase):
241

242 243 244 245 246 247
    def test_prior_box(self):
        program = Program()
        with program_guard(program):
            data_shape = [None, 3, None, None]
            images = fluid.data(name='pixel', shape=data_shape, dtype='float32')
            conv1 = fluid.layers.conv2d(images, 3, 3, 2)
248 249 250 251 252 253
            box, var = layers.prior_box(input=conv1,
                                        image=images,
                                        min_sizes=[100.0],
                                        aspect_ratios=[1.],
                                        flip=True,
                                        clip=True)
254 255 256
            assert len(box.shape) == 4
            assert box.shape == var.shape
            assert box.shape[3] == 4
257 258


R
ruri 已提交
259
class TestDensityPriorBox(unittest.TestCase):
260

R
ruri 已提交
261
    def test_density_prior_box(self):
262 263 264
        program = Program()
        with program_guard(program):
            data_shape = [3, 224, 224]
265 266 267
            images = fluid.layers.data(name='pixel',
                                       shape=data_shape,
                                       dtype='float32')
268
            conv1 = fluid.layers.conv2d(images, 3, 3, 2)
269 270 271 272 273 274
            box, var = layers.density_prior_box(input=conv1,
                                                image=images,
                                                densities=[3, 4],
                                                fixed_sizes=[50., 60.],
                                                fixed_ratios=[1.0],
                                                clip=True)
275 276 277
            assert len(box.shape) == 4
            assert box.shape == var.shape
            assert box.shape[-1] == 4
R
ruri 已提交
278 279


280
class TestAnchorGenerator(unittest.TestCase):
281

282 283
    def test_anchor_generator(self):
        data_shape = [3, 224, 224]
284 285 286
        images = fluid.layers.data(name='pixel',
                                   shape=data_shape,
                                   dtype='float32')
287 288 289 290 291 292 293 294 295 296 297 298 299
        conv1 = fluid.layers.conv2d(images, 3, 3, 2)
        anchor, var = fluid.layers.anchor_generator(
            input=conv1,
            anchor_sizes=[64, 128, 256, 512],
            aspect_ratios=[0.5, 1.0, 2.0],
            variance=[0.1, 0.1, 0.2, 0.2],
            stride=[16.0, 16.0],
            offset=0.5)
        assert len(anchor.shape) == 4
        assert anchor.shape == var.shape
        assert anchor.shape[3] == 4


300
class TestGenerateProposalLabels(unittest.TestCase):
301

302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
    def check_out(self, outs):
        rois = outs[0]
        labels_int32 = outs[1]
        bbox_targets = outs[2]
        bbox_inside_weights = outs[3]
        bbox_outside_weights = outs[4]
        assert rois.shape[1] == 4
        assert rois.shape[0] == labels_int32.shape[0]
        assert rois.shape[0] == bbox_targets.shape[0]
        assert rois.shape[0] == bbox_inside_weights.shape[0]
        assert rois.shape[0] == bbox_outside_weights.shape[0]
        assert bbox_targets.shape[1] == 4 * self.class_nums
        assert bbox_inside_weights.shape[1] == 4 * self.class_nums
        assert bbox_outside_weights.shape[1] == 4 * self.class_nums
        if len(outs) == 6:
            max_overlap_with_gt = outs[5]
            assert max_overlap_with_gt.shape[0] == rois.shape[0]

320
    def test_generate_proposal_labels(self):
321 322
        program = Program()
        with program_guard(program):
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338
            rpn_rois = fluid.data(name='rpn_rois',
                                  shape=[4, 4],
                                  dtype='float32',
                                  lod_level=1)
            gt_classes = fluid.data(name='gt_classes',
                                    shape=[6],
                                    dtype='int32',
                                    lod_level=1)
            is_crowd = fluid.data(name='is_crowd',
                                  shape=[6],
                                  dtype='int32',
                                  lod_level=1)
            gt_boxes = fluid.data(name='gt_boxes',
                                  shape=[6, 4],
                                  dtype='float32',
                                  lod_level=1)
339
            im_info = fluid.data(name='im_info', shape=[1, 3], dtype='float32')
340 341 342 343
            max_overlap = fluid.data(name='max_overlap',
                                     shape=[4],
                                     dtype='float32',
                                     lod_level=1)
344
            self.class_nums = 5
345
            outs = fluid.layers.generate_proposal_labels(
346 347 348 349 350 351 352 353 354 355 356
                rpn_rois=rpn_rois,
                gt_classes=gt_classes,
                is_crowd=is_crowd,
                gt_boxes=gt_boxes,
                im_info=im_info,
                batch_size_per_im=2,
                fg_fraction=0.5,
                fg_thresh=0.5,
                bg_thresh_hi=0.5,
                bg_thresh_lo=0.0,
                bbox_reg_weights=[0.1, 0.1, 0.2, 0.2],
357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376
                class_nums=self.class_nums)
            outs_1 = fluid.layers.generate_proposal_labels(
                rpn_rois=rpn_rois,
                gt_classes=gt_classes,
                is_crowd=is_crowd,
                gt_boxes=gt_boxes,
                im_info=im_info,
                batch_size_per_im=2,
                fg_fraction=0.5,
                fg_thresh=0.5,
                bg_thresh_hi=0.5,
                bg_thresh_lo=0.0,
                bbox_reg_weights=[0.1, 0.1, 0.2, 0.2],
                class_nums=self.class_nums,
                is_cascade_rcnn=True,
                max_overlap=max_overlap,
                return_max_overlap=True)

            self.check_out(outs)
            self.check_out(outs_1)
377
            rois = outs[0]
378 379


380
class TestGenerateMaskLabels(unittest.TestCase):
381

382 383 384
    def test_generate_mask_labels(self):
        program = Program()
        with program_guard(program):
385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414
            im_info = layers.data(name='im_info',
                                  shape=[1, 3],
                                  dtype='float32',
                                  lod_level=1,
                                  append_batch_size=False)
            gt_classes = layers.data(name='gt_classes',
                                     shape=[2, 1],
                                     dtype='int32',
                                     lod_level=1,
                                     append_batch_size=False)
            is_crowd = layers.data(name='is_crowd',
                                   shape=[2, 1],
                                   dtype='int32',
                                   lod_level=1,
                                   append_batch_size=False)
            gt_segms = layers.data(name='gt_segms',
                                   shape=[20, 2],
                                   dtype='float32',
                                   lod_level=3,
                                   append_batch_size=False)
            rois = layers.data(name='rois',
                               shape=[4, 4],
                               dtype='float32',
                               lod_level=1,
                               append_batch_size=False)
            labels_int32 = layers.data(name='labels_int32',
                                       shape=[4, 1],
                                       dtype='int32',
                                       lod_level=1,
                                       append_batch_size=False)
415 416
            num_classes = 5
            resolution = 14
417 418 419 420 421 422 423 424
            outs = fluid.layers.generate_mask_labels(im_info=im_info,
                                                     gt_classes=gt_classes,
                                                     is_crowd=is_crowd,
                                                     gt_segms=gt_segms,
                                                     rois=rois,
                                                     labels_int32=labels_int32,
                                                     num_classes=num_classes,
                                                     resolution=resolution)
425 426 427 428 429
            mask_rois, roi_has_mask_int32, mask_int32 = outs
            assert mask_rois.shape[1] == 4
            assert mask_int32.shape[1] == num_classes * resolution * resolution


C
chengduoZH 已提交
430
class TestMultiBoxHead(unittest.TestCase):
431

C
chengduoZH 已提交
432
    def test_multi_box_head(self):
433
        data_shape = [3, 224, 224]
C
chengduoZH 已提交
434
        mbox_locs, mbox_confs, box, var = self.multi_box_head_output(data_shape)
435 436 437 438

        assert len(box.shape) == 2
        assert box.shape == var.shape
        assert box.shape[1] == 4
Y
Yuan Gao 已提交
439
        assert mbox_locs.shape[1] == mbox_confs.shape[1]
C
chengduoZH 已提交
440 441

    def multi_box_head_output(self, data_shape):
442 443 444
        images = fluid.layers.data(name='pixel',
                                   shape=data_shape,
                                   dtype='float32')
445 446 447 448 449
        conv1 = fluid.layers.conv2d(images, 3, 3, 2)
        conv2 = fluid.layers.conv2d(conv1, 3, 3, 2)
        conv3 = fluid.layers.conv2d(conv2, 3, 3, 2)
        conv4 = fluid.layers.conv2d(conv3, 3, 3, 2)
        conv5 = fluid.layers.conv2d(conv4, 3, 3, 2)
C
chengduoZH 已提交
450

C
chengduoZH 已提交
451
        mbox_locs, mbox_confs, box, var = layers.multi_box_head(
C
chengduoZH 已提交
452 453
            inputs=[conv1, conv2, conv3, conv4, conv5, conv5],
            image=images,
C
chengduoZH 已提交
454
            num_classes=21,
C
chengduoZH 已提交
455 456 457 458 459 460 461
            min_ratio=20,
            max_ratio=90,
            aspect_ratios=[[2.], [2., 3.], [2., 3.], [2., 3.], [2.], [2.]],
            base_size=300,
            offset=0.5,
            flip=True,
            clip=True)
C
chengduoZH 已提交
462

C
chengduoZH 已提交
463
        return mbox_locs, mbox_confs, box, var
C
chengduoZH 已提交
464 465


466
class TestDetectionMAP(unittest.TestCase):
467

468 469 470
    def test_detection_map(self):
        program = Program()
        with program_guard(program):
471 472 473 474 475 476 477 478
            detect_res = layers.data(name='detect_res',
                                     shape=[10, 6],
                                     append_batch_size=False,
                                     dtype='float32')
            label = layers.data(name='label',
                                shape=[10, 6],
                                append_batch_size=False,
                                dtype='float32')
479

480
            map_out = detection.detection_map(detect_res, label, 21)
481 482
            self.assertIsNotNone(map_out)
            self.assertEqual(map_out.shape, (1, ))
483
        print(str(program))
484 485


486
class TestRpnTargetAssign(unittest.TestCase):
487

488 489 490
    def test_rpn_target_assign(self):
        program = Program()
        with program_guard(program):
491 492
            bbox_pred_shape = [10, 50, 4]
            cls_logits_shape = [10, 50, 2]
493 494
            anchor_shape = [50, 4]

495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537
            bbox_pred = layers.data(name='bbox_pred',
                                    shape=bbox_pred_shape,
                                    append_batch_size=False,
                                    dtype='float32')
            cls_logits = layers.data(name='cls_logits',
                                     shape=cls_logits_shape,
                                     append_batch_size=False,
                                     dtype='float32')
            anchor_box = layers.data(name='anchor_box',
                                     shape=anchor_shape,
                                     append_batch_size=False,
                                     dtype='float32')
            anchor_var = layers.data(name='anchor_var',
                                     shape=anchor_shape,
                                     append_batch_size=False,
                                     dtype='float32')
            gt_boxes = layers.data(name='gt_boxes',
                                   shape=[4],
                                   lod_level=1,
                                   dtype='float32')
            is_crowd = layers.data(name='is_crowd',
                                   shape=[1, 10],
                                   dtype='int32',
                                   lod_level=1,
                                   append_batch_size=False)
            im_info = layers.data(name='im_info',
                                  shape=[1, 3],
                                  dtype='float32',
                                  lod_level=1,
                                  append_batch_size=False)
            outs = layers.rpn_target_assign(bbox_pred=bbox_pred,
                                            cls_logits=cls_logits,
                                            anchor_box=anchor_box,
                                            anchor_var=anchor_var,
                                            gt_boxes=gt_boxes,
                                            is_crowd=is_crowd,
                                            im_info=im_info,
                                            rpn_batch_size_per_im=256,
                                            rpn_straddle_thresh=0.0,
                                            rpn_fg_fraction=0.5,
                                            rpn_positive_overlap=0.7,
                                            rpn_negative_overlap=0.3,
                                            use_random=False)
538 539 540 541 542
            pred_scores = outs[0]
            pred_loc = outs[1]
            tgt_lbl = outs[2]
            tgt_bbox = outs[3]
            bbox_inside_weight = outs[4]
543

544 545 546 547
            self.assertIsNotNone(pred_scores)
            self.assertIsNotNone(pred_loc)
            self.assertIsNotNone(tgt_lbl)
            self.assertIsNotNone(tgt_bbox)
J
jerrywgz 已提交
548
            self.assertIsNotNone(bbox_inside_weight)
549 550 551
            assert pred_scores.shape[1] == 1
            assert pred_loc.shape[1] == 4
            assert pred_loc.shape[1] == tgt_bbox.shape[1]
J
jerrywgz 已提交
552
            print(str(program))
553 554


555
class TestGenerateProposals(LayerTest):
556

557
    def test_generate_proposals(self):
558 559 560 561 562 563 564 565
        scores_np = np.random.rand(2, 3, 4, 4).astype('float32')
        bbox_deltas_np = np.random.rand(2, 12, 4, 4).astype('float32')
        im_info_np = np.array([[8, 8, 0.5], [6, 6, 0.5]]).astype('float32')
        anchors_np = np.reshape(np.arange(4 * 4 * 3 * 4),
                                [4, 4, 3, 4]).astype('float32')
        variances_np = np.ones((4, 4, 3, 4)).astype('float32')

        with self.static_graph():
566 567 568 569 570 571
            scores = fluid.data(name='scores',
                                shape=[2, 3, 4, 4],
                                dtype='float32')
            bbox_deltas = fluid.data(name='bbox_deltas',
                                     shape=[2, 12, 4, 4],
                                     dtype='float32')
572
            im_info = fluid.data(name='im_info', shape=[2, 3], dtype='float32')
573 574 575 576 577 578
            anchors = fluid.data(name='anchors',
                                 shape=[4, 4, 3, 4],
                                 dtype='float32')
            variances = fluid.data(name='var',
                                   shape=[4, 4, 3, 4],
                                   dtype='float32')
579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596
            rois, roi_probs, rois_num = fluid.layers.generate_proposals(
                scores,
                bbox_deltas,
                im_info,
                anchors,
                variances,
                pre_nms_top_n=10,
                post_nms_top_n=5,
                return_rois_num=True)
            rois_stat, roi_probs_stat, rois_num_stat = self.get_static_graph_result(
                feed={
                    'scores': scores_np,
                    'bbox_deltas': bbox_deltas_np,
                    'im_info': im_info_np,
                    'anchors': anchors_np,
                    'var': variances_np
                },
                fetch_list=[rois, roi_probs, rois_num],
Z
zhiboniu 已提交
597
                with_lod=False)
598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617

        with self.dynamic_graph():
            scores_dy = base.to_variable(scores_np)
            bbox_deltas_dy = base.to_variable(bbox_deltas_np)
            im_info_dy = base.to_variable(im_info_np)
            anchors_dy = base.to_variable(anchors_np)
            variances_dy = base.to_variable(variances_np)
            rois, roi_probs, rois_num = fluid.layers.generate_proposals(
                scores_dy,
                bbox_deltas_dy,
                im_info_dy,
                anchors_dy,
                variances_dy,
                pre_nms_top_n=10,
                post_nms_top_n=5,
                return_rois_num=True)
            rois_dy = rois.numpy()
            roi_probs_dy = roi_probs.numpy()
            rois_num_dy = rois_num.numpy()

618 619 620
        np.testing.assert_array_equal(np.array(rois_stat), rois_dy)
        np.testing.assert_array_equal(np.array(roi_probs_stat), roi_probs_dy)
        np.testing.assert_array_equal(np.array(rois_num_stat), rois_num_dy)
621 622


D
dengkaipeng 已提交
623
class TestYoloDetection(unittest.TestCase):
624

D
dengkaipeng 已提交
625 626 627 628
    def test_yolov3_loss(self):
        program = Program()
        with program_guard(program):
            x = layers.data(name='x', shape=[30, 7, 7], dtype='float32')
629 630 631
            gt_box = layers.data(name='gt_box', shape=[10, 4], dtype='float32')
            gt_label = layers.data(name='gt_label', shape=[10], dtype='int32')
            gt_score = layers.data(name='gt_score', shape=[10], dtype='float32')
632 633 634 635 636 637 638 639
            loss = layers.yolov3_loss(x,
                                      gt_box,
                                      gt_label, [10, 13, 30, 13], [0, 1],
                                      10,
                                      0.7,
                                      32,
                                      gt_score=gt_score,
                                      use_label_smooth=False)
D
dengkaipeng 已提交
640 641 642

            self.assertIsNotNone(loss)

D
dengkaipeng 已提交
643 644 645 646
    def test_yolo_box(self):
        program = Program()
        with program_guard(program):
            x = layers.data(name='x', shape=[30, 7, 7], dtype='float32')
D
dengkaipeng 已提交
647
            img_size = layers.data(name='img_size', shape=[2], dtype='int32')
648 649
            boxes, scores = layers.yolo_box(x, img_size, [10, 13, 30, 13], 10,
                                            0.01, 32)
D
dengkaipeng 已提交
650 651 652
            self.assertIsNotNone(boxes)
            self.assertIsNotNone(scores)

653 654 655 656 657 658 659
    def test_yolov3_loss_with_scale(self):
        program = Program()
        with program_guard(program):
            x = layers.data(name='x', shape=[30, 7, 7], dtype='float32')
            gt_box = layers.data(name='gt_box', shape=[10, 4], dtype='float32')
            gt_label = layers.data(name='gt_label', shape=[10], dtype='int32')
            gt_score = layers.data(name='gt_score', shape=[10], dtype='float32')
660 661 662 663 664 665 666 667 668
            loss = layers.yolov3_loss(x,
                                      gt_box,
                                      gt_label, [10, 13, 30, 13], [0, 1],
                                      10,
                                      0.7,
                                      32,
                                      gt_score=gt_score,
                                      use_label_smooth=False,
                                      scale_x_y=1.2)
669 670 671 672 673 674 675 676

            self.assertIsNotNone(loss)

    def test_yolo_box_with_scale(self):
        program = Program()
        with program_guard(program):
            x = layers.data(name='x', shape=[30, 7, 7], dtype='float32')
            img_size = layers.data(name='img_size', shape=[2], dtype='int32')
677 678 679 680 681 682
            boxes, scores = layers.yolo_box(x,
                                            img_size, [10, 13, 30, 13],
                                            10,
                                            0.01,
                                            32,
                                            scale_x_y=1.2)
683 684 685
            self.assertIsNotNone(boxes)
            self.assertIsNotNone(scores)

D
dengkaipeng 已提交
686

J
jerrywgz 已提交
687
class TestBoxClip(unittest.TestCase):
688

J
jerrywgz 已提交
689 690 691
    def test_box_clip(self):
        program = Program()
        with program_guard(program):
692 693 694 695
            input_box = layers.data(name='input_box',
                                    shape=[7, 4],
                                    dtype='float32',
                                    lod_level=1)
J
jerrywgz 已提交
696 697 698 699
            im_info = layers.data(name='im_info', shape=[3], dtype='float32')
            out = layers.box_clip(input_box, im_info)
            self.assertIsNotNone(out)

J
jerrywgz 已提交
700

J
jerrywgz 已提交
701
class TestMulticlassNMS(unittest.TestCase):
702

J
jerrywgz 已提交
703 704 705
    def test_multiclass_nms(self):
        program = Program()
        with program_guard(program):
706 707 708
            bboxes = layers.data(name='bboxes',
                                 shape=[-1, 10, 4],
                                 dtype='float32')
J
jerrywgz 已提交
709
            scores = layers.data(name='scores', shape=[-1, 10], dtype='float32')
J
jerrywgz 已提交
710
            output = layers.multiclass_nms(bboxes, scores, 0.3, 400, 200, 0.7)
J
jerrywgz 已提交
711 712
            self.assertIsNotNone(output)

713 714 715
    def test_multiclass_nms_error(self):
        program = Program()
        with program_guard(program):
716 717 718 719 720 721 722 723 724
            bboxes1 = fluid.data(name='bboxes1',
                                 shape=[10, 10, 4],
                                 dtype='int32')
            scores1 = fluid.data(name='scores1',
                                 shape=[10, 10],
                                 dtype='float32')
            bboxes2 = fluid.data(name='bboxes2',
                                 shape=[10, 10, 4],
                                 dtype='float32')
725
            scores2 = fluid.data(name='scores2', shape=[10, 10], dtype='int32')
726 727 728 729 730 731 732 733 734 735 736 737 738 739
            self.assertRaises(TypeError,
                              layers.multiclass_nms,
                              bboxes=bboxes1,
                              scores=scores1,
                              score_threshold=0.5,
                              nms_top_k=400,
                              keep_top_k=200)
            self.assertRaises(TypeError,
                              layers.multiclass_nms,
                              bboxes=bboxes2,
                              scores=scores2,
                              score_threshold=0.5,
                              nms_top_k=400,
                              keep_top_k=200)
740

J
jerrywgz 已提交
741

742
class TestMulticlassNMS2(unittest.TestCase):
743

744 745 746
    def test_multiclass_nms2(self):
        program = Program()
        with program_guard(program):
747 748 749
            bboxes = layers.data(name='bboxes',
                                 shape=[-1, 10, 4],
                                 dtype='float32')
750
            scores = layers.data(name='scores', shape=[-1, 10], dtype='float32')
751 752
            output = fluid.contrib.multiclass_nms2(bboxes, scores, 0.3, 400,
                                                   200, 0.7)
753 754 755 756 757 758 759
            output2, index = fluid.contrib.multiclass_nms2(bboxes,
                                                           scores,
                                                           0.3,
                                                           400,
                                                           200,
                                                           0.7,
                                                           return_index=True)
760 761 762 763 764
            self.assertIsNotNone(output)
            self.assertIsNotNone(output2)
            self.assertIsNotNone(index)


765
class TestCollectFpnPropsals(LayerTest):
766

767
    def test_collect_fpn_proposals(self):
768 769 770 771 772 773 774 775 776 777 778 779
        multi_bboxes_np = []
        multi_scores_np = []
        rois_num_per_level_np = []
        for i in range(4):
            bboxes_np = np.random.rand(5, 4).astype('float32')
            scores_np = np.random.rand(5, 1).astype('float32')
            rois_num = np.array([2, 3]).astype('int32')
            multi_bboxes_np.append(bboxes_np)
            multi_scores_np.append(scores_np)
            rois_num_per_level_np.append(rois_num)

        with self.static_graph():
780 781
            multi_bboxes = []
            multi_scores = []
782
            rois_num_per_level = []
783
            for i in range(4):
784 785 786 787 788 789 790 791 792 793 794
                bboxes = fluid.data(name='rois' + str(i),
                                    shape=[5, 4],
                                    dtype='float32',
                                    lod_level=1)
                scores = fluid.data(name='scores' + str(i),
                                    shape=[5, 1],
                                    dtype='float32',
                                    lod_level=1)
                rois_num = fluid.data(name='rois_num' + str(i),
                                      shape=[None],
                                      dtype='int32')
795

796 797
                multi_bboxes.append(bboxes)
                multi_scores.append(scores)
798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837
                rois_num_per_level.append(rois_num)

            fpn_rois, rois_num = layers.collect_fpn_proposals(
                multi_bboxes,
                multi_scores,
                2,
                5,
                10,
                rois_num_per_level=rois_num_per_level)
            feed = {}
            for i in range(4):
                feed['rois' + str(i)] = multi_bboxes_np[i]
                feed['scores' + str(i)] = multi_scores_np[i]
                feed['rois_num' + str(i)] = rois_num_per_level_np[i]
            fpn_rois_stat, rois_num_stat = self.get_static_graph_result(
                feed=feed, fetch_list=[fpn_rois, rois_num], with_lod=True)
            fpn_rois_stat = np.array(fpn_rois_stat)
            rois_num_stat = np.array(rois_num_stat)

        with self.dynamic_graph():
            multi_bboxes_dy = []
            multi_scores_dy = []
            rois_num_per_level_dy = []
            for i in range(4):
                bboxes_dy = base.to_variable(multi_bboxes_np[i])
                scores_dy = base.to_variable(multi_scores_np[i])
                rois_num_dy = base.to_variable(rois_num_per_level_np[i])
                multi_bboxes_dy.append(bboxes_dy)
                multi_scores_dy.append(scores_dy)
                rois_num_per_level_dy.append(rois_num_dy)
            fpn_rois_dy, rois_num_dy = fluid.layers.collect_fpn_proposals(
                multi_bboxes_dy,
                multi_scores_dy,
                2,
                5,
                10,
                rois_num_per_level=rois_num_per_level_dy)
            fpn_rois_dy = fpn_rois_dy.numpy()
            rois_num_dy = rois_num_dy.numpy()

838 839
        np.testing.assert_array_equal(fpn_rois_stat, fpn_rois_dy)
        np.testing.assert_array_equal(rois_num_stat, rois_num_dy)
840

841
    def test_collect_fpn_proposals_error(self):
842

843 844 845 846
        def generate_input(bbox_type, score_type, name):
            multi_bboxes = []
            multi_scores = []
            for i in range(4):
847 848 849 850 851 852 853 854
                bboxes = fluid.data(name='rois' + name + str(i),
                                    shape=[10, 4],
                                    dtype=bbox_type,
                                    lod_level=1)
                scores = fluid.data(name='scores' + name + str(i),
                                    shape=[10, 1],
                                    dtype=score_type,
                                    lod_level=1)
855 856 857 858 859 860
                multi_bboxes.append(bboxes)
                multi_scores.append(scores)
            return multi_bboxes, multi_scores

        program = Program()
        with program_guard(program):
861 862 863 864 865 866 867 868
            bbox1 = fluid.data(name='rois',
                               shape=[5, 10, 4],
                               dtype='float32',
                               lod_level=1)
            score1 = fluid.data(name='scores',
                                shape=[5, 10, 1],
                                dtype='float32',
                                lod_level=1)
869
            bbox2, score2 = generate_input('int32', 'float32', '2')
870 871 872 873 874 875 876 877 878 879 880 881 882 883
            self.assertRaises(TypeError,
                              layers.collect_fpn_proposals,
                              multi_rois=bbox1,
                              multi_scores=score1,
                              min_level=2,
                              max_level=5,
                              post_nms_top_n=2000)
            self.assertRaises(TypeError,
                              layers.collect_fpn_proposals,
                              multi_rois=bbox2,
                              multi_scores=score2,
                              min_level=2,
                              max_level=5,
                              post_nms_top_n=2000)
884

885

886
class TestDistributeFpnProposals(LayerTest):
887

888
    def test_distribute_fpn_proposals(self):
889 890 891 892 893 894 895 896 897 898 899 900 901
        rois_np = np.random.rand(10, 4).astype('float32')
        rois_num_np = np.array([4, 6]).astype('int32')
        with self.static_graph():
            rois = fluid.data(name='rois', shape=[10, 4], dtype='float32')
            rois_num = fluid.data(name='rois_num', shape=[None], dtype='int32')
            multi_rois, restore_ind, rois_num_per_level = layers.distribute_fpn_proposals(
                fpn_rois=rois,
                min_level=2,
                max_level=5,
                refer_level=4,
                refer_scale=224,
                rois_num=rois_num)
            fetch_list = multi_rois + [restore_ind] + rois_num_per_level
902 903 904 905 906 907
            output_stat = self.get_static_graph_result(feed={
                'rois': rois_np,
                'rois_num': rois_num_np
            },
                                                       fetch_list=fetch_list,
                                                       with_lod=True)
908 909 910 911 912 913 914 915 916 917 918
            output_stat_np = []
            for output in output_stat:
                output_np = np.array(output)
                if len(output_np) > 0:
                    output_stat_np.append(output_np)

        with self.dynamic_graph():
            rois_dy = base.to_variable(rois_np)
            rois_num_dy = base.to_variable(rois_num_np)
            multi_rois_dy, restore_ind_dy, rois_num_per_level_dy = layers.distribute_fpn_proposals(
                fpn_rois=rois_dy,
919 920 921
                min_level=2,
                max_level=5,
                refer_level=4,
922 923
                refer_scale=224,
                rois_num=rois_num_dy)
H
hong 已提交
924
            print(type(multi_rois_dy))
925 926 927 928 929 930 931 932
            output_dy = multi_rois_dy + [restore_ind_dy] + rois_num_per_level_dy
            output_dy_np = []
            for output in output_dy:
                output_np = output.numpy()
                if len(output_np) > 0:
                    output_dy_np.append(output_np)

        for res_stat, res_dy in zip(output_stat_np, output_dy_np):
933
            np.testing.assert_array_equal(res_stat, res_dy)
934

935 936 937
    def test_distribute_fpn_proposals_error(self):
        program = Program()
        with program_guard(program):
938 939 940 941 942 943 944 945 946 947 948
            fpn_rois = fluid.data(name='data_error',
                                  shape=[10, 4],
                                  dtype='int32',
                                  lod_level=1)
            self.assertRaises(TypeError,
                              layers.distribute_fpn_proposals,
                              fpn_rois=fpn_rois,
                              min_level=2,
                              max_level=5,
                              refer_level=4,
                              refer_scale=224)
949 950 951


class TestBoxDecoderAndAssign(unittest.TestCase):
952

953 954 955 956 957
    def test_box_decoder_and_assign(self):
        program = Program()
        with program_guard(program):
            pb = fluid.data(name='prior_box', shape=[None, 4], dtype='float32')
            pbv = fluid.data(name='prior_box_var', shape=[4], dtype='float32')
958 959 960 961 962 963
            loc = fluid.data(name='target_box',
                             shape=[None, 4 * 81],
                             dtype='float32')
            scores = fluid.data(name='scores',
                                shape=[None, 81],
                                dtype='float32')
964 965 966 967 968 969
            decoded_box, output_assign_box = fluid.layers.box_decoder_and_assign(
                pb, pbv, loc, scores, 4.135)
            self.assertIsNotNone(decoded_box)
            self.assertIsNotNone(output_assign_box)

    def test_box_decoder_and_assign_error(self):
970

971
        def generate_input(pb_type, pbv_type, loc_type, score_type, name):
972 973 974 975 976 977 978 979 980 981 982 983
            pb = fluid.data(name='prior_box' + name,
                            shape=[None, 4],
                            dtype=pb_type)
            pbv = fluid.data(name='prior_box_var' + name,
                             shape=[4],
                             dtype=pbv_type)
            loc = fluid.data(name='target_box' + name,
                             shape=[None, 4 * 81],
                             dtype=loc_type)
            scores = fluid.data(name='scores' + name,
                                shape=[None, 81],
                                dtype=score_type)
984 985 986 987 988 989 990 991 992 993
            return pb, pbv, loc, scores

        program = Program()
        with program_guard(program):
            pb1, pbv1, loc1, scores1 = generate_input('int32', 'float32',
                                                      'float32', 'float32', '1')
            pb2, pbv2, loc2, scores2 = generate_input('float32', 'float32',
                                                      'int32', 'float32', '2')
            pb3, pbv3, loc3, scores3 = generate_input('float32', 'float32',
                                                      'float32', 'int32', '3')
994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014
            self.assertRaises(TypeError,
                              layers.box_decoder_and_assign,
                              prior_box=pb1,
                              prior_box_var=pbv1,
                              target_box=loc1,
                              box_score=scores1,
                              box_clip=4.0)
            self.assertRaises(TypeError,
                              layers.box_decoder_and_assign,
                              prior_box=pb2,
                              prior_box_var=pbv2,
                              target_box=loc2,
                              box_score=scores2,
                              box_clip=4.0)
            self.assertRaises(TypeError,
                              layers.box_decoder_and_assign,
                              prior_box=pb3,
                              prior_box_var=pbv3,
                              target_box=loc3,
                              box_score=scores3,
                              box_clip=4.0)
1015

1016

1017
if __name__ == '__main__':
H
hong 已提交
1018
    paddle.enable_static()
1019
    unittest.main()