test_detection.py 42.9 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
from __future__ import print_function

17 18
import paddle.fluid as fluid
import paddle.fluid.layers as layers
19
from paddle.fluid.layers import detection
20
from paddle.fluid.framework import Program, program_guard
C
chengduoZH 已提交
21
import unittest
22 23 24 25 26
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 已提交
27 28 29
import paddle

paddle.enable_static()
30 31 32


class LayerTest(unittest.TestCase):
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 75 76
    @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
77 78


79
class TestDetection(unittest.TestCase):
80

81 82 83
    def test_detection_output(self):
        program = Program()
        with program_guard(program):
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
            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)
109
            self.assertIsNotNone(out)
110 111
            self.assertIsNotNone(out2)
            self.assertIsNotNone(index)
112
            self.assertEqual(out.shape[-1], 6)
113
        print(str(program))
114

J
jerrywgz 已提交
115 116 117 118 119
    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)
120 121 122 123
            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 已提交
124 125 126
            self.assertIsNotNone(bcoder)
        print(str(program))

127 128 129 130
    def test_box_coder_error(self):
        program = Program()
        with program_guard(program):
            x1 = fluid.data(name='x1', shape=[10, 4], dtype='int32')
131 132 133 134
            y1 = fluid.data(name='y1',
                            shape=[10, 4],
                            dtype='float32',
                            lod_level=1)
135
            x2 = fluid.data(name='x2', shape=[10, 4], dtype='float32')
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
            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')
153

154 155 156 157 158 159 160
    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)
161 162 163 164
            bcoder = layers.box_coder(prior_box=x,
                                      prior_box_var=y,
                                      target_box=z,
                                      code_type='encode_center_size')
165 166 167 168 169 170 171
            self.assertIsNotNone(iou)
            self.assertIsNotNone(bcoder)

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

172 173 174 175 176 177 178
            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)
179 180 181
            self.assertIsNotNone(trg)
            self.assertIsNotNone(trg_weight)

182 183 184 185 186 187 188
            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)
189 190 191
            self.assertIsNotNone(trg)
            self.assertIsNotNone(trg_weight)

192
        print(str(program))
193 194 195 196

    def test_ssd_loss(self):
        program = Program()
        with program_guard(program):
197 198 199 200 201 202 203 204
            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')
205 206
            loc = layers.data(name='target_box', shape=[10, 4], dtype='float32')
            scores = layers.data(name='scores', shape=[10, 21], dtype='float32')
207 208 209 210 211 212 213 214
            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')
215 216 217
            loss = layers.ssd_loss(loc, scores, gt_box, gt_label, pb, pbv)
            self.assertIsNotNone(loss)
            self.assertEqual(loss.shape[-1], 1)
218
        print(str(program))
219 220


221
class TestPriorBox(unittest.TestCase):
222

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


class TestPriorBox2(unittest.TestCase):
243

244 245 246 247 248 249
    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)
250 251 252 253 254 255
            box, var = layers.prior_box(input=conv1,
                                        image=images,
                                        min_sizes=[100.0],
                                        aspect_ratios=[1.],
                                        flip=True,
                                        clip=True)
256 257 258
            assert len(box.shape) == 4
            assert box.shape == var.shape
            assert box.shape[3] == 4
259 260


R
ruri 已提交
261
class TestDensityPriorBox(unittest.TestCase):
262

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


282
class TestAnchorGenerator(unittest.TestCase):
283

284 285
    def test_anchor_generator(self):
        data_shape = [3, 224, 224]
286 287 288
        images = fluid.layers.data(name='pixel',
                                   shape=data_shape,
                                   dtype='float32')
289 290 291 292 293 294 295 296 297 298 299 300 301
        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


302
class TestGenerateProposalLabels(unittest.TestCase):
303

304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321
    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]

322
    def test_generate_proposal_labels(self):
323 324
        program = Program()
        with program_guard(program):
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340
            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)
341
            im_info = fluid.data(name='im_info', shape=[1, 3], dtype='float32')
342 343 344 345
            max_overlap = fluid.data(name='max_overlap',
                                     shape=[4],
                                     dtype='float32',
                                     lod_level=1)
346
            self.class_nums = 5
347
            outs = fluid.layers.generate_proposal_labels(
348 349 350 351 352 353 354 355 356 357 358
                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],
359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378
                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)
379
            rois = outs[0]
380 381


382
class TestGenerateMaskLabels(unittest.TestCase):
383

384 385 386
    def test_generate_mask_labels(self):
        program = Program()
        with program_guard(program):
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 415 416
            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)
417 418
            num_classes = 5
            resolution = 14
419 420 421 422 423 424 425 426
            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)
427 428 429 430 431
            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 已提交
432
class TestMultiBoxHead(unittest.TestCase):
433

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

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

    def multi_box_head_output(self, data_shape):
444 445 446
        images = fluid.layers.data(name='pixel',
                                   shape=data_shape,
                                   dtype='float32')
447 448 449 450 451
        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 已提交
452

C
chengduoZH 已提交
453
        mbox_locs, mbox_confs, box, var = layers.multi_box_head(
C
chengduoZH 已提交
454 455
            inputs=[conv1, conv2, conv3, conv4, conv5, conv5],
            image=images,
C
chengduoZH 已提交
456
            num_classes=21,
C
chengduoZH 已提交
457 458 459 460 461 462 463
            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 已提交
464

C
chengduoZH 已提交
465
        return mbox_locs, mbox_confs, box, var
C
chengduoZH 已提交
466 467


468
class TestDetectionMAP(unittest.TestCase):
469

470 471 472
    def test_detection_map(self):
        program = Program()
        with program_guard(program):
473 474 475 476 477 478 479 480
            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')
481

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


488
class TestRpnTargetAssign(unittest.TestCase):
489

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

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 538 539
            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)
