test_detection.py 29.2 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
import contextlib
16 17
import unittest

18 19
import numpy as np
from unittests.test_imperative_base import new_program_scope
20

P
pangyoki 已提交
21
import paddle
22 23 24 25 26 27
import paddle.fluid as fluid
import paddle.fluid.layers as layers
from paddle.fluid import core
from paddle.fluid.dygraph import base
from paddle.fluid.framework import Program, program_guard
from paddle.fluid.layers import detection
P
pangyoki 已提交
28 29

paddle.enable_static()
30 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


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

57 58 59
    def get_static_graph_result(
        self, feed, fetch_list, with_lod=False, force_to_use_cpu=False
    ):
60 61
        exe = fluid.Executor(self._get_place(force_to_use_cpu))
        exe.run(fluid.default_startup_program())
62 63 64 65 66 67
        return exe.run(
            fluid.default_main_program(),
            feed=feed,
            fetch_list=fetch_list,
            return_numpy=(not with_lod),
        )
68 69 70 71

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


79
class TestDetection(unittest.TestCase):
J
jerrywgz 已提交
80 81 82 83 84
    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)
85 86 87 88 89 90
            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 已提交
91 92 93
            self.assertIsNotNone(bcoder)
        print(str(program))

94 95 96 97
    def test_box_coder_error(self):
        program = Program()
        with program_guard(program):
            x1 = fluid.data(name='x1', shape=[10, 4], dtype='int32')
98 99 100
            y1 = fluid.data(
                name='y1', shape=[10, 4], dtype='float32', lod_level=1
            )
101
            x2 = fluid.data(name='x2', shape=[10, 4], dtype='float32')
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
            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',
            )
122

123

124 125
class TestPriorBox(unittest.TestCase):
    def test_prior_box(self):
126 127 128
        program = Program()
        with program_guard(program):
            data_shape = [3, 224, 224]
129 130 131
            images = fluid.layers.data(
                name='pixel', shape=data_shape, dtype='float32'
            )
132
            conv1 = fluid.layers.conv2d(images, 3, 3, 2)
133 134 135 136 137 138 139 140
            box, var = layers.prior_box(
                input=conv1,
                image=images,
                min_sizes=[100.0],
                aspect_ratios=[1.0],
                flip=True,
                clip=True,
            )
141 142 143 144 145 146 147 148 149 150 151 152
            assert len(box.shape) == 4
            assert box.shape == var.shape
            assert box.shape[3] == 4


class TestPriorBox2(unittest.TestCase):
    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)
153 154 155 156 157 158 159 160
            box, var = layers.prior_box(
                input=conv1,
                image=images,
                min_sizes=[100.0],
                aspect_ratios=[1.0],
                flip=True,
                clip=True,
            )
161 162 163
            assert len(box.shape) == 4
            assert box.shape == var.shape
            assert box.shape[3] == 4
164 165


R
ruri 已提交
166 167
class TestDensityPriorBox(unittest.TestCase):
    def test_density_prior_box(self):
168 169 170
        program = Program()
        with program_guard(program):
            data_shape = [3, 224, 224]
171 172 173
            images = fluid.layers.data(
                name='pixel', shape=data_shape, dtype='float32'
            )
174
            conv1 = fluid.layers.conv2d(images, 3, 3, 2)
175 176 177 178 179 180 181 182
            box, var = layers.density_prior_box(
                input=conv1,
                image=images,
                densities=[3, 4],
                fixed_sizes=[50.0, 60.0],
                fixed_ratios=[1.0],
                clip=True,
            )
183 184 185
            assert len(box.shape) == 4
            assert box.shape == var.shape
            assert box.shape[-1] == 4
R
ruri 已提交
186 187


188 189 190
class TestAnchorGenerator(unittest.TestCase):
    def test_anchor_generator(self):
        data_shape = [3, 224, 224]
191 192 193
        images = fluid.layers.data(
            name='pixel', shape=data_shape, dtype='float32'
        )
194 195 196 197 198 199 200
        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],
201 202
            offset=0.5,
        )
203 204 205 206 207
        assert len(anchor.shape) == 4
        assert anchor.shape == var.shape
        assert anchor.shape[3] == 4


208
class TestGenerateProposalLabels(unittest.TestCase):
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
    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]

227
    def test_generate_proposal_labels(self):
228 229
        program = Program()
        with program_guard(program):
230 231 232 233 234 235 236 237 238 239 240 241
            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
            )
242
            im_info = fluid.data(name='im_info', shape=[1, 3], dtype='float32')
243 244 245
            max_overlap = fluid.data(
                name='max_overlap', shape=[4], dtype='float32', lod_level=1
            )
246
            self.class_nums = 5
247
            outs = fluid.layers.generate_proposal_labels(
248 249 250 251 252 253 254 255 256 257 258
                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],
259 260
                class_nums=self.class_nums,
            )
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275
            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,
276 277
                return_max_overlap=True,
            )
278 279 280

            self.check_out(outs)
            self.check_out(outs_1)
281
            rois = outs[0]
282 283


284 285 286 287
class TestGenerateMaskLabels(unittest.TestCase):
    def test_generate_mask_labels(self):
        program = Program()
        with program_guard(program):
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329
            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,
            )
330 331
            num_classes = 5
            resolution = 14
332 333 334 335 336 337 338 339 340 341
            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,
            )
342 343 344 345 346
            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 已提交
347 348
class TestMultiBoxHead(unittest.TestCase):
    def test_multi_box_head(self):
349
        data_shape = [3, 224, 224]
C
chengduoZH 已提交
350
        mbox_locs, mbox_confs, box, var = self.multi_box_head_output(data_shape)
351 352 353 354

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

    def multi_box_head_output(self, data_shape):
358 359 360
        images = fluid.layers.data(
            name='pixel', shape=data_shape, dtype='float32'
        )
361 362 363 364 365
        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 已提交
366

C
chengduoZH 已提交
367
        mbox_locs, mbox_confs, box, var = layers.multi_box_head(
C
chengduoZH 已提交
368 369
            inputs=[conv1, conv2, conv3, conv4, conv5, conv5],
            image=images,
C
chengduoZH 已提交
370
            num_classes=21,
C
chengduoZH 已提交
371 372
            min_ratio=20,
            max_ratio=90,
373 374 375 376 377 378 379 380
            aspect_ratios=[
                [2.0],
                [2.0, 3.0],
                [2.0, 3.0],
                [2.0, 3.0],
                [2.0],
                [2.0],
            ],
C
chengduoZH 已提交
381 382 383
            base_size=300,
            offset=0.5,
            flip=True,
384 385
            clip=True,
        )
C
chengduoZH 已提交
386

C
chengduoZH 已提交
387
        return mbox_locs, mbox_confs, box, var
C
chengduoZH 已提交
388 389


390 391 392 393
class TestDetectionMAP(unittest.TestCase):
    def test_detection_map(self):
        program = Program()
        with program_guard(program):
394 395 396 397 398 399 400 401 402 403 404 405
            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',
            )
406

407
            map_out = detection.detection_map(detect_res, label, 21)
408
            self.assertIsNotNone(map_out)
409
            self.assertEqual(map_out.shape, (1,))
410
        print(str(program))
411 412


413
class TestGenerateProposals(LayerTest):
414
    def test_generate_proposals(self):
415 416 417
        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')
418 419 420
        anchors_np = np.reshape(np.arange(4 * 4 * 3 * 4), [4, 4, 3, 4]).astype(
            'float32'
        )
421 422 423
        variances_np = np.ones((4, 4, 3, 4)).astype('float32')

        with self.static_graph():
424 425 426 427 428 429
            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'
            )
430
            im_info = fluid.data(name='im_info', shape=[2, 3], dtype='float32')
431 432 433 434 435 436
            anchors = fluid.data(
                name='anchors', shape=[4, 4, 3, 4], dtype='float32'
            )
            variances = fluid.data(
                name='var', shape=[4, 4, 3, 4], dtype='float32'
            )
437 438 439 440 441 442 443 444
            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,
445 446 447 448 449 450 451
                return_rois_num=True,
            )
            (
                rois_stat,
                roi_probs_stat,
                rois_num_stat,
            ) = self.get_static_graph_result(
452 453 454 455 456
                feed={
                    'scores': scores_np,
                    'bbox_deltas': bbox_deltas_np,
                    'im_info': im_info_np,
                    'anchors': anchors_np,
457
                    'var': variances_np,
458 459
                },
                fetch_list=[rois, roi_probs, rois_num],
460 461
                with_lod=False,
            )
462 463 464 465 466 467 468 469 470 471 472 473 474 475 476

        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,
477 478
                return_rois_num=True,
            )
479 480 481 482
            rois_dy = rois.numpy()
            roi_probs_dy = roi_probs.numpy()
            rois_num_dy = rois_num.numpy()

483 484 485
        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)
486 487


J
jerrywgz 已提交
488 489 490 491
class TestBoxClip(unittest.TestCase):
    def test_box_clip(self):
        program = Program()
        with program_guard(program):
492 493 494
            input_box = layers.data(
                name='input_box', shape=[7, 4], dtype='float32', lod_level=1
            )
J
jerrywgz 已提交
495 496 497 498
            im_info = layers.data(name='im_info', shape=[3], dtype='float32')
            out = layers.box_clip(input_box, im_info)
            self.assertIsNotNone(out)

J
jerrywgz 已提交
499

J
jerrywgz 已提交
500 501 502 503
class TestMulticlassNMS(unittest.TestCase):
    def test_multiclass_nms(self):
        program = Program()
        with program_guard(program):
504 505 506
            bboxes = layers.data(
                name='bboxes', shape=[-1, 10, 4], dtype='float32'
            )
J
jerrywgz 已提交
507
            scores = layers.data(name='scores', shape=[-1, 10], dtype='float32')
J
jerrywgz 已提交
508
            output = layers.multiclass_nms(bboxes, scores, 0.3, 400, 200, 0.7)
J
jerrywgz 已提交
509 510
            self.assertIsNotNone(output)

511 512 513
    def test_multiclass_nms_error(self):
        program = Program()
        with program_guard(program):
514 515 516 517 518 519 520 521 522
            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'
            )
523
            scores2 = fluid.data(name='scores2', shape=[10, 10], dtype='int32')
524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541
            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,
            )
542

J
jerrywgz 已提交
543

544 545 546 547
class TestMulticlassNMS2(unittest.TestCase):
    def test_multiclass_nms2(self):
        program = Program()
        with program_guard(program):
548 549 550
            bboxes = layers.data(
                name='bboxes', shape=[-1, 10, 4], dtype='float32'
            )
551
            scores = layers.data(name='scores', shape=[-1, 10], dtype='float32')
552 553 554 555 556 557
            output = fluid.contrib.multiclass_nms2(
                bboxes, scores, 0.3, 400, 200, 0.7
            )
            output2, index = fluid.contrib.multiclass_nms2(
                bboxes, scores, 0.3, 400, 200, 0.7, return_index=True
            )
558 559 560 561 562
            self.assertIsNotNone(output)
            self.assertIsNotNone(output2)
            self.assertIsNotNone(index)


563
class TestCollectFpnPropsals(LayerTest):
564
    def test_collect_fpn_proposals(self):
565 566 567 568 569 570 571 572 573 574 575 576
        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():
577 578
            multi_bboxes = []
            multi_scores = []
579
            rois_num_per_level = []
580
            for i in range(4):
581 582 583 584 585 586 587 588 589 590 591 592 593 594 595
                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'
                )
596

597 598
                multi_bboxes.append(bboxes)
                multi_scores.append(scores)
599 600 601 602 603 604 605 606
                rois_num_per_level.append(rois_num)

            fpn_rois, rois_num = layers.collect_fpn_proposals(
                multi_bboxes,
                multi_scores,
                2,
                5,
                10,
607 608
                rois_num_per_level=rois_num_per_level,
            )
609 610 611 612 613 614
            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(
615 616
                feed=feed, fetch_list=[fpn_rois, rois_num], with_lod=True
            )
617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636
            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,
637 638
                rois_num_per_level=rois_num_per_level_dy,
            )
639 640 641
            fpn_rois_dy = fpn_rois_dy.numpy()
            rois_num_dy = rois_num_dy.numpy()

642 643
        np.testing.assert_array_equal(fpn_rois_stat, fpn_rois_dy)
        np.testing.assert_array_equal(rois_num_stat, rois_num_dy)
644

645 646 647 648 649
    def test_collect_fpn_proposals_error(self):
        def generate_input(bbox_type, score_type, name):
            multi_bboxes = []
            multi_scores = []
            for i in range(4):
650 651 652 653 654 655 656 657 658 659 660 661
                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,
                )
662 663 664 665 666 667
                multi_bboxes.append(bboxes)
                multi_scores.append(scores)
            return multi_bboxes, multi_scores

        program = Program()
        with program_guard(program):
668 669 670 671 672 673
            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
            )
674
            bbox2, score2 = generate_input('int32', 'float32', '2')
675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692
            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,
            )
693

694

695
class TestDistributeFpnProposals(LayerTest):
696
    def test_distribute_fpn_proposals(self):
697 698 699 700 701
        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')
702 703 704 705 706
            (
                multi_rois,
                restore_ind,
                rois_num_per_level,
            ) = layers.distribute_fpn_proposals(
707 708 709 710 711
                fpn_rois=rois,
                min_level=2,
                max_level=5,
                refer_level=4,
                refer_scale=224,
712 713
                rois_num=rois_num,
            )
714
            fetch_list = multi_rois + [restore_ind] + rois_num_per_level
715 716 717 718 719
            output_stat = self.get_static_graph_result(
                feed={'rois': rois_np, 'rois_num': rois_num_np},
                fetch_list=fetch_list,
                with_lod=True,
            )
720 721 722 723 724 725 726 727 728
            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)
729 730 731 732 733
            (
                multi_rois_dy,
                restore_ind_dy,
                rois_num_per_level_dy,
            ) = layers.distribute_fpn_proposals(
734
                fpn_rois=rois_dy,
735 736 737
                min_level=2,
                max_level=5,
                refer_level=4,
738
                refer_scale=224,
739 740
                rois_num=rois_num_dy,
            )
H
hong 已提交
741
            print(type(multi_rois_dy))
742 743 744 745 746 747 748 749
            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):
750
            np.testing.assert_array_equal(res_stat, res_dy)
751

752 753 754
    def test_distribute_fpn_proposals_error(self):
        program = Program()
        with program_guard(program):
755 756 757 758 759 760 761 762 763 764 765 766
            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,
            )
767 768 769 770 771 772 773 774


class TestBoxDecoderAndAssign(unittest.TestCase):
    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')
775 776 777 778 779 780 781 782 783 784
            loc = fluid.data(
                name='target_box', shape=[None, 4 * 81], dtype='float32'
            )
            scores = fluid.data(
                name='scores', shape=[None, 81], dtype='float32'
            )
            (
                decoded_box,
                output_assign_box,
            ) = fluid.layers.box_decoder_and_assign(pb, pbv, loc, scores, 4.135)
785 786 787 788 789
            self.assertIsNotNone(decoded_box)
            self.assertIsNotNone(output_assign_box)

    def test_box_decoder_and_assign_error(self):
        def generate_input(pb_type, pbv_type, loc_type, score_type, name):
790 791 792 793 794 795 796 797 798 799 800 801
            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
            )
802 803 804 805
            return pb, pbv, loc, scores

        program = Program()
        with program_guard(program):
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
            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'
            )
            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,
            )
842

843

844
if __name__ == '__main__':
H
hong 已提交
845
    paddle.enable_static()
846
    unittest.main()