From 11b38b12d64bfdcc58de30d357ef51038b85d0aa Mon Sep 17 00:00:00 2001 From: liukuikun <24622904+Harold-lkk@users.noreply.github.com> Date: Sat, 5 Mar 2022 15:02:54 +0800 Subject: [PATCH] [Fix] fix random may generate same value (#85) --- mmengine/data/base_data_element.py | 71 ++++++++--------- mmengine/data/base_data_sample.py | 119 +++++++++++++--------------- tests/test_data/test_data_sample.py | 8 ++ 3 files changed, 99 insertions(+), 99 deletions(-) diff --git a/mmengine/data/base_data_element.py b/mmengine/data/base_data_element.py index 5ab96f6f..ac5870bc 100644 --- a/mmengine/data/base_data_element.py +++ b/mmengine/data/base_data_element.py @@ -25,27 +25,26 @@ class BaseDataElement: types of ground truth labels or predictions. They are used as interfaces between different commopenets. - The attributes in ``BaseDataElement`` are divided into two parts, the ``metainfo`` and the ``data`` respectively. - - ``metainfo``: Usually contains the - information about the image such as filename, - image_shape, pad_shape, etc. The attributes can be accessed or - modified by dict-like or object-like operations, such as - ``.``(for data access and modification) , ``in``, ``del``, - ``pop(str)``, ``get(str)``, ``metainfo_keys()``, - ``metainfo_values()``, ``metainfo_items()``, ``set_metainfo()``(for - set or change key-value pairs in metainfo). - - - ``data``: Annotations or model predictions are - stored. The attributes can be accessed or modified by - dict-like or object-like operations, such as - ``.`` , ``in``, ``del``, ``pop(str)`` ``get(str)``, ``data_keys()``, - ``data_values()``, ``data_items()``. Users can also apply tensor-like - methods to all obj:``torch.Tensor`` in the ``data_fileds``, - such as ``.cuda()``, ``.cpu()``, ``.numpy()``, , ``.to()`` - ``to_tensor()``, ``.detach()``, ``.numpy()`` + - ``metainfo``: Usually contains the + information about the image such as filename, + image_shape, pad_shape, etc. The attributes can be accessed or + modified by dict-like or object-like operations, such as + ``.``(for data access and modification) , ``in``, ``del``, + ``pop(str)``, ``get(str)``, ``metainfo_keys()``, + ``metainfo_values()``, ``metainfo_items()``, ``set_metainfo()``(for + set or change key-value pairs in metainfo). + + - ``data``: Annotations or model predictions are + stored. The attributes can be accessed or modified by + dict-like or object-like operations, such as + ``.`` , ``in``, ``del``, ``pop(str)`` ``get(str)``, ``data_keys()``, + ``data_values()``, ``data_items()``. Users can also apply tensor-like + methods to all obj:``torch.Tensor`` in the ``data_fileds``, + such as ``.cuda()``, ``.cpu()``, ``.numpy()``, , ``.to()`` + ``to_tensor()``, ``.detach()``, ``.numpy()`` Args: meta_info (dict, optional): A dict contains the meta information @@ -57,24 +56,24 @@ class BaseDataElement: Examples: >>> from mmengine.data import BaseDataElement >>> gt_instances = BaseDataElement() - >>> bboxes = torch.rand((5, 4)) >>> scores = torch.rand((5,)) >>> img_id = 0 >>> img_shape = (800, 1333) >>> gt_instances = BaseDataElement( - metainfo=dict(img_id=img_id, img_shape=img_shape), - data=dict(bboxes=bboxes, scores=scores)) + ... metainfo=dict(img_id=img_id, img_shape=img_shape), + ... data=dict(bboxes=bboxes, scores=scores)) >>> gt_instances = BaseDataElement(dict(img_id=img_id, - img_shape=(H, W))) - # new + ... img_shape=(H, W))) + + >>> # new >>> gt_instances1 = gt_instance.new( - metainfo=dict(img_id=1, img_shape=(640, 640)), - data=dict(bboxes=torch.rand((5, 4)), - scores=torch.rand((5,)))) + ... metainfo=dict(img_id=1, img_shape=(640, 640)), + ... data=dict(bboxes=torch.rand((5, 4)), + ... scores=torch.rand((5,)))) >>> gt_instances2 = gt_instances1.new() - # add and process property + >>> # add and process property >>> gt_instances = BaseDataElement() >>> gt_instances.set_metainfo(dict(img_id=9, img_shape=(100, 100)) >>> assert 'img_shape' in gt_instances.metainfo_keys() @@ -82,14 +81,12 @@ class BaseDataElement: >>> assert 'img_shape' not in gt_instances.data_keys() >>> assert 'img_shape' in gt_instances.keys() >>> print(gt_instances.img_shape) - >>> gt_instances.scores = torch.rand((5,)) >>> assert 'scores' in gt_instances.data_keys() >>> assert 'scores' in gt_instances >>> assert 'scores' in gt_instances.keys() >>> assert 'scores' not in gt_instances.metainfo_keys() >>> print(gt_instances.scores) - >>> gt_instances.bboxes = torch.rand((5, 4)) >>> assert 'bboxes' in gt_instances.data_keys() >>> assert 'bboxes' in gt_instances @@ -97,14 +94,14 @@ class BaseDataElement: >>> assert 'bboxes' not in gt_instances.metainfo_keys() >>> print(gt_instances.bboxes) - # delete and change property + >>> # delete and change property >>> gt_instances = BaseDataElement( - metainfo=dict(img_id=0, img_shape=(640, 640)), - data=dict(bboxes=torch.rand((6, 4)), scores=torch.rand((6,)))) + ... metainfo=dict(img_id=0, img_shape=(640, 640)), + ... data=dict(bboxes=torch.rand((6, 4)), scores=torch.rand((6,)))) >>> gt_instances.img_shape = (1280, 1280) >>> gt_instances.img_shape # (1280, 1280) >>> gt_instances.bboxes = gt_instances.bboxes * 2 - >>> gt_instances.get('img_shape', None) # (640, 640) + >>> gt_instances.get('img_shape', None) # (640, 640) >>> gt_instances.get('bboxes', None) # 6x4 tensor >>> del gt_instances.img_shape >>> del gt_instances.bboxes @@ -113,18 +110,18 @@ class BaseDataElement: >>> gt_instances.pop('img_shape', None) # None >>> gt_instances.pop('bboxes', None) # None - # Tensor-like + >>> # Tensor-like >>> cuda_instances = gt_instances.cuda() >>> cuda_instances = gt_instancess.to('cuda:0') >>> cpu_instances = cuda_instances.cpu() >>> cpu_instances = cuda_instances.to('cpu') >>> fp16_instances = cuda_instances.to( - device=None, dtype=torch.float16, non_blocking=False, copy=False, - memory_format=torch.preserve_format) + ... device=None, dtype=torch.float16, non_blocking=False, copy=False, + ... memory_format=torch.preserve_format) >>> cpu_instances = cuda_instances.detach() >>> np_instances = cpu_instances.numpy() - # print + >>> # print >>> img_meta = dict(img_shape=(800, 1196, 3), pad_shape=(800, 1216, 3)) >>> instance_data = BaseDataElement(metainfo=img_meta) >>> instance_data.det_labels = torch.LongTensor([0, 1, 2, 3]) diff --git a/mmengine/data/base_data_sample.py b/mmengine/data/base_data_sample.py index 4c6a2607..dd6fafd1 100644 --- a/mmengine/data/base_data_sample.py +++ b/mmengine/data/base_data_sample.py @@ -54,55 +54,52 @@ class BaseDataSample: Examples: >>> from mmengine.data import BaseDataElement, BaseDataSample >>> gt_instances = BaseDataSample() - >>> bboxes = torch.rand((5, 4)) >>> scores = torch.rand((5,)) >>> img_id = 0 >>> img_shape = (800, 1333) >>> gt_instances = BaseDataElement( - metainfo=dict(img_id=img_id, img_shape=img_shape), - data=dict(bboxes=bboxes, scores=scores)) + ... metainfo=dict(img_id=img_id, img_shape=img_shape), + ... data=dict(bboxes=bboxes, scores=scores)) >>> data = dict(gt_instances=gt_instances) >>> sample = BaseDataSample( - metainfo=dict(img_id=img_id, img_shape=img_shape), - data=data) + ... metainfo=dict(img_id=img_id, img_shape=img_shape), + ... data=data) >>> sample = BaseDataSample(dict(img_id=img_id, - img_shape=(H, W))) - # new + ... img_shape=(H, W))) + + >>> # new >>> data1 = dict(bboxes=torch.rand((5, 4)), scores=torch.rand((5,))) >>> metainfo1 = dict(img_id=1, img_shape=(640, 640)), >>> gt_instances1 = BaseDataElement( - metainfo=metainfo1, - data=data1) + ... metainfo=metainfo1, + ... data=data1) >>> sample1 = sample.new( - metainfo=metainfo1 - data=dict(gt_instances1=gt_instances1)), - + ... metainfo=metainfo1 + ... data=dict(gt_instances1=gt_instances1)), >>> gt_instances2 = gt_instances1.new() - # property add and access + >>> # property add and access >>> sample = BaseDataSample() >>> gt_instances = BaseDataElement( - metainfo=dict(img_id=9, img_shape=(100, 100)), - data=dict(bboxes=torch.rand((5, 4)), scores=torch.rand((5,))) + ... metainfo=dict(img_id=9, img_shape=(100, 100)), + ... data=dict(bboxes=torch.rand((5, 4)), scores=torch.rand((5,))) >>> sample.set_metainfo(dict(img_id=9, img_shape=(100, 100)) >>> assert 'img_shape' in sample.metainfo_keys() >>> assert 'img_shape' in sample >>> assert 'img_shape' not in sample.data_keys() >>> assert 'img_shape' in sample.keys() >>> print(sample.img_shape) - >>> gt_instances.gt_instances = gt_instances >>> assert 'gt_instances' in sample.data_keys() >>> assert 'gt_instances' in sample >>> assert 'gt_instances' in sample.keys() >>> assert 'gt_instances' not in sample.metainfo_keys() >>> print(sample.gt_instances) - >>> pred_instances = BaseDataElement( - metainfo=dict(img_id=9, img_shape=(100, 100)), - data=dict(bboxes=torch.rand((5, 4)), scores=torch.rand((5,)) + ... metainfo=dict(img_id=9, img_shape=(100, 100)), + ... data=dict(bboxes=torch.rand((5, 4)), scores=torch.rand((5,)) >>> sample.pred_instances = pred_instances >>> assert 'pred_instances' in sample.data_keys() >>> assert 'pred_instances' in sample @@ -110,17 +107,17 @@ class BaseDataSample: >>> assert 'pred_instances' not in sample.metainfo_keys() >>> print(sample.pred_instances) - # property delete and change + >>> # property delete and change >>> metainfo=dict(img_id=0, img_shape=(640, 640) >>> gt_instances = BaseDataElement( - metainfo=metainfo), - data=dict(bboxes=torch.rand((6, 4)), scores=torch.rand((6,)))) + ... metainfo=metainfo), + ... data=dict(bboxes=torch.rand((6, 4)), scores=torch.rand((6,)))) >>> sample = BaseDataSample(metainfo=metainfo, - data=dict(gt_instances=gt_instances)) + ... data=dict(gt_instances=gt_instances)) >>> sample.img_shape = (1280, 1280) >>> sample.img_shape # (1280, 1280) >>> sample.gt_instances = gt_instances - >>> sample.get('img_shape', None) # (640, 640) + >>> sample.get('img_shape', None) # (640, 640) >>> sample.get('gt_instances', None) >>> del sample.img_shape >>> del sample.gt_instances @@ -129,23 +126,22 @@ class BaseDataSample: >>> sample.pop('img_shape', None) # None >>> sample.pop('gt_instances', None) # None - # Tensor-like + >>> # Tensor-like >>> cuda_sample = gt_instasamplences.cuda() >>> cuda_sample = gt_sample.to('cuda:0') >>> cpu_sample = cuda_sample.cpu() >>> cpu_sample = cuda_sample.to('cpu') >>> fp16_sample = cuda_sample.to( - device=None, dtype=torch.float16, non_blocking=False, copy=False, - memory_format=torch.preserve_format) + ... device=None, dtype=torch.float16, non_blocking=False, copy=False, + ... memory_format=torch.preserve_format) >>> cpu_sample = cuda_sample.detach() >>> np_sample = cpu_sample.numpy() - # print + >>> # print >>> metainfo = dict(img_shape=(800, 1196, 3)) >>> gt_instances = BaseDataElement( - metainfo=metainfo, - data=dict(det_labels=torch.LongTensor([0, 1, 2, 3]))) - + ... metainfo=metainfo, + ... data=dict(det_labels=torch.LongTensor([0, 1, 2, 3]))) >>> data = dict(gt_instances=gt_instances) >>> sample = BaseDataSample(metainfo=metainfo, data=data) >>> print(sample) @@ -161,37 +157,36 @@ class BaseDataSample: ) at 0x7f9705daecd0>' ) at 0x7f981e41c550>' - # inheritance + >>> # inheritance >>> class DetDataSample(BaseDataSample): - >>> proposals = property( - >>> fget=partial(BaseDataSample.get_field, name='_proposals'), - >>> fset=partial( - >>> BaseDataSample.set_field, - >>> name='_proposals', - >>> dtype=BaseDataElement), - >>> fdel=partial(BaseDataSample.del_field, name='_proposals'), - >>> doc='Region proposals of an image') - >>> gt_instances = property( - >>> fget=partial(BaseDataSample.get_field, - name='_gt_instances'), - >>> fset=partial( - >>> BaseDataSample.set_field, - >>> name='_gt_instances', - >>> dtype=BaseDataElement), - >>> fdel=partial(BaseDataSample.del_field, - name='_gt_instances'), - >>> doc='Ground truth instances of an image') - >>> pred_instances = property( - >>> fget=partial( - >>> BaseDataSample.get_field, name='_pred_instances'), - >>> fset=partial( - >>> BaseDataSample.set_field, - >>> name='_pred_instances', - >>> dtype=BaseDataElement), - >>> fdel=partial( - >>> BaseDataSample.del_field, name='_pred_instances'), - >>> doc='Predicted instances of an image') - + ... proposals = property( + ... fget=partial(BaseDataSample.get_field, name='_proposals'), + ... fset=partial( + ... BaseDataSample.set_field, + ... name='_proposals', + ... dtype=BaseDataElement), + ... fdel=partial(BaseDataSample.del_field, name='_proposals'), + ... doc='Region proposals of an image') + ... gt_instances = property( + ... fget=partial(BaseDataSample.get_field, + ... name='_gt_instances'), + ... fset=partial( + ... BaseDataSample.set_field, + ... name='_gt_instances', + ... dtype=BaseDataElement), + ... fdel=partial(BaseDataSample.del_field, + ... name='_gt_instances'), + ... doc='Ground truth instances of an image') + ... pred_instances = property( + ... fget=partial( + ... BaseDataSample.get_field, name='_pred_instances'), + ... fset=partial( + ... BaseDataSample.set_field, + ... name='_pred_instances', + ... dtype=BaseDataElement), + ... fdel=partial( + ... BaseDataSample.del_field, name='_pred_instances'), + ... doc='Predicted instances of an image') >>> det_sample = DetDataSample() >>> proposals = BaseDataElement(data=dict(bboxes=torch.rand((5, 4)))) >>> det_sample.proposals = proposals @@ -200,7 +195,7 @@ class BaseDataSample: >>> del det_sample.proposals >>> assert 'proposals' not in det_sample >>> with self.assertRaises(AssertionError): - det_sample.proposals = torch.rand((5, 4)) + ... det_sample.proposals = torch.rand((5, 4)) """ def __init__(self, diff --git a/tests/test_data/test_data_sample.py b/tests/test_data/test_data_sample.py index cc940073..e03508fb 100644 --- a/tests/test_data/test_data_sample.py +++ b/tests/test_data/test_data_sample.py @@ -185,6 +185,14 @@ class TestBaseDataSample(TestCase): instances = BaseDataSample(metainfo, data) new_metainfo, new_data = self.setup_data() + # avoid generating same metainfo + while True: + if new_metainfo['img_id'] == metainfo['img_id'] or new_metainfo[ + 'img_shape'] == metainfo['img_shape']: + new_metainfo, new_data = self.setup_data() + else: + break + instances.gt_instances = new_data['gt_instances'] instances.pred_instances = new_data['pred_instances'] -- GitLab