瀏覽代碼

update ppdet

will-jl944 4 年之前
父節點
當前提交
285d477419

+ 0 - 13
paddlex/ppdet/model_zoo/tests/__init__.py

@@ -1,13 +0,0 @@
-#   Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
-#
-# 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.

+ 0 - 48
paddlex/ppdet/model_zoo/tests/test_get_model.py

@@ -1,48 +0,0 @@
-#   Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
-#
-# 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.
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import os
-import paddle
-import paddlex.ppdet
-import unittest
-
-# NOTE: weights downloading costs time, we choose
-#       a small model for unittesting
-MODEL_NAME = 'ppyolo/ppyolo_tiny_650e_coco'
-
-
-class TestGetConfigFile(unittest.TestCase):
-    def test_main(self):
-        try:
-            cfg_file = ppdet.model_zoo.get_config_file(MODEL_NAME)
-            assert os.path.isfile(cfg_file)
-        except:
-            self.assertTrue(False)
-
-
-class TestGetModel(unittest.TestCase):
-    def test_main(self):
-        try:
-            model = ppdet.model_zoo.get_model(MODEL_NAME)
-            assert isinstance(model, paddle.nn.Layer)
-        except:
-            self.assertTrue(False)
-
-
-if __name__ == '__main__':
-    unittest.main()

+ 0 - 68
paddlex/ppdet/model_zoo/tests/test_list_model.py

@@ -1,68 +0,0 @@
-#   Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
-#
-# 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.
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import unittest
-import paddlex.ppdet
-
-
-class TestListModel(unittest.TestCase):
-    def setUp(self):
-        self._filter = []
-
-    def test_main(self):
-        try:
-            ppdet.model_zoo.list_model(self._filter)
-            self.assertTrue(True)
-        except:
-            self.assertTrue(False)
-
-
-class TestListModelYOLO(TestListModel):
-    def setUp(self):
-        self._filter = ['yolo']
-
-
-class TestListModelRCNN(TestListModel):
-    def setUp(self):
-        self._filter = ['rcnn']
-
-
-class TestListModelSSD(TestListModel):
-    def setUp(self):
-        self._filter = ['ssd']
-
-
-class TestListModelMultiFilter(TestListModel):
-    def setUp(self):
-        self._filter = ['yolo', 'darknet']
-
-
-class TestListModelError(unittest.TestCase):
-    def setUp(self):
-        self._filter = ['xxx']
-
-    def test_main(self):
-        try:
-            ppdet.model_zoo.list_model(self._filter)
-            self.assertTrue(False)
-        except ValueError:
-            self.assertTrue(True)
-
-
-if __name__ == '__main__':
-    unittest.main()

+ 0 - 135
paddlex/ppdet/modeling/necks/pan.py

@@ -1,135 +0,0 @@
-# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
-#
-# 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.
-
-import numpy as np
-import paddle
-import paddle.nn as nn
-import paddle.nn.functional as F
-from paddle import ParamAttr
-from paddle.nn.initializer import XavierUniform
-from paddle.regularizer import L2Decay
-from paddlex.ppdet.core.workspace import register, serializable
-from paddlex.ppdet.modeling.layers import ConvNormLayer
-from ..shape_spec import ShapeSpec
-
-__all__ = ['PAN']
-
-
-@register
-@serializable
-class PAN(nn.Layer):
-    """
-    Path Aggregation Network, see https://arxiv.org/abs/1803.01534
-
-    Args:
-        in_channels (list[int]): input channels of each level which can be
-            derived from the output shape of backbone by from_config
-        out_channel (list[int]): output channel of each level
-        spatial_scales (list[float]): the spatial scales between input feature
-            maps and original input image which can be derived from the output
-            shape of backbone by from_config
-        has_extra_convs (bool): whether to add extra conv to the last level.
-            default False
-        extra_stage (int): the number of extra stages added to the last level.
-            default 1
-        use_c5 (bool): Whether to use c5 as the input of extra stage,
-            otherwise p5 is used. default True
-        norm_type (string|None): The normalization type in FPN module. If
-            norm_type is None, norm will not be used after conv and if
-            norm_type is string, bn, gn, sync_bn are available. default None
-        norm_decay (float): weight decay for normalization layer weights.
-            default 0.
-        freeze_norm (bool): whether to freeze normalization layer.
-            default False
-        relu_before_extra_convs (bool): whether to add relu before extra convs.
-            default False
-    """
-
-    def __init__(self,
-                 in_channels,
-                 out_channel,
-                 spatial_scales=[0.125, 0.0625, 0.03125],
-                 start_level=0,
-                 end_level=-1,
-                 norm_type=None):
-        super(PAN, self).__init__()
-        self.out_channel = out_channel
-        self.num_ins = len(in_channels)
-        self.spatial_scales = spatial_scales
-        if end_level == -1:
-            self.end_level = self.num_ins
-        else:
-            # if end_level < inputs, no extra level is allowed
-            self.end_level = end_level
-            assert end_level <= len(in_channels)
-        self.start_level = start_level
-        self.norm_type = norm_type
-        self.lateral_convs = []
-
-        for i in range(self.start_level, self.end_level):
-            in_c = in_channels[i - self.start_level]
-            if self.norm_type is not None:
-                lateral = self.add_sublayer(
-                    'pan_lateral' + str(i),
-                    ConvNormLayer(
-                        ch_in=in_c,
-                        ch_out=self.out_channel,
-                        filter_size=1,
-                        stride=1,
-                        norm_type=self.norm_type,
-                        norm_decay=self.norm_decay,
-                        freeze_norm=self.freeze_norm,
-                        initializer=XavierUniform(fan_out=in_c)))
-            else:
-                lateral = self.add_sublayer(
-                    'pan_lateral' + str(i),
-                    nn.Conv2D(
-                        in_channels=in_c,
-                        out_channels=self.out_channel,
-                        kernel_size=1,
-                        weight_attr=ParamAttr(
-                            initializer=XavierUniform(fan_out=in_c))))
-            self.lateral_convs.append(lateral)
-
-    @classmethod
-    def from_config(cls, cfg, input_shape):
-        return {'in_channels': [i.channels for i in input_shape], }
-
-    def forward(self, body_feats):
-        laterals = []
-        for i, lateral_conv in enumerate(self.lateral_convs):
-            laterals.append(lateral_conv(body_feats[i + self.start_level]))
-        num_levels = len(laterals)
-        for i in range(1, num_levels):
-            lvl = num_levels - i
-            upsample = F.interpolate(
-                laterals[lvl],
-                scale_factor=2.,
-                mode='bilinear', )
-            laterals[lvl - 1] += upsample
-
-        outs = [laterals[i] for i in range(num_levels)]
-        for i in range(0, num_levels - 1):
-            outs[i + 1] += F.interpolate(
-                outs[i], scale_factor=0.5, mode='bilinear')
-
-        return outs
-
-    @property
-    def out_shape(self):
-        return [
-            ShapeSpec(
-                channels=self.out_channel, stride=1. / s)
-            for s in self.spatial_scales
-        ]

+ 2 - 2
paddlex/ppdet/modeling/ops.py

@@ -473,7 +473,7 @@ def distribute_fpn_proposals(fpn_rois,
                              pixel_offset=False,
                              rois_num=None,
                              name=None):