540 541 542 543 544
            pred_scores = outs[0]
            pred_loc = outs[1]
            tgt_lbl = outs[2]
            tgt_bbox = outs[3]
            bbox_inside_weight = outs[4]
545

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


557
class TestGenerateProposals(LayerTest):
558

559
    def test_generate_proposals(self):
560 561 562 563 564 565 566 567
        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():
568 569 570 571 572 573
            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')
574
            im_info = fluid.data(name='im_info', shape=[2, 3], dtype='float32')
575 576 577 578 579 580
            anchors = fluid.data(name='anchors',
                                 shape=[4, 4, 3, 4],
                                 dtype='float32')
            variances = fluid.data(name='var',
                                   shape=[4, 4, 3, 4],
                                   dtype='float32')
581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598
            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 已提交
599
                with_lod=False)
600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622

        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()

        self.assertTrue(np.array_equal(np.array(rois_stat), rois_dy))
        self.assertTrue(np.array_equal(np.array(roi_probs_stat), roi_probs_dy))
        self.assertTrue(np.array_equal(np.array(rois_num_stat), rois_num_dy))
623 624


D
dengkaipeng 已提交
625
class TestYoloDetection(unittest.TestCase):
626

D
dengkaipeng 已提交
627 628 629 630
    def test_yolov3_loss(self):
        program = Program()
        with program_guard(program):
            x = layers.data(name='x', shape=[30, 7, 7], dtype='float32')
631 632 633
            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')
634 635 636 637 638 639 640 641
            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 已提交
642 643 644

            self.assertIsNotNone(loss)

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

655 656 657 658 659 660 661
    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')
662 663 664 665 666 667 668 669 670
            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)
671 672 673 674 675 676 677 678

            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')
679 680 681 682 683 684
            boxes, scores = layers.yolo_box(x,
                                            img_size, [10, 13, 30, 13],
                                            10,
                                            0.01,
                                            32,
                                            scale_x_y=1.2)
685 686 687
            self.assertIsNotNone(boxes)
            self.assertIsNotNone(scores)

D
dengkaipeng 已提交
688

J
jerrywgz 已提交
689
class TestBoxClip(unittest.TestCase):
690

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

J
jerrywgz 已提交
702

J
jerrywgz 已提交
703
class TestMulticlassNMS(unittest.TestCase):
704

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

715 716 717
    def test_multiclass_nms_error(self):
        program = Program()
        with program_guard(program):
718 719 720 721 722 723 724 725 726
            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')
727
            scores2 = fluid.data(name='scores2', shape=[10, 10], dtype='int32')
728 729 730 731 732 733 734 735 736 737 738 739 740 741
            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)
742

J
jerrywgz 已提交
743

744
class TestMulticlassNMS2(unittest.TestCase):
745

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


767
class TestCollectFpnPropsals(LayerTest):
768

769
    def test_collect_fpn_proposals(self):
770 771 772 773 774 775 776 777 778 779 780 781
        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():
782 783
            multi_bboxes = []
            multi_scores = []
784
            rois_num_per_level = []
785
            for i in range(4):
786 787 788 789 790 791 792 793 794 795 796
                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')
797

798 799
                multi_bboxes.append(bboxes)
                multi_scores.append(scores)
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 838 839 840 841
                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()

        self.assertTrue(np.array_equal(fpn_rois_stat, fpn_rois_dy))
        self.assertTrue(np.array_equal(rois_num_stat, rois_num_dy))
842

843
    def test_collect_fpn_proposals_error(self):
844

845 846 847 848
        def generate_input(bbox_type, score_type, name):
            multi_bboxes = []
            multi_scores = []
            for i in range(4):
849 850 851 852 853 854 855 856
                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)
857 858 859 860 861 862
                multi_bboxes.append(bboxes)
                multi_scores.append(scores)
            return multi_bboxes, multi_scores

        program = Program()
        with program_guard(program):
863 864 865 866 867 868 869 870
            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)
871
            bbox2, score2 = generate_input('int32', 'float32', '2')
872 873 874 875 876 877 878 879 880 881 882 883 884 885
            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)
886

887

888
class TestDistributeFpnProposals(LayerTest):
889

890
    def test_distribute_fpn_proposals(self):
891 892 893 894 895 896 897 898 899 900 901 902 903
        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
904 905 906 907 908 909
            output_stat = self.get_static_graph_result(feed={
                'rois': rois_np,
                'rois_num': rois_num_np
            },
                                                       fetch_list=fetch_list,
                                                       with_lod=True)
910 911 912 913 914 915 916 917 918 919 920
            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,
921 922 923
                min_level=2,
                max_level=5,
                refer_level=4,
924 925
                refer_scale=224,
                rois_num=rois_num_dy)
H
hong 已提交
926
            print(type(multi_rois_dy))
927 928 929 930 931 932 933 934 935
            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):
            self.assertTrue(np.array_equal(res_stat, res_dy))
936

937 938 939
    def test_distribute_fpn_proposals_error(self):
        program = Program()
        with program_guard(program):
940 941 942 943 944 945 946 947 948 949 950
            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)
951 952 953


class TestBoxDecoderAndAssign(unittest.TestCase):
954

955 956 957 958 959
    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')
960 961 962 963 964 965
            loc = fluid.data(name='target_box',
                             shape=[None, 4 * 81],
                             dtype='float32')
            scores = fluid.data(name='scores',
                                shape=[None, 81],
                                dtype='float32')
966 967 968 969 970 971
            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):
972

973
        def generate_input(pb_type, pbv_type, loc_type, score_type, name):
974 975 976 977 978 979 980 981 982 983 984 985
            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)
986 987 988 989 990 991 992 993 994 995
            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')
996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016
            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)
1017

1018

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