Bobholamovic vor 2 Jahren
Ursprung
Commit
8ba124d82b

+ 1 - 1
paddlers/custom_models/seg/farseg.py

@@ -32,7 +32,7 @@ class FPN(nn.Layer):
     """
     Module that adds FPN on top of a list of feature maps.
     The feature maps are currently supposed to be in increasing depth
-    order, and must be consecutive
+        order, and must be consecutive
     """
 
     def __init__(self,

+ 1 - 1
paddlers/tasks/slim/prune.py

@@ -41,7 +41,7 @@ def _pruner_template_input(sample, model_type):
 
 
 def sensitive_prune(pruner, pruned_flops, skip_vars=[], align=None):
-    # skip depthwise convolutions
+    # Skip depthwise convolutions
     for layer in pruner.model.sublayers():
         if isinstance(layer, paddle.nn.layer.conv.Conv2D) and layer._groups > 1:
             for param in layer.parameters(include_sublayers=False):

+ 41 - 38
paddlers/tasks/utils/det_metrics/coco_utils.py

@@ -35,6 +35,7 @@ def get_infer_results(outs, catid, bias=0):
     For example, bbox result is a list and each element contains
     image_id, category_id, bbox and score.
     """
+
     if outs is None or len(outs) == 0:
         raise ValueError(
             'The number of valid detection result if zero. Please use reasonable model and check input data.'
@@ -78,6 +79,7 @@ def cocoapi_eval(anns,
         max_dets (tuple): COCO evaluation maxDets.
         classwise (bool): Whether per-category AP and draw P-R Curve or not.
     """
+
     assert coco_gt is not None or anno_file is not None
     from pycocotools.coco import COCO
     from pycocotools.cocoeval import COCOeval
@@ -220,19 +222,19 @@ def loadRes(coco_obj, anns):
 
 
 def makeplot(rs, ps, outDir, class_name, iou_type):
-    """针对某个特定类别,绘制不同评估要求下的准确率和召回率。
-       绘制结果说明参考COCODataset官网给出分析工具说明https://cocodataset.org/#detection-eval。
-
-       Refer to https://github.com/open-mmlab/mmdetection/blob/master/tools/analysis_tools/coco_error_analysis.py#L13
+    """
+    针对某个特定类别,绘制不同评估要求下的准确率和召回率。
+    绘制结果说明参考COCODataset官网给出分析工具说明https://cocodataset.org/#detection-eval。
 
-       Args:
-           rs (np.array): 在不同置信度阈值下计算得到的召回率。
-           ps (np.array): 在不同置信度阈值下计算得到的准确率。ps与rs相同位置下的数值为同一个置信度阈值
-               计算得到的准确率与召回率。
-           outDir (str): 图表保存的路径。
-           class_name (str): 类别名。
-           iou_type (str): iou计算方式,若为检测框,则设置为'bbox',若为像素级分割结果,则设置为'segm'。
+    Refer to https://github.com/open-mmlab/mmdetection/blob/master/tools/analysis_tools/coco_error_analysis.py#L13
 
+    Args:
+        rs (np.array): 在不同置信度阈值下计算得到的召回率。
+        ps (np.array): 在不同置信度阈值下计算得到的准确率。ps与rs相同位置下的数值为同一个置信度阈值
+            计算得到的准确率与召回率。
+        outDir (str): 图表保存的路径。
+        class_name (str): 类别名。
+        iou_type (str): iou计算方式,若为检测框,则设置为'bbox',若为像素级分割结果,则设置为'segm'。
     """
 
     import matplotlib.pyplot as plt
@@ -276,21 +278,22 @@ def makeplot(rs, ps, outDir, class_name, iou_type):
 
 
 def analyze_individual_category(k, cocoDt, cocoGt, catId, iou_type, areas=None):
-    """针对某个特定类别,分析忽略亚类混淆和类别混淆时的准确率。
+    """
+    针对某个特定类别,分析忽略亚类混淆和类别混淆时的准确率。
 
-       Refer to https://github.com/open-mmlab/mmdetection/blob/master/tools/analysis_tools/coco_error_analysis.py#L174
+    Refer to https://github.com/open-mmlab/mmdetection/blob/master/tools/analysis_tools/coco_error_analysis.py#L174
 
-       Args:
-           k (int): 待分析类别的序号。
-           cocoDt (pycocotols.coco.COCO): 按COCO类存放的预测结果。
-           cocoGt (pycocotols.coco.COCO): 按COCO类存放的真值。
-           catId (int): 待分析类别在数据集中的类别id。
-           iou_type (str): iou计算方式,若为检测框,则设置为'bbox',若为像素级分割结果,则设置为'segm'。
+    Args:
+        k (int): 待分析类别的序号。
+        cocoDt (pycocotols.coco.COCO): 按COCO类存放的预测结果。
+        cocoGt (pycocotols.coco.COCO): 按COCO类存放的真值。
+        catId (int): 待分析类别在数据集中的类别id。
+        iou_type (str): iou计算方式,若为检测框,则设置为'bbox',若为像素级分割结果,则设置为'segm'。
 
-       Returns:
-           int:
-           dict: 有关键字'ps_supercategory'和'ps_allcategory'。关键字'ps_supercategory'的键值是忽略亚类间
-               混淆时的准确率,关键字'ps_allcategory'的键值是忽略类别间混淆时的准确率。
+    Returns:
+        int:
+        dict: 有关键字'ps_supercategory'和'ps_allcategory'。关键字'ps_supercategory'的键值是忽略亚类间
+            混淆时的准确率,关键字'ps_allcategory'的键值是忽略类别间混淆时的准确率。
 
     """
 
@@ -362,23 +365,23 @@ def coco_error_analysis(eval_details_file=None,
                         pred_bbox=None,
                         pred_mask=None,
                         save_dir='./output'):
-    """逐个分析模型预测错误的原因,并将分析结果以图表的形式展示。
-       分析结果说明参考COCODataset官网给出分析工具说明https://cocodataset.org/#detection-eval。
-
-       Refer to https://github.com/open-mmlab/mmdetection/blob/master/tools/analysis_tools/coco_error_analysis.py
-
-       Args:
-           eval_details_file (str):  模型评估结果的保存路径,包含真值信息和预测结果。
-           gt (list): 数据集的真值信息。默认值为None。
-           pred_bbox (list): 模型在数据集上的预测框。默认值为None。
-           pred_mask (list): 模型在数据集上的预测mask。默认值为None。
-           save_dir (str): 可视化结果保存路径。默认值为'./output'。
+    """
+    逐个分析模型预测错误的原因,并将分析结果以图表的形式展示。
+    分析结果说明参考COCODataset官网给出分析工具说明https://cocodataset.org/#detection-eval。
 
-        Note:
-           eval_details_file的优先级更高,只要eval_details_file不为None,
-           就会从eval_details_file提取真值信息和预测结果做分析。
-           当eval_details_file为None时,则用gt、pred_mask、pred_mask做分析。
+    Refer to https://github.com/open-mmlab/mmdetection/blob/master/tools/analysis_tools/coco_error_analysis.py
 
+    Args:
+        eval_details_file (str):  模型评估结果的保存路径,包含真值信息和预测结果。
+        gt (list): 数据集的真值信息。默认值为None。
+        pred_bbox (list): 模型在数据集上的预测框。默认值为None。
+        pred_mask (list): 模型在数据集上的预测mask。默认值为None。
+        save_dir (str): 可视化结果保存路径。默认值为'./output'。
+
+    Note:
+        eval_details_file的优先级更高,只要eval_details_file不为None,
+        就会从eval_details_file提取真值信息和预测结果做分析。
+        当eval_details_file为None时,则用gt、pred_mask、pred_mask做分析。
     """
 
     import multiprocessing as mp

+ 8 - 3
paddlers/tasks/utils/visualize.py

@@ -25,7 +25,7 @@ from .det_metrics.coco_utils import loadRes
 def visualize_detection(image, result, threshold=0.5, save_dir='./',
                         color=None):
     """
-        Visualize bbox and mask results
+    Visualize bbox and mask results
     """
 
     if isinstance(image, np.ndarray):
@@ -48,6 +48,7 @@ def visualize_segmentation(image, result, weight=0.6, save_dir='./',
                            color=None):
     """
     Convert segment result to color image, and save added image.
+
     Args:
         image: the path of origin image
         result: the predict result of image
@@ -55,6 +56,7 @@ def visualize_segmentation(image, result, weight=0.6, save_dir='./',
         save_dir: the directory for saving visual image
         color: the list of a BGR-mode color for each label.
     """
+
     label_map = result['label_map'].astype("uint8")
     color_map = get_color_map_list(256)
     if color is not None:
@@ -104,13 +106,16 @@ def visualize_segmentation(image, result, weight=0.6, save_dir='./',
 
 
 def get_color_map_list(num_classes):
-    """ Returns the color map for visualizing the segmentation mask,
-        which can support arbitrary number of classes.
+    """ 
+    Returns the color map for visualizing the segmentation mask, which can support arbitrary number of classes.
+
     Args:
         num_classes: Number of classes
+
     Returns:
         The color map
     """
+
     color_map = num_classes * [0, 0, 0]
     for i in range(0, num_classes):
         j = 0

+ 5 - 0
tests/check_coverage.sh

@@ -0,0 +1,5 @@
+#!/usr/bin/bash
+
+coverage run -m unittest discover
+coverage report
+coverage html -d coverage_html

+ 13 - 0
tests/components/__init__.py

@@ -0,0 +1,13 @@
+# Copyright (c) 2022 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.

+ 13 - 0
tests/datasets/__init__.py

@@ -0,0 +1,13 @@
+# Copyright (c) 2022 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.

+ 13 - 0
tests/deploy/__init__.py

@@ -0,0 +1,13 @@
+# Copyright (c) 2022 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.

+ 13 - 0
tests/rs_models/__init__.py

@@ -0,0 +1,13 @@
+# Copyright (c) 2022 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.

+ 3 - 0
tests/run_tests.sh

@@ -0,0 +1,3 @@
+#!/usr/bin/bash
+
+python -m unittest discover -v

+ 13 - 0
tests/tasks/__init__.py

@@ -0,0 +1,13 @@
+# Copyright (c) 2022 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.

+ 13 - 0
tests/test_examples.py

@@ -0,0 +1,13 @@
+# Copyright (c) 2022 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.

+ 13 - 0
tests/test_tutorials.py

@@ -0,0 +1,13 @@
+# Copyright (c) 2022 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.

+ 183 - 0
tests/test_utils.py

@@ -0,0 +1,183 @@
+# Copyright (c) 2022 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.
+
+# Based on https://github.com/PaddlePaddle/PaddleNLP/blob/develop/tests/common_test.py
+
+import unittest
+import warnings
+
+import numpy as np
+import paddle
+
+__all__ = ['CommonTest', 'CpuCommonTest']
+
+
+# Assume all elements has same data type
+def get_container_type(container):
+    container_t = type(container)
+    if container_t in [list, tuple]:
+        if len(container) == 0:
+            return container_t
+        return get_container_type(container[0])
+    return container_t
+
+
+class _CommonTestNamespace:
+    # Wrap the subclasses of unittest.TestCase that are expected to be inherited from.
+    class CommonTest(unittest.TestCase):
+        CATCH_WARNINGS = False
+
+        def __init__(self, methodName='runTest'):
+            super(CommonTest, self).__init__(methodName=methodName)
+            self.config = {}
+            self.places = ['cpu']
+            if paddle.is_compiled_with_cuda():
+                self.places.append('gpu')
+
+        @classmethod
+        def setUpClass(cls):
+            '''
+            Set the decorators for all test function
+            '''
+            for key, value in cls.__dict__.items():
+                if key.startswith('test'):
+                    decorator_func_list = ["_test_places"]
+                    if cls.CATCH_WARNINGS:
+                        decorator_func_list.append("_catch_warnings")
+                    for decorator_func in decorator_func_list:
+                        decorator_func = getattr(CommonTest, decorator_func)
+                        value = decorator_func(value)
+                    setattr(cls, key, value)
+
+        def _catch_warnings(func):
+            '''
+            Catch the warnings and treat them as errors for each test.
+            '''
+
+            def wrapper(self, *args, **kwargs):
+                with warnings.catch_warnings(record=True) as w:
+                    warnings.resetwarnings()
+                    # ignore specified warnings
+                    warning_white_list = [UserWarning]
+                    for warning in warning_white_list:
+                        warnings.simplefilter("ignore", warning)
+                    func(self, *args, **kwargs)
+                    msg = None if len(w) == 0 else w[0].message
+                    self.assertFalse(len(w) > 0, msg)
+
+            return wrapper
+
+        def _test_places(func):
+            '''
+            Setting the running place for each test.
+            '''
+
+            def wrapper(self, *args, **kwargs):
+                places = self.places
+                for place in places:
+                    paddle.set_device(place)
+                    func(self, *args, **kwargs)
+
+            return wrapper
+
+        def _check_output_impl(self,
+                               result,
+                               expected_result,
+                               rtol,
+                               atol,
+                               equal=True):
+            assertForNormalType = self.assertNotEqual
+            assertForFloat = self.assertFalse
+            if equal:
+                assertForNormalType = self.assertEqual
+                assertForFloat = self.assertTrue
+
+            result_t = type(result)
+            error_msg = 'Output has diff at place:{}. \nExpect: {} \nBut Got: {} in class {}'
+            if result_t in [list, tuple]:
+                result_t = get_container_type(result)
+            if result_t in [
+                    str, int, bool, set, np.bool, np.int32, np.int64, np.str
+            ]:
+                assertForNormalType(
+                    result,
+                    expected_result,
+                    msg=error_msg.format(paddle.get_device(), expected_result,
+                                         result, self.__class__.__name__))
+            elif result_t in [float, np.ndarray, np.float32, np.float64]:
+                assertForFloat(
+                    np.allclose(
+                        result, expected_result, rtol=rtol, atol=atol),
+                    msg=error_msg.format(paddle.get_device(), expected_result,
+                                         result, self.__class__.__name__))
+                if result_t == np.ndarray:
+                    assertForNormalType(
+                        result.shape,
+                        expected_result.shape,
+                        msg=error_msg.format(
+                            paddle.get_device(), expected_result.shape,
+                            result.shape, self.__class__.__name__))
+            else:
+                raise ValueError(
+                    'result type must be str, int, bool, set, np.bool, np.int32, '
+                    'np.int64, np.str, float, np.ndarray, np.float32, np.float64'
+                )
+
+        def check_output_equal(self,
+                               result,
+                               expected_result,
+                               rtol=1.e-5,
+                               atol=1.e-8):
+            '''
+                Check whether result and expected result are equal, including shape. 
+            Args:
+                result: str, int, bool, set, np.ndarray.
+                    The result needs to be checked.
+                expected_result: str, int, bool, set, np.ndarray. The type has to be same as result's.
+                    Use the expected result to check result.
+                rtol: float
+                    relative tolerance, default 1.e-5.
+                atol: float
+                    absolute tolerance, default 1.e-8
+            '''
+            self._check_output_impl(result, expected_result, rtol, atol)
+
+        def check_output_not_equal(self,
+                                   result,
+                                   expected_result,
+                                   rtol=1.e-5,
+                                   atol=1.e-8):
+            '''
+                Check whether result and expected result are not equal, including shape. 
+            Args:
+                result: str, int, bool, set, np.ndarray.
+                    The result needs to be checked.
+                expected_result: str, int, bool, set, np.ndarray. The type has to be same as result's.
+                    Use the expected result to check result.
+                rtol: float
+                    relative tolerance, default 1.e-5.
+                atol: float
+                    absolute tolerance, default 1.e-8
+            '''
+            self._check_output_impl(
+                result, expected_result, rtol, atol, equal=False)
+
+    class CpuCommonTest(CommonTest):
+        def __init__(self, methodName='runTest'):
+            super(CpuCommonTest, self).__init__(methodName=methodName)
+            self.places = ['cpu']
+
+
+CommonTest = _CommonTestNamespace.CommonTest
+CpuCommonTest = _CommonTestNamespace.CpuCommonTest

+ 13 - 0
tests/tools/__init__.py

@@ -0,0 +1,13 @@
+# Copyright (c) 2022 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.

+ 13 - 0
tests/transforms/__init__.py

@@ -0,0 +1,13 @@
+# Copyright (c) 2022 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.