-    r"""
+    """
 
     **This op only takes LoDTensor as input.** In Feature Pyramid Networks
     (FPN) models, it is needed to distribute all proposals into different FPN
@@ -1275,7 +1275,7 @@ def box_coder(prior_box,
               box_normalized=True,
               axis=0,
               name=None):
-    r"""
+    """
     **Box Coder Layer**
     Encode/Decode the target bounding box with the priorbox information.
 

+ 18 - 3
paddlex/ppdet/modeling/post_process.py

@@ -91,9 +91,23 @@ class BBoxPostProcess(nn.Layer):
                 including labels, scores and bboxes.
         """
 
-        if bboxes.shape[0] == 0:
-            bboxes = self.fake_bboxes
-            bbox_num = self.fake_bbox_num
+        bboxes_list = []
+        bbox_num_list = []
+        id_start = 0
+        # add fake bbox when output is empty for each batch
+        for i in range(bbox_num.shape[0]):
+            if bbox_num[i] == 0:
+                bboxes_i = self.fake_bboxes
+                bbox_num_i = self.fake_bbox_num
+                id_start += 1
+            else:
+                bboxes_i = bboxes[id_start:id_start + bbox_num[i], :]
+                bbox_num_i = bbox_num[i]
+                id_start += bbox_num[i]
+            bboxes_list.append(bboxes_i)
+            bbox_num_list.append(bbox_num_i)
+        bboxes = paddle.concat(bboxes_list)
+        bbox_num = paddle.concat(bbox_num_list)
 
         origin_shape = paddle.floor(im_shape / scale_factor + 0.5)
 
@@ -157,6 +171,7 @@ class MaskPostProcess(object):
         """
         Paste the mask prediction to the original image.
         """
+
         x0, y0, x1, y1 = paddle.split(boxes, 4, axis=1)
         masks = paddle.unsqueeze(masks, [0, 1])
         img_y = paddle.arange(0, im_h, dtype='float32') + 0.5

+ 0 - 13
paddlex/ppdet/modeling/tests/__init__.py

@@ -1,13 +0,0 @@
-#   Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
-#
-# 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.

二進制
paddlex/ppdet/modeling/tests/imgs/coco2017_val2017_000000000139.jpg


二進制
paddlex/ppdet/modeling/tests/imgs/coco2017_val2017_000000000724.jpg


+ 0 - 69
paddlex/ppdet/modeling/tests/test_architectures.py

@@ -1,69 +0,0 @@
-#   Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
-#
-# 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.
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import unittest
-import paddlex.ppdet
-
-
-class TestFasterRCNN(unittest.TestCase):
-    def setUp(self):
-        self.set_config()
-
-    def set_config(self):
-        self.cfg_file = 'configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.yml'
-
-    def test_trainer(self):
-        # Trainer __init__ will build model and DataLoader
-        # 'train' and 'eval' mode include dataset loading
-        # use 'test' mode to simplify tests
-        cfg = ppdet.core.workspace.load_config(self.cfg_file)
-        trainer = ppdet.engine.Trainer(cfg, mode='test')
-
-
-class TestMaskRCNN(TestFasterRCNN):
-    def set_config(self):
-        self.cfg_file = 'configs/mask_rcnn/mask_rcnn_r50_fpn_1x_coco.yml'
-
-
-class TestCascadeRCNN(TestFasterRCNN):
-    def set_config(self):
-        self.cfg_file = 'configs/cascade_rcnn/cascade_rcnn_r50_fpn_1x_coco.yml'
-
-
-class TestYolov3(TestFasterRCNN):
-    def set_config(self):
-        self.cfg_file = 'configs/yolov3/yolov3_darknet53_270e_coco.yml'
-
-
-class TestSSD(TestFasterRCNN):
-    def set_config(self):
-        self.cfg_file = 'configs/ssd/ssd_vgg16_300_240e_voc.yml'
-
-
-class TestGFL(TestFasterRCNN):
-    def set_config(self):
-        self.cfg_file = 'configs/gfl/gfl_r50_fpn_1x_coco.yml'
-
-
-class TestPicoDet(TestFasterRCNN):
-    def set_config(self):
-        self.cfg_file = 'configs/picodet/picodet_s_320_coco.yml'
-
-
-if __name__ == '__main__':
-    unittest.main()

+ 0 - 74
paddlex/ppdet/modeling/tests/test_base.py

@@ -1,74 +0,0 @@
-#   Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
-#
-# 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.
-
-from __future__ import print_function
-import unittest
-
-import contextlib
-
-import paddle
-import paddle.fluid as fluid
-from paddle.fluid.framework import Program
-from paddle.fluid import core
-
-
-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):
-        paddle.enable_static()
-        scope = fluid.core.Scope()
-        program = Program()
-        with fluid.scope_guard(scope):
-            with fluid.program_guard(program):
-                paddle.seed(self.seed)
-                paddle.framework.random._manual_program_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):
-        paddle.disable_static()
-        with fluid.dygraph.guard(
-                self._get_place(force_to_use_cpu=force_to_use_cpu)):
-            paddle.seed(self.seed)
-            paddle.framework.random._manual_program_seed(self.seed)
-            yield

+ 0 - 62
paddlex/ppdet/modeling/tests/test_mstest.py

@@ -1,62 +0,0 @@
-#   Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
-#
-# 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.
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import os
-import unittest
-from paddlex.ppdet.core.workspace import load_config
-from paddlex.ppdet.engine import Trainer
-
-
-class TestMultiScaleInference(unittest.TestCase):
-    def setUp(self):
-        self.set_config()
-
-    def set_config(self):
-        self.mstest_cfg_file = 'configs/faster_rcnn/faster_rcnn_r34_fpn_multiscaletest_1x_coco.yml'
-
-    # test evaluation with multi scale test
-    def test_eval_mstest(self):
-        cfg = load_config(self.mstest_cfg_file)
-        trainer = Trainer(cfg, mode='eval')
-
-        cfg.weights = 'https://paddledet.bj.bcebos.com/models/faster_rcnn_r34_fpn_1x_coco.pdparams'
-        trainer.load_weights(cfg.weights)
-
-        trainer.evaluate()
-
-    # test inference with multi scale test
-    def test_infer_mstest(self):
-        cfg = load_config(self.mstest_cfg_file)
-        trainer = Trainer(cfg, mode='test')
-
-        cfg.weights = 'https://paddledet.bj.bcebos.com/models/faster_rcnn_r34_fpn_1x_coco.pdparams'
-        trainer.load_weights(cfg.weights)
-        tests_img_root = os.path.join(os.path.dirname(__file__), 'imgs')
-
-        # input images to predict
-        imgs = [
-            'coco2017_val2017_000000000139.jpg',
-            'coco2017_val2017_000000000724.jpg'
-        ]
-        imgs = [os.path.join(tests_img_root, img) for img in imgs]
-        trainer.predict(
-            imgs, draw_threshold=0.5, output_dir='output', save_txt=True)
-
-
-if __name__ == '__main__':
-    unittest.main()

+ 0 - 838
paddlex/ppdet/modeling/tests/test_ops.py

@@ -1,838 +0,0 @@
-#   Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
-#
-# 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.
-
-from __future__ import print_function
-import os, sys
-# add python path of PadleDetection to sys.path
-parent_path = os.path.abspath(os.path.join(__file__, *(['..'] * 4)))
-if parent_path not in sys.path:
-    sys.path.append(parent_path)
-
-import unittest
-import numpy as np
-
-import paddle
-import paddle.fluid as fluid
-from paddle.fluid.dygraph import base
-
-import paddlex.ppdet.modeling.ops as ops
-from paddlex.ppdet.modeling.tests.test_base import LayerTest
-
-
-def make_rois(h, w, rois_num, output_size):
-    rois = np.zeros((0, 4)).astype('float32')
-    for roi_num in rois_num:
-        roi = np.zeros((roi_num, 4)).astype('float32')
-        roi[:, 0] = np.random.randint(0, h - output_size[0], size=roi_num)
-        roi[:, 1] = np.random.randint(0, w - output_size[1], size=roi_num)
-        roi[:, 2] = np.random.randint(roi[:, 0] + output_size[0], h)
-        roi[:, 3] = np.random.randint(roi[:, 1] + output_size[1], w)
-        rois = np.vstack((rois, roi))
-    return rois
-
-
-def softmax(x):
-    # clip to shiftx, otherwise, when calc loss with
-    # log(exp(shiftx)), may get log(0)=INF
-    shiftx = (x - np.max(x)).clip(-64.)
-    exps = np.exp(shiftx)
-    return exps / np.sum(exps)
-
-
-class TestCollectFpnProposals(LayerTest):
-    def test_collect_fpn_proposals(self):
-        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():
-            multi_bboxes = []
-            multi_scores = []
-            rois_num_per_level = []
-            for i in range(4):
-                bboxes = paddle.static.data(
-                    name='rois' + str(i),
-                    shape=[5, 4],
-                    dtype='float32',
-                    lod_level=1)
-                scores = paddle.static.data(
-                    name='scores' + str(i),
-                    shape=[5, 1],
-                    dtype='float32',
-                    lod_level=1)
-                rois_num = paddle.static.data(
-                    name='rois_num' + str(i), shape=[None], dtype='int32')
-
-                multi_bboxes.append(bboxes)
-                multi_scores.append(scores)
-                rois_num_per_level.append(rois_num)
-
-            fpn_rois, rois_num = ops.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 = ops.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))
-
-    def test_collect_fpn_proposals_error(self):
-        def generate_input(bbox_type, score_type, name):
-            multi_bboxes = []
-            multi_scores = []
-            for i in range(4):
-                bboxes = paddle.static.data(
-                    name='rois' + name + str(i),
-                    shape=[10, 4],
-                    dtype=bbox_type,
-                    lod_level=1)
-                scores = paddle.static.data(
-                    name='scores' + name + str(i),
-                    shape=[10, 1],
-                    dtype=score_type,
-                    lod_level=1)
-                multi_bboxes.append(bboxes)
-                multi_scores.append(scores)
-            return multi_bboxes, multi_scores
-
-        with self.static_graph():
-            bbox1 = paddle.static.data(
-                name='rois', shape=[5, 10, 4], dtype='float32', lod_level=1)
-            score1 = paddle.static.data(
-                name='scores', shape=[5, 10, 1], dtype='float32', lod_level=1)
-            bbox2, score2 = generate_input('int32', 'float32', '2')
-            self.assertRaises(
-                TypeError,
-                ops.collect_fpn_proposals,
-                multi_rois=bbox1,
-                multi_scores=score1,
-                min_level=2,
-                max_level=5,
-                post_nms_top_n=2000)
-            self.assertRaises(
-                TypeError,
-                ops.collect_fpn_proposals,
-                multi_rois=bbox2,
-                multi_scores=score2,
-                min_level=2,
-                max_level=5,
-                post_nms_top_n=2000)
-
-        paddle.disable_static()
-
-
-class TestDistributeFpnProposals(LayerTest):
-    def test_distribute_fpn_proposals(self):
-        rois_np = np.random.rand(10, 4).astype('float32')
-        rois_num_np = np.array([4, 6]).astype('int32')
-        with self.static_graph():
-            rois = paddle.static.data(
-                name='rois', shape=[10, 4], dtype='float32')
-            rois_num = paddle.static.data(
-                name='rois_num', shape=[None], dtype='int32')
-            multi_rois, restore_ind, rois_num_per_level = ops.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
-            output_stat = self.get_static_graph_result(
-                feed={'rois': rois_np,
-                      'rois_num': rois_num_np},
-                fetch_list=fetch_list,
-                with_lod=True)
-            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 = ops.distribute_fpn_proposals(
-                fpn_rois=rois_dy,
-                min_level=2,
-                max_level=5,
-                refer_level=4,
-                refer_scale=224,
-                rois_num=rois_num_dy)
-            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))
-
-    def test_distribute_fpn_proposals_error(self):
-        with self.static_graph():
-            fpn_rois = paddle.static.data(
-                name='data_error', shape=[10, 4], dtype='int32', lod_level=1)
-            self.assertRaises(
-                TypeError,
-                ops.distribute_fpn_proposals,
-                fpn_rois=fpn_rois,
-                min_level=2,
-                max_level=5,
-                refer_level=4,
-                refer_scale=224)
-
-        paddle.disable_static()
-
-
-class TestROIAlign(LayerTest):
-    def test_roi_align(self):
-        b, c, h, w = 2, 12, 20, 20
-        inputs_np = np.random.rand(b, c, h, w).astype('float32')
-        rois_num = [4, 6]
-        output_size = (7, 7)
-        rois_np = make_rois(h, w, rois_num, output_size)
-        rois_num_np = np.array(rois_num).astype('int32')
-        with self.static_graph():
-            inputs = paddle.static.data(
-                name='inputs', shape=[b, c, h, w], dtype='float32')
-            rois = paddle.static.data(
-                name='rois', shape=[10, 4], dtype='float32')
-            rois_num = paddle.static.data(
-                name='rois_num', shape=[None], dtype='int32')
-
-            output = ops.roi_align(
-                input=inputs,
-                rois=rois,
-                output_size=output_size,
-                rois_num=rois_num)
-            output_np, = self.get_static_graph_result(
-                feed={
-                    'inputs': inputs_np,
-                    'rois': rois_np,
-                    'rois_num': rois_num_np
-                },
-                fetch_list=output,
-                with_lod=False)
-
-        with self.dynamic_graph():
-            inputs_dy = base.to_variable(inputs_np)
-            rois_dy = base.to_variable(rois_np)
-            rois_num_dy = base.to_variable(rois_num_np)
-
-            output_dy = ops.roi_align(
-                input=inputs_dy,
-                rois=rois_dy,
-                output_size=output_size,
-                rois_num=rois_num_dy)
-            output_dy_np = output_dy.numpy()
-
-        self.assertTrue(np.array_equal(output_np, output_dy_np))
-
-    def test_roi_align_error(self):
-        with self.static_graph():
-            inputs = paddle.static.data(
-                name='inputs', shape=[2, 12, 20, 20], dtype='float32')
-            rois = paddle.static.data(
-                name='data_error', shape=[10, 4], dtype='int32', lod_level=1)
-            self.assertRaises(
-                TypeError,
-                ops.roi_align,
-                input=inputs,
-                rois=rois,
-                output_size=(7, 7))
-
-        paddle.disable_static()
-
-
-class TestROIPool(LayerTest):
-    def test_roi_pool(self):
-        b, c, h, w = 2, 12, 20, 20
-        inputs_np = np.random.rand(b, c, h, w).astype('float32')
-        rois_num = [4, 6]
-        output_size = (7, 7)
-        rois_np = make_rois(h, w, rois_num, output_size)
-        rois_num_np = np.array(rois_num).astype('int32')
-        with self.static_graph():
-            inputs = paddle.static.data(
-                name='inputs', shape=[b, c, h, w], dtype='float32')
-            rois = paddle.static.data(
-                name='rois', shape=[10, 4], dtype='float32')
-            rois_num = paddle.static.data(
-                name='rois_num', shape=[None], dtype='int32')
-
-            output, _ = ops.roi_pool(
-                input=inputs,
-                rois=rois,
-                output_size=output_size,
-                rois_num=rois_num)
-            output_np, = self.get_static_graph_result(
-                feed={
-                    'inputs': inputs_np,
-                    'rois': rois_np,
-                    'rois_num': rois_num_np
-                },
-                fetch_list=[output],
-                with_lod=False)
-
-        with self.dynamic_graph():
-            inputs_dy = base.to_variable(inputs_np)
-            rois_dy = base.to_variable(rois_np)
-            rois_num_dy = base.to_variable(rois_num_np)
-
-            output_dy, _ = ops.roi_pool(
-                input=inputs_dy,
-                rois=rois_dy,
-                output_size=output_size,
-                rois_num=rois_num_dy)
-            output_dy_np = output_dy.numpy()
-
-        self.assertTrue(np.array_equal(output_np, output_dy_np))
-
-    def test_roi_pool_error(self):
-        with self.static_graph():
-            inputs = paddle.static.data(
-                name='inputs', shape=[2, 12, 20, 20], dtype='float32')
-            rois = paddle.static.data(
-                name='data_error', shape=[10, 4], dtype='int32', lod_level=1)
-            self.assertRaises(
-                TypeError,
-                ops.roi_pool,
-                input=inputs,
-                rois=rois,
-                output_size=(7, 7))
-
-        paddle.disable_static()
-
-
-class TestIoUSimilarity(LayerTest):
-    def test_iou_similarity(self):
-        b, c, h, w = 2, 12, 20, 20
-        inputs_np = np.random.rand(b, c, h, w).astype('float32')
-        output_size = (7, 7)
-        x_np = make_rois(h, w, [20], output_size)
-        y_np = make_rois(h, w, [10], output_size)
-        with self.static_graph():
-            x = paddle.static.data(name='x', shape=[20, 4], dtype='float32')
-            y = paddle.static.data(name='y', shape=[10, 4], dtype='float32')
-
-            iou = ops.iou_similarity(x=x, y=y)
-            iou_np, = self.get_static_graph_result(
-                feed={
-                    'x': x_np,
-                    'y': y_np,
-                },
-                fetch_list=[iou],
-                with_lod=False)
-
-        with self.dynamic_graph():
-            x_dy = base.to_variable(x_np)
-            y_dy = base.to_variable(y_np)
-
-            iou_dy = ops.iou_similarity(x=x_dy, y=y_dy)
-            iou_dy_np = iou_dy.numpy()
-
-        self.assertTrue(np.array_equal(iou_np, iou_dy_np))
-
-
-class TestBipartiteMatch(LayerTest):
-    def test_bipartite_match(self):
-        distance = np.random.random((20, 10)).astype('float32')
-        with self.static_graph():
-            x = paddle.static.data(name='x', shape=[20, 10], dtype='float32')
-
-            match_indices, match_dist = ops.bipartite_match(
-                x, match_type='per_prediction', dist_threshold=0.5)
-            match_indices_np, match_dist_np = self.get_static_graph_result(
-                feed={'x': distance, },
-                fetch_list=[match_indices, match_dist],
-                with_lod=False)
-
-        with self.dynamic_graph():
-            x_dy = base.to_variable(distance)
-
-            match_indices_dy, match_dist_dy = ops.bipartite_match(
-                x_dy, match_type='per_prediction', dist_threshold=0.5)
-            match_indices_dy_np = match_indices_dy.numpy()
-            match_dist_dy_np = match_dist_dy.numpy()
-
-        self.assertTrue(np.array_equal(match_indices_np, match_indices_dy_np))
-        self.assertTrue(np.array_equal(match_dist_np, match_dist_dy_np))
-
-
-class TestYoloBox(LayerTest):
-    def test_yolo_box(self):
-
-        # x shape [N C H W], C=K * (5 + class_num), class_num=10, K=2
-        np_x = np.random.random([1, 30, 7, 7]).astype('float32')
-        np_origin_shape = np.array([[608, 608]], dtype='int32')
-        class_num = 10
-        conf_thresh = 0.01
-        downsample_ratio = 32
-        scale_x_y = 1.2
-
-        # static
-        with self.static_graph():
-            # x shape [N C H W], C=K * (5 + class_num), class_num=10, K=2
-            x = paddle.static.data(
-                name='x', shape=[1, 30, 7, 7], dtype='float32')
-            origin_shape = paddle.static.data(
-                name='origin_shape', shape=[1, 2], dtype='int32')
-
-            boxes, scores = ops.yolo_box(
-                x,
-                origin_shape, [10, 13, 30, 13],
-                class_num,
-                conf_thresh,
-                downsample_ratio,
-                scale_x_y=scale_x_y)
-
-            boxes_np, scores_np = self.get_static_graph_result(
-                feed={
-                    'x': np_x,
-                    'origin_shape': np_origin_shape,
-                },
-                fetch_list=[boxes, scores],
-                with_lod=False)
-
-        # dygraph
-        with self.dynamic_graph():
-            x_dy = fluid.layers.assign(np_x)
-            origin_shape_dy = fluid.layers.assign(np_origin_shape)
-
-            boxes_dy, scores_dy = ops.yolo_box(
-                x_dy,
-                origin_shape_dy, [10, 13, 30, 13],
-                10,
-                0.01,
-                32,
-                scale_x_y=scale_x_y)
-
-            boxes_dy_np = boxes_dy.numpy()
-            scores_dy_np = scores_dy.numpy()
-
-        self.assertTrue(np.array_equal(boxes_np, boxes_dy_np))
-        self.assertTrue(np.array_equal(scores_np, scores_dy_np))
-
-    def test_yolo_box_error(self):
-        with self.static_graph():
-            # x shape [N C H W], C=K * (5 + class_num), class_num=10, K=2
-            x = paddle.static.data(
-                name='x', shape=[1, 30, 7, 7], dtype='float32')
-            origin_shape = paddle.static.data(
-                name='origin_shape', shape=[1, 2], dtype='int32')
-
-            self.assertRaises(
-                TypeError,
-                ops.yolo_box,
-                x,
-                origin_shape, [10, 13, 30, 13],
-                10.123,
-                0.01,
-                32,
-                scale_x_y=1.2)
-
-        paddle.disable_static()
-
-
-class TestPriorBox(LayerTest):
-    def test_prior_box(self):
-        input_np = np.random.rand(2, 10, 32, 32).astype('float32')
-        image_np = np.random.rand(2, 10, 40, 40).astype('float32')
-        min_sizes = [2, 4]
-        with self.static_graph():
-            input = paddle.static.data(
-                name='input', shape=[2, 10, 32, 32], dtype='float32')
-            image = paddle.static.data(
-                name='image', shape=[2, 10, 40, 40], dtype='float32')
-
-            box, var = ops.prior_box(
-                input=input,
-                image=image,
-                min_sizes=min_sizes,
-                clip=True,
-                flip=True)
-            box_np, var_np = self.get_static_graph_result(
-                feed={
-                    'input': input_np,
-                    'image': image_np,
-                },
-                fetch_list=[box, var],
-                with_lod=False)
-
-        with self.dynamic_graph():
-            inputs_dy = base.to_variable(input_np)
-            image_dy = base.to_variable(image_np)
-
-            box_dy, var_dy = ops.prior_box(
-                input=inputs_dy,
-                image=image_dy,
-                min_sizes=min_sizes,
-                clip=True,
-                flip=True)
-            box_dy_np = box_dy.numpy()
-            var_dy_np = var_dy.numpy()
-
-        self.assertTrue(np.array_equal(box_np, box_dy_np))
-        self.assertTrue(np.array_equal(var_np, var_dy_np))
-
-    def test_prior_box_error(self):
-        with self.static_graph():
-            input = paddle.static.data(
-                name='input', shape=[2, 10, 32, 32], dtype='int32')
-            image = paddle.static.data(
-                name='image', shape=[2, 10, 40, 40], dtype='int32')
-            self.assertRaises(
-                TypeError,
-                ops.prior_box,
-                input=input,
-                image=image,
-                min_sizes=[2, 4],
-                clip=True,
-                flip=True)
-
-        paddle.disable_static()
-
-
-class TestMulticlassNms(LayerTest):
-    def test_multiclass_nms(self):
-        boxes_np = np.random.rand(10, 81, 4).astype('float32')
-        scores_np = np.random.rand(10, 81).astype('float32')
-        rois_num_np = np.array([2, 8]).astype('int32')
-        with self.static_graph():
-            boxes = paddle.static.data(
-                name='bboxes',
-                shape=[None, 81, 4],
-                dtype='float32',
-                lod_level=1)
-            scores = paddle.static.data(
-                name='scores', shape=[None, 81], dtype='float32', lod_level=1)
-            rois_num = paddle.static.data(
-                name='rois_num', shape=[None], dtype='int32')
-
-            output = ops.multiclass_nms(
-                bboxes=boxes,
-                scores=scores,
-                background_label=0,
-                score_threshold=0.5,
-                nms_top_k=400,
-                nms_threshold=0.3,
-                keep_top_k=200,
-                normalized=False,
-                return_index=True,
-                rois_num=rois_num)
-            out_np, index_np, nms_rois_num_np = self.get_static_graph_result(
-                feed={
-                    'bboxes': boxes_np,
-                    'scores': scores_np,
-                    'rois_num': rois_num_np
-                },
-                fetch_list=output,
-                with_lod=True)
-            out_np = np.array(out_np)
-            index_np = np.array(index_np)
-            nms_rois_num_np = np.array(nms_rois_num_np)
-
-        with self.dynamic_graph():
-            boxes_dy = base.to_variable(boxes_np)
-            scores_dy = base.to_variable(scores_np)
-            rois_num_dy = base.to_variable(rois_num_np)
-
-            out_dy, index_dy, nms_rois_num_dy = ops.multiclass_nms(
-                bboxes=boxes_dy,
-                scores=scores_dy,
-                background_label=0,
-                score_threshold=0.5,
-                nms_top_k=400,
-                nms_threshold=0.3,
-                keep_top_k=200,
-                normalized=False,
-                return_index=True,
-                rois_num=rois_num_dy)
-            out_dy_np = out_dy.numpy()
-            index_dy_np = index_dy.numpy()
-            nms_rois_num_dy_np = nms_rois_num_dy.numpy()
-
-        self.assertTrue(np.array_equal(out_np, out_dy_np))
-        self.assertTrue(np.array_equal(index_np, index_dy_np))
-        self.assertTrue(np.array_equal(nms_rois_num_np, nms_rois_num_dy_np))
-
-    def test_multiclass_nms_error(self):
-        with self.static_graph():
-            boxes = paddle.static.data(
-                name='bboxes', shape=[81, 4], dtype='float32', lod_level=1)
-            scores = paddle.static.data(
-                name='scores', shape=[81], dtype='float32', lod_level=1)
-            rois_num = paddle.static.data(
-                name='rois_num', shape=[40, 41], dtype='int32')
-            self.assertRaises(
-                TypeError,
-                ops.multiclass_nms,
-                boxes=boxes,
-                scores=scores,
-                background_label=0,
-                score_threshold=0.5,
-                nms_top_k=400,
-                nms_threshold=0.3,
-                keep_top_k=200,
-                normalized=False,
-                return_index=True,
-                rois_num=rois_num)
-
-
-class TestMatrixNMS(LayerTest):
-    def test_matrix_nms(self):
-        N, M, C = 7, 1200, 21
-        BOX_SIZE = 4
-        nms_top_k = 400
-        keep_top_k = 200
-        score_threshold = 0.01
-        post_threshold = 0.
-
-        scores_np = np.random.random((N * M, C)).astype('float32')
-        scores_np = np.apply_along_axis(softmax, 1, scores_np)
-        scores_np = np.reshape(scores_np, (N, M, C))
-        scores_np = np.transpose(scores_np, (0, 2, 1))
-
-        boxes_np = np.random.random((N, M, BOX_SIZE)).astype('float32')
-        boxes_np[:, :, 0:2] = boxes_np[:, :, 0:2] * 0.5
-        boxes_np[:, :, 2:4] = boxes_np[:, :, 2:4] * 0.5 + 0.5
-
-        with self.static_graph():
-            boxes = paddle.static.data(
-                name='boxes', shape=[N, M, BOX_SIZE], dtype='float32')
-            scores = paddle.static.data(
-                name='scores', shape=[N, C, M], dtype='float32')
-            out, index, _ = ops.matrix_nms(
-                bboxes=boxes,
-                scores=scores,
-                score_threshold=score_threshold,
-                post_threshold=post_threshold,
-                nms_top_k=nms_top_k,
-                keep_top_k=keep_top_k,
-                return_index=True)
-            out_np, index_np = self.get_static_graph_result(
-                feed={'boxes': boxes_np,
-                      'scores': scores_np},
-                fetch_list=[out, index],
-                with_lod=True)
-
-        with self.dynamic_graph():
-            boxes_dy = base.to_variable(boxes_np)
-            scores_dy = base.to_variable(scores_np)
-
-            out_dy, index_dy, _ = ops.matrix_nms(
-                bboxes=boxes_dy,
-                scores=scores_dy,
-                score_threshold=score_threshold,
-                post_threshold=post_threshold,
-                nms_top_k=nms_top_k,
-                keep_top_k=keep_top_k,
-                return_index=True)
-            out_dy_np = out_dy.numpy()
-            index_dy_np = index_dy.numpy()
-
-        self.assertTrue(np.array_equal(out_np, out_dy_np))
-        self.assertTrue(np.array_equal(index_np, index_dy_np))
-
-    def test_matrix_nms_error(self):
-        with self.static_graph():
-            bboxes = paddle.static.data(
-                name='bboxes', shape=[7, 1200, 4], dtype='float32')
-            scores = paddle.static.data(
-                name='data_error', shape=[7, 21, 1200], dtype='int32')
-            self.assertRaises(
-                TypeError,
-                ops.matrix_nms,
-                bboxes=bboxes,
-                scores=scores,
-                score_threshold=0.01,
-                post_threshold=0.,
-                nms_top_k=400,
-                keep_top_k=200,
-                return_index=True)
-
-        paddle.disable_static()
-
-
-class TestBoxCoder(LayerTest):
-    def test_box_coder(self):
-
-        prior_box_np = np.random.random((81, 4)).astype('float32')
-        prior_box_var_np = np.random.random((81, 4)).astype('float32')
-        target_box_np = np.random.random((20, 81, 4)).astype('float32')
-
-        # static
-        with self.static_graph():
-            prior_box = paddle.static.data(
-                name='prior_box', shape=[81, 4], dtype='float32')
-            prior_box_var = paddle.static.data(
-                name='prior_box_var', shape=[81, 4], dtype='float32')
-            target_box = paddle.static.data(
-                name='target_box', shape=[20, 81, 4], dtype='float32')
-
-            boxes = ops.box_coder(
-                prior_box=prior_box,
-                prior_box_var=prior_box_var,
-                target_box=target_box,
-                code_type="decode_center_size",
-                box_normalized=False)
-
-            boxes_np, = self.get_static_graph_result(
-                feed={
-                    'prior_box': prior_box_np,
-                    'prior_box_var': prior_box_var_np,
-                    'target_box': target_box_np,
-                },
-                fetch_list=[boxes],
-                with_lod=False)
-
-        # dygraph
-        with self.dynamic_graph():
-            prior_box_dy = base.to_variable(prior_box_np)
-            prior_box_var_dy = base.to_variable(prior_box_var_np)
-            target_box_dy = base.to_variable(target_box_np)
-
-            boxes_dy = ops.box_coder(
-                prior_box=prior_box_dy,
-                prior_box_var=prior_box_var_dy,
-                target_box=target_box_dy,
-                code_type="decode_center_size",
-                box_normalized=False)
-
-            boxes_dy_np = boxes_dy.numpy()
-
-            self.assertTrue(np.array_equal(boxes_np, boxes_dy_np))
-
-    def test_box_coder_error(self):
-        with self.static_graph():
-            prior_box = paddle.static.data(
-                name='prior_box', shape=[81, 4], dtype='int32')
-            prior_box_var = paddle.static.data(
-                name='prior_box_var', shape=[81, 4], dtype='float32')
-            target_box = paddle.static.data(
-                name='target_box', shape=[20, 81, 4], dtype='float32')
-
-            self.assertRaises(TypeError, ops.box_coder, prior_box,
-                              prior_box_var, target_box)
-
-        paddle.disable_static()
-
-
-class TestGenerateProposals(LayerTest):
-    def test_generate_proposals(self):
-        scores_np = np.random.rand(2, 3, 4, 4).astype('float32')
-        bbox_deltas_np = np.random.rand(2, 12, 4, 4).astype('float32')
-        im_shape_np = np.array([[8, 8], [6, 6]]).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():
-            scores = paddle.static.data(
-                name='scores', shape=[2, 3, 4, 4], dtype='float32')
-            bbox_deltas = paddle.static.data(
-                name='bbox_deltas', shape=[2, 12, 4, 4], dtype='float32')
-            im_shape = paddle.static.data(
-                name='im_shape', shape=[2, 2], dtype='float32')
-            anchors = paddle.static.data(
-                name='anchors', shape=[4, 4, 3, 4], dtype='float32')
-            variances = paddle.static.data(
-                name='var', shape=[4, 4, 3, 4], dtype='float32')
-            rois, roi_probs, rois_num = ops.generate_proposals(
-                scores,
-                bbox_deltas,
-                im_shape,
-                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_shape': im_shape_np,
-                    'anchors': anchors_np,
-                    'var': variances_np
-                },
-                fetch_list=[rois, roi_probs, rois_num],
-                with_lod=True)
-
-        with self.dynamic_graph():
-            scores_dy = base.to_variable(scores_np)
-            bbox_deltas_dy = base.to_variable(bbox_deltas_np)
-            im_shape_dy = base.to_variable(im_shape_np)
-            anchors_dy = base.to_variable(anchors_np)
-            variances_dy = base.to_variable(variances_np)
-            rois, roi_probs, rois_num = ops.generate_proposals(
-                scores_dy,
-                bbox_deltas_dy,
-                im_shape_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))
-
-
-if __name__ == '__main__':
-    unittest.main()

+ 0 - 415
paddlex/ppdet/modeling/tests/test_yolov3_loss.py

@@ -1,415 +0,0 @@
-#   Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
-#
-# 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.
-
-from __future__ import division
-
-import unittest
-
-import paddle
-from paddle import fluid
-# add python path of PadleDetection to sys.path
-import os
-import sys
-parent_path = os.path.abspath(os.path.join(__file__, *(['..'] * 4)))
-if parent_path not in sys.path:
-    sys.path.append(parent_path)
-
-from paddlex.ppdet.modeling.losses import YOLOv3Loss
-from paddlex.ppdet.data.transform.op_helper import jaccard_overlap
-import numpy as np
-
-
-def _split_ioup(output, an_num, num_classes):
-    """
-    Split output feature map to output, predicted iou
-    along channel dimension
-    """
-    ioup = fluid.layers.slice(output, axes=[1], starts=[0], ends=[an_num])
-    ioup = fluid.layers.sigmoid(ioup)
-    oriout = fluid.layers.slice(
-        output, axes=[1], starts=[an_num], ends=[an_num * (num_classes + 6)])
-    return (ioup, oriout)
-
-
-def _split_output(output, an_num, num_classes):
-    """
-    Split output feature map to x, y, w, h, objectness, classification
-    along channel dimension
-    """
-    x = fluid.layers.strided_slice(
-        output,
-        axes=[1],
-        starts=[0],
-        ends=[output.shape[1]],
-        strides=[5 + num_classes])
-    y = fluid.layers.strided_slice(
-        output,
-        axes=[1],
-        starts=[1],
-        ends=[output.shape[1]],
-        strides=[5 + num_classes])
-    w = fluid.layers.strided_slice(
-        output,
-        axes=[1],
-        starts=[2],
-        ends=[output.shape[1]],
-        strides=[5 + num_classes])
-    h = fluid.layers.strided_slice(
-        output,
-        axes=[1],
-        starts=[3],
-        ends=[output.shape[1]],
-        strides=[5 + num_classes])
-    obj = fluid.layers.strided_slice(
-        output,
-        axes=[1],
-        starts=[4],
-        ends=[output.shape[1]],
-        strides=[5 + num_classes])
-    clss = []
-    stride = output.shape[1] // an_num
-    for m in range(an_num):
-        clss.append(
-            fluid.layers.slice(
-                output,
-                axes=[1],
-                starts=[stride * m + 5],
-                ends=[stride * m + 5 + num_classes]))
-    cls = fluid.layers.transpose(
-        fluid.layers.stack(
-            clss, axis=1), perm=[0, 1, 3, 4, 2])
-    return (x, y, w, h, obj, cls)
-
-
-def _split_target(target):
-    """
-    split target to x, y, w, h, objectness, classification
-    along dimension 2
-    target is in shape [N, an_num, 6 + class_num, H, W]
-    """
-    tx = target[:, :, 0, :, :]
-    ty = target[:, :, 1, :, :]
-    tw = target[:, :, 2, :, :]
-    th = target[:, :, 3, :, :]
-    tscale = target[:, :, 4, :, :]
-    tobj = target[:, :, 5, :, :]
-    tcls = fluid.layers.transpose(target[:, :, 6:, :, :], perm=[0, 1, 3, 4, 2])
-    tcls.stop_gradient = True
-    return (tx, ty, tw, th, tscale, tobj, tcls)
-
-
-def _calc_obj_loss(output, obj, tobj, gt_box, batch_size, anchors, num_classes,
-                   downsample, ignore_thresh, scale_x_y):
-    # A prediction bbox overlap any gt_bbox over ignore_thresh,
-    # objectness loss will be ignored, process as follows:
-    # 1. get pred bbox, which is same with YOLOv3 infer mode, use yolo_box here
-    # NOTE: img_size is set as 1.0 to get noramlized pred bbox
-    bbox, prob = fluid.layers.yolo_box(
-        x=output,
-        img_size=fluid.layers.ones(
-            shape=[batch_size, 2], dtype="int32"),
-        anchors=anchors,
-        class_num=num_classes,
-        conf_thresh=0.,
-        downsample_ratio=downsample,
-        clip_bbox=False,
-        scale_x_y=scale_x_y)
-    # 2. split pred bbox and gt bbox by sample, calculate IoU between pred bbox
-    #    and gt bbox in each sample
-    if batch_size > 1:
-        preds = fluid.layers.split(bbox, batch_size, dim=0)
-        gts = fluid.layers.split(gt_box, batch_size, dim=0)
-    else:
-        preds = [bbox]
-        gts = [gt_box]
-        probs = [prob]
-    ious = []
-    for pred, gt in zip(preds, gts):
-
-        def box_xywh2xyxy(box):
-            x = box[:, 0]
-            y = box[:, 1]
-            w = box[:, 2]
-            h = box[:, 3]
-            return fluid.layers.stack(
-                [
-                    x - w / 2.,
-                    y - h / 2.,
-                    x + w / 2.,
-                    y + h / 2.,
-                ], axis=1)
-
-        pred = fluid.layers.squeeze(pred, axes=[0])
-        gt = box_xywh2xyxy(fluid.layers.squeeze(gt, axes=[0]))
-        ious.append(fluid.layers.iou_similarity(pred, gt))
-    iou = fluid.layers.stack(ious, axis=0)
-    # 3. Get iou_mask by IoU between gt bbox and prediction bbox,
-    #    Get obj_mask by tobj(holds gt_score), calculate objectness loss
-    max_iou = fluid.layers.reduce_max(iou, dim=-1)
-    iou_mask = fluid.layers.cast(max_iou <= ignore_thresh, dtype="float32")
-    output_shape = fluid.layers.shape(output)
-    an_num = len(anchors) // 2
-    iou_mask = fluid.layers.reshape(iou_mask, (-1, an_num, output_shape[2],
-                                               output_shape[3]))
-    iou_mask.stop_gradient = True
-    # NOTE: tobj holds gt_score, obj_mask holds object existence mask
-    obj_mask = fluid.layers.cast(tobj > 0., dtype="float32")
-    obj_mask.stop_gradient = True
-    # For positive objectness grids, objectness loss should be calculated
-    # For negative objectness grids, objectness loss is calculated only iou_mask == 1.0
-    loss_obj = fluid.layers.sigmoid_cross_entropy_with_logits(obj, obj_mask)
-    loss_obj_pos = fluid.layers.reduce_sum(loss_obj * tobj, dim=[1, 2, 3])
-    loss_obj_neg = fluid.layers.reduce_sum(
-        loss_obj * (1.0 - obj_mask) * iou_mask, dim=[1, 2, 3])
-    return loss_obj_pos, loss_obj_neg
-
-
-def fine_grained_loss(output,
-                      target,
-                      gt_box,
-                      batch_size,
-                      num_classes,
-                      anchors,
-                      ignore_thresh,
-                      downsample,
-                      scale_x_y=1.,
-                      eps=1e-10):
-    an_num = len(anchors) // 2
-    x, y, w, h, obj, cls = _split_output(output, an_num, num_classes)
-    tx, ty, tw, th, tscale, tobj, tcls = _split_target(target)
-
-    tscale_tobj = tscale * tobj
-
-    scale_x_y = scale_x_y
-
-    if (abs(scale_x_y - 1.0) < eps):
-        loss_x = fluid.layers.sigmoid_cross_entropy_with_logits(
-            x, tx) * tscale_tobj
-        loss_x = fluid.layers.reduce_sum(loss_x, dim=[1, 2, 3])
-        loss_y = fluid.layers.sigmoid_cross_entropy_with_logits(
-            y, ty) * tscale_tobj
-        loss_y = fluid.layers.reduce_sum(loss_y, dim=[1, 2, 3])
-    else:
-        dx = scale_x_y * fluid.layers.sigmoid(x) - 0.5 * (scale_x_y - 1.0)
-        dy = scale_x_y * fluid.layers.sigmoid(y) - 0.5 * (scale_x_y - 1.0)
-        loss_x = fluid.layers.abs(dx - tx) * tscale_tobj
-        loss_x = fluid.layers.reduce_sum(loss_x, dim=[1, 2, 3])
-        loss_y = fluid.layers.abs(dy - ty) * tscale_tobj
-        loss_y = fluid.layers.reduce_sum(loss_y, dim=[1, 2, 3])
-
-    # NOTE: we refined loss function of (w, h) as L1Loss
-    loss_w = fluid.layers.abs(w - tw) * tscale_tobj
-    loss_w = fluid.layers.reduce_sum(loss_w, dim=[1, 2, 3])
-    loss_h = fluid.layers.abs(h - th) * tscale_tobj
-    loss_h = fluid.layers.reduce_sum(loss_h, dim=[1, 2, 3])
-
-    loss_obj_pos, loss_obj_neg = _calc_obj_loss(
-        output, obj, tobj, gt_box, batch_size, anchors, num_classes,
-        downsample, ignore_thresh, scale_x_y)
-
-    loss_cls = fluid.layers.sigmoid_cross_entropy_with_logits(cls, tcls)
-    loss_cls = fluid.layers.elementwise_mul(loss_cls, tobj, axis=0)
-    loss_cls = fluid.layers.reduce_sum(loss_cls, dim=[1, 2, 3, 4])
-
-    loss_xys = fluid.layers.reduce_mean(loss_x + loss_y)
-    loss_whs = fluid.layers.reduce_mean(loss_w + loss_h)
-    loss_objs = fluid.layers.reduce_mean(loss_obj_pos + loss_obj_neg)
-    loss_clss = fluid.layers.reduce_mean(loss_cls)
-
-    losses_all = {
-        "loss_xy": fluid.layers.sum(loss_xys),
-        "loss_wh": fluid.layers.sum(loss_whs),
-        "loss_loc": fluid.layers.sum(loss_xys) + fluid.layers.sum(loss_whs),
-        "loss_obj": fluid.layers.sum(loss_objs),
-        "loss_cls": fluid.layers.sum(loss_clss),
-    }
-    return losses_all, x, y, tx, ty
-
-
-def gt2yolotarget(gt_bbox, gt_class, gt_score, anchors, mask, num_classes,
-                  size, stride):
-    grid_h, grid_w = size
-    h, w = grid_h * stride, grid_w * stride
-    an_hw = np.array(anchors) / np.array([[w, h]])
-    target = np.zeros(
-        (len(mask), 6 + num_classes, grid_h, grid_w), dtype=np.float32)
-    for b in range(gt_bbox.shape[0]):
-        gx, gy, gw, gh = gt_bbox[b, :]
-        cls = gt_class[b]
-        score = gt_score[b]
-        if gw <= 0. or gh <= 0. or score <= 0.:
-            continue
-
-        # find best match anchor index
-        best_iou = 0.
-        best_idx = -1
-        for an_idx in range(an_hw.shape[0]):
-            iou = jaccard_overlap(
-                [0., 0., gw, gh],
-                [0., 0., an_hw[an_idx, 0], an_hw[an_idx, 1]])
-            if iou > best_iou:
-                best_iou = iou
-                best_idx = an_idx
-
-        gi = int(gx * grid_w)
-        gj = int(gy * grid_h)
-
-        # gtbox should be regresed in this layes if best match
-        # anchor index in anchor mask of this layer
-        if best_idx in mask:
-            best_n = mask.index(best_idx)
-
-            # x, y, w, h, scale
-            target[best_n, 0, gj, gi] = gx * grid_w - gi
-            target[best_n, 1, gj, gi] = gy * grid_h - gj
-            target[best_n, 2, gj, gi] = np.log(gw * w / anchors[best_idx][0])
-            target[best_n, 3, gj, gi] = np.log(gh * h / anchors[best_idx][1])
-            target[best_n, 4, gj, gi] = 2.0 - gw * gh
-
-            # objectness record gt_score
-            # if target[best_n, 5, gj, gi] > 0:
-            #     print('find 1 duplicate')
-            target[best_n, 5, gj, gi] = score
-
-            # classification
-            target[best_n, 6 + cls, gj, gi] = 1.
-
-    return target
-
-
-class TestYolov3LossOp(unittest.TestCase):
-    def setUp(self):
-        self.initTestCase()
-        x = np.random.uniform(0, 1, self.x_shape).astype('float64')
-        gtbox = np.random.random(size=self.gtbox_shape).astype('float64')
-        gtlabel = np.random.randint(0, self.class_num, self.gtbox_shape[:2])
-        gtmask = np.random.randint(0, 2, self.gtbox_shape[:2])
-        gtbox = gtbox * gtmask[:, :, np.newaxis]
-        gtlabel = gtlabel * gtmask
-
-        gtscore = np.ones(self.gtbox_shape[:2]).astype('float64')
-        if self.gtscore:
-            gtscore = np.random.random(self.gtbox_shape[:2]).astype('float64')
-
-        target = []
-        for box, label, score in zip(gtbox, gtlabel, gtscore):
-            target.append(
-                gt2yolotarget(box, label, score, self.anchors,
-                              self.anchor_mask, self.class_num, (
-                                  self.h, self.w), self.downsample_ratio))
-
-        self.target = np.array(target).astype('float64')
-
-        self.mask_anchors = []
-        for i in self.anchor_mask:
-            self.mask_anchors.extend(self.anchors[i])
-        self.x = x
-        self.gtbox = gtbox
-        self.gtlabel = gtlabel
-        self.gtscore = gtscore
-
-    def initTestCase(self):
-        self.b = 8
-        self.h = 19
-        self.w = 19
-        self.anchors = [[10, 13], [16, 30], [33, 23], [30, 61], [62, 45],
-                        [59, 119], [116, 90], [156, 198], [373, 326]]
-        self.anchor_mask = [6, 7, 8]
-        self.na = len(self.anchor_mask)
-        self.class_num = 80
-        self.ignore_thresh = 0.7
-        self.downsample_ratio = 32
-        self.x_shape = (self.b, len(self.anchor_mask) * (5 + self.class_num),
-                        self.h, self.w)
-        self.gtbox_shape = (self.b, 40, 4)
-        self.gtscore = True
-        self.use_label_smooth = False
-        self.scale_x_y = 1.
-
-    def test_loss(self):
-        x, gtbox, gtlabel, gtscore, target = self.x, self.gtbox, self.gtlabel, self.gtscore, self.target
-        yolo_loss = YOLOv3Loss(
-            ignore_thresh=self.ignore_thresh,
-            label_smooth=self.use_label_smooth,
-            num_classes=self.class_num,
-            downsample=self.downsample_ratio,
-            scale_x_y=self.scale_x_y)
-        x = paddle.to_tensor(x.astype(np.float32))
-        gtbox = paddle.to_tensor(gtbox.astype(np.float32))
-        gtlabel = paddle.to_tensor(gtlabel.astype(np.float32))
-        gtscore = paddle.to_tensor(gtscore.astype(np.float32))
-        t = paddle.to_tensor(target.astype(np.float32))
-        anchor = [self.anchors[i] for i in self.anchor_mask]
-        (yolo_loss1, px, py, tx, ty) = fine_grained_loss(
-            output=x,
-            target=t,
-            gt_box=gtbox,
-            batch_size=self.b,
-            num_classes=self.class_num,
-            anchors=self.mask_anchors,
-            ignore_thresh=self.ignore_thresh,
-            downsample=self.downsample_ratio,
-            scale_x_y=self.scale_x_y)
-        yolo_loss2 = yolo_loss.yolov3_loss(
-            x, t, gtbox, anchor, self.downsample_ratio, self.scale_x_y)
-        for k in yolo_loss2:
-            self.assertAlmostEqual(
-                yolo_loss1[k].numpy()[0],
-                yolo_loss2[k].numpy()[0],
-                delta=1e-2,
-                msg=k)
-
-
-class TestYolov3LossNoGTScore(TestYolov3LossOp):
-    def initTestCase(self):
-        self.b = 1
-        self.h = 76
-        self.w = 76
-        self.anchors = [[10, 13], [16, 30], [33, 23], [30, 61], [62, 45],
-                        [59, 119], [116, 90], [156, 198], [373, 326]]
-        self.anchor_mask = [0, 1, 2]
-        self.na = len(self.anchor_mask)
-        self.class_num = 80
-        self.ignore_thresh = 0.7
-        self.downsample_ratio = 8
-        self.x_shape = (self.b, len(self.anchor_mask) * (5 + self.class_num),
-                        self.h, self.w)
-        self.gtbox_shape = (self.b, 40, 4)
-        self.gtscore = False
-        self.use_label_smooth = False
-        self.scale_x_y = 1.
-
-
-class TestYolov3LossWithScaleXY(TestYolov3LossOp):
-    def initTestCase(self):
-        self.b = 5
-        self.h = 38
-        self.w = 38
-        self.anchors = [[10, 13], [16, 30], [33, 23], [30, 61], [62, 45],
-                        [59, 119], [116, 90], [156, 198], [373, 326]]
-        self.anchor_mask = [3, 4, 5]
-        self.na = len(self.anchor_mask)
-        self.class_num = 80
-        self.ignore_thresh = 0.7
-        self.downsample_ratio = 16
-        self.x_shape = (self.b, len(self.anchor_mask) * (5 + self.class_num),
-                        self.h, self.w)
-        self.gtbox_shape = (self.b, 40, 4)
-        self.gtscore = True
-        self.use_label_smooth = False
-        self.scale_x_y = 1.2
-
-
-if __name__ == "__main__":
-    unittest.main()