From 7aa143d6948374ef17d6dd720646ec1ec01a5222 Mon Sep 17 00:00:00 2001 From: joncrall Date: Mon, 18 Nov 2019 17:04:41 -0500 Subject: [PATCH] Consolidate test_forward and test_forward2 --- tests/test_forward.py | 105 ++++++++++++++++++++ tests/test_forward2.py | 213 ----------------------------------------- 2 files changed, 105 insertions(+), 213 deletions(-) delete mode 100644 tests/test_forward2.py diff --git a/tests/test_forward.py b/tests/test_forward.py index 0bec83c73ca..1ed9236e15d 100644 --- a/tests/test_forward.py +++ b/tests/test_forward.py @@ -168,6 +168,111 @@ def test_retina_ghm_forward(): batch_results.append(result) +def test_cascade_empty_forward(): + try: + from torchvision import _C as C # NOQA + except ImportError: + import pytest + raise pytest.skip('requires torchvision on cpu') + + model, train_cfg, test_cfg = _get_detector_cfg( + 'cascade_rcnn_r50_fpn_1x.py') + model['pretrained'] = None + # torchvision roi align supports CPU + model['bbox_roi_extractor']['roi_layer']['use_torchvision'] = True + + from mmdet.models import build_detector + detector = build_detector(model, train_cfg=train_cfg, test_cfg=test_cfg) + + input_shape = (1, 3, 256, 256) + + # Test forward train with an empty truth batch + mm_inputs = _demo_mm_inputs(input_shape, num_items=[0]) + imgs = mm_inputs.pop('imgs') + img_metas = mm_inputs.pop('img_metas') + gt_bboxes = mm_inputs['gt_bboxes'] + gt_labels = mm_inputs['gt_labels'] + losses = detector.forward( + imgs, + img_metas, + gt_bboxes=gt_bboxes, + gt_labels=gt_labels, + return_loss=True) + assert isinstance(losses, dict) + from mmdet.apis.train import parse_losses + total_loss = float(parse_losses(losses)[0].item()) + assert total_loss > 0 + + # Test forward train with a non-empty truth batch + mm_inputs = _demo_mm_inputs(input_shape, num_items=[10]) + imgs = mm_inputs.pop('imgs') + img_metas = mm_inputs.pop('img_metas') + gt_bboxes = mm_inputs['gt_bboxes'] + gt_labels = mm_inputs['gt_labels'] + losses = detector.forward( + imgs, + img_metas, + gt_bboxes=gt_bboxes, + gt_labels=gt_labels, + return_loss=True) + assert isinstance(losses, dict) + from mmdet.apis.train import parse_losses + total_loss = float(parse_losses(losses)[0].item()) + assert total_loss > 0 + + +def test_faster_rcnn_empty_forward(): + try: + from torchvision import _C as C # NOQA + except ImportError: + import pytest + raise pytest.skip('requires torchvision on cpu') + + model, train_cfg, test_cfg = _get_detector_cfg('faster_rcnn_r50_fpn_1x.py') + model['pretrained'] = None + # torchvision roi align supports CPU + model['bbox_roi_extractor']['roi_layer']['use_torchvision'] = True + + from mmdet.models import build_detector + detector = build_detector(model, train_cfg=train_cfg, test_cfg=test_cfg) + + input_shape = (1, 3, 256, 256) + + # Test forward train with an empty truth batch + mm_inputs = _demo_mm_inputs(input_shape, num_items=[0]) + imgs = mm_inputs.pop('imgs') + img_metas = mm_inputs.pop('img_metas') + gt_bboxes = mm_inputs['gt_bboxes'] + gt_labels = mm_inputs['gt_labels'] + losses = detector.forward( + imgs, + img_metas, + gt_bboxes=gt_bboxes, + gt_labels=gt_labels, + return_loss=True) + assert isinstance(losses, dict) + from mmdet.apis.train import parse_losses + total_loss = float(parse_losses(losses)[0].item()) + assert total_loss > 0 + + # Test forward train with a non-empty truth batch + mm_inputs = _demo_mm_inputs(input_shape, num_items=[10]) + imgs = mm_inputs.pop('imgs') + img_metas = mm_inputs.pop('img_metas') + gt_bboxes = mm_inputs['gt_bboxes'] + gt_labels = mm_inputs['gt_labels'] + losses = detector.forward( + imgs, + img_metas, + gt_bboxes=gt_bboxes, + gt_labels=gt_labels, + return_loss=True) + assert isinstance(losses, dict) + from mmdet.apis.train import parse_losses + total_loss = float(parse_losses(losses)[0].item()) + assert total_loss > 0 + + def _demo_mm_inputs( input_shape=(1, 3, 300, 300), num_items=None, num_classes=10): """ diff --git a/tests/test_forward2.py b/tests/test_forward2.py deleted file mode 100644 index 25b2ec8ccf0..00000000000 --- a/tests/test_forward2.py +++ /dev/null @@ -1,213 +0,0 @@ -# TODO: This should be merged with test_forward once -# `dev/fix_base_forward_test` lands -import copy -from os.path import dirname, exists, join - -import numpy as np -import torch - - -def _get_config_directory(): - """ Find the predefined detector config directory """ - try: - # Assume we are running in the source mmdetection repo - repo_dpath = dirname(dirname(__file__)) - except NameError: - # For IPython development when this __file__ is not defined - import mmdet - repo_dpath = dirname(dirname(mmdet.__file__)) - config_dpath = join(repo_dpath, 'configs') - if not exists(config_dpath): - raise Exception('Cannot find config path') - return config_dpath - - -def _get_config_module(fname): - """ - Load a configuration as a python module - """ - from xdoctest.utils import import_module_from_path - config_dpath = _get_config_directory() - config_fpath = join(config_dpath, fname) - config_mod = import_module_from_path(config_fpath) - return config_mod - - -def _get_detector_cfg(fname): - """ - Grab configs necessary to create a detector. These are deep copied to allow - for safe modification of parameters without influencing other tests. - """ - import mmcv - config = _get_config_module(fname) - model = copy.deepcopy(config.model) - train_cfg = mmcv.Config(copy.deepcopy(config.train_cfg)) - test_cfg = mmcv.Config(copy.deepcopy(config.test_cfg)) - return model, train_cfg, test_cfg - - -def test_cascade_empty_forward(): - try: - from torchvision import _C as C # NOQA - except ImportError: - import pytest - raise pytest.skip('requires torchvision on cpu') - - model, train_cfg, test_cfg = _get_detector_cfg( - 'cascade_rcnn_r50_fpn_1x.py') - model['pretrained'] = None - # torchvision roi align supports CPU - model['bbox_roi_extractor']['roi_layer']['use_torchvision'] = True - - from mmdet.models import build_detector - detector = build_detector(model, train_cfg=train_cfg, test_cfg=test_cfg) - - input_shape = (1, 3, 256, 256) - - # Test forward train with an empty truth batch - mm_inputs = _demo_mm_inputs(input_shape, num_items=[0]) - imgs = mm_inputs.pop('imgs') - img_metas = mm_inputs.pop('img_metas') - gt_bboxes = mm_inputs['gt_bboxes'] - gt_labels = mm_inputs['gt_labels'] - losses = detector.forward( - imgs, - img_metas, - gt_bboxes=gt_bboxes, - gt_labels=gt_labels, - return_loss=True) - assert isinstance(losses, dict) - from mmdet.apis.train import parse_losses - total_loss = float(parse_losses(losses)[0].item()) - assert total_loss > 0 - - # Test forward train with a non-empty truth batch - mm_inputs = _demo_mm_inputs(input_shape, num_items=[10]) - imgs = mm_inputs.pop('imgs') - img_metas = mm_inputs.pop('img_metas') - gt_bboxes = mm_inputs['gt_bboxes'] - gt_labels = mm_inputs['gt_labels'] - losses = detector.forward( - imgs, - img_metas, - gt_bboxes=gt_bboxes, - gt_labels=gt_labels, - return_loss=True) - assert isinstance(losses, dict) - from mmdet.apis.train import parse_losses - total_loss = float(parse_losses(losses)[0].item()) - assert total_loss > 0 - - -def test_faster_rcnn_empty_forward(): - try: - from torchvision import _C as C # NOQA - except ImportError: - import pytest - raise pytest.skip('requires torchvision on cpu') - - model, train_cfg, test_cfg = _get_detector_cfg('faster_rcnn_r50_fpn_1x.py') - model['pretrained'] = None - # torchvision roi align supports CPU - model['bbox_roi_extractor']['roi_layer']['use_torchvision'] = True - - from mmdet.models import build_detector - detector = build_detector(model, train_cfg=train_cfg, test_cfg=test_cfg) - - input_shape = (1, 3, 256, 256) - - # Test forward train with an empty truth batch - mm_inputs = _demo_mm_inputs(input_shape, num_items=[0]) - imgs = mm_inputs.pop('imgs') - img_metas = mm_inputs.pop('img_metas') - gt_bboxes = mm_inputs['gt_bboxes'] - gt_labels = mm_inputs['gt_labels'] - losses = detector.forward( - imgs, - img_metas, - gt_bboxes=gt_bboxes, - gt_labels=gt_labels, - return_loss=True) - assert isinstance(losses, dict) - from mmdet.apis.train import parse_losses - total_loss = float(parse_losses(losses)[0].item()) - assert total_loss > 0 - - # Test forward train with a non-empty truth batch - mm_inputs = _demo_mm_inputs(input_shape, num_items=[10]) - imgs = mm_inputs.pop('imgs') - img_metas = mm_inputs.pop('img_metas') - gt_bboxes = mm_inputs['gt_bboxes'] - gt_labels = mm_inputs['gt_labels'] - losses = detector.forward( - imgs, - img_metas, - gt_bboxes=gt_bboxes, - gt_labels=gt_labels, - return_loss=True) - assert isinstance(losses, dict) - from mmdet.apis.train import parse_losses - total_loss = float(parse_losses(losses)[0].item()) - assert total_loss > 0 - - -def _demo_mm_inputs( - input_shape=(1, 3, 300, 300), num_items=None, num_classes=10): - """ - Create a superset of inputs needed to run test or train batches. - - Args: - input_shape (tuple): - input batch dimensions - - num_items (None | List[int]): - specifies the number of boxes in each batch item - - num_classes (int): - number of different labels a box might have - """ - (N, C, H, W) = input_shape - - rng = np.random.RandomState(0) - - imgs = rng.rand(*input_shape) - - img_metas = [{ - 'img_shape': (H, W, C), - 'ori_shape': (H, W, C), - 'pad_shape': (H, W, C), - 'filename': '.png', - 'scale_factor': 1.0, - 'flip': False, - } for _ in range(N)] - - gt_bboxes = [] - gt_labels = [] - - for batch_idx in range(N): - if num_items is None: - num_boxes = rng.randint(1, 10) - else: - num_boxes = num_items[batch_idx] - - cx, cy, bw, bh = rng.rand(num_boxes, 4).T - - tl_x = ((cx * W) - (W * bw / 2)).clip(0, W) - tl_y = ((cy * H) - (H * bh / 2)).clip(0, H) - br_x = ((cx * W) + (W * bw / 2)).clip(0, W) - br_y = ((cy * H) + (H * bh / 2)).clip(0, H) - - boxes = np.vstack([tl_x, tl_y, br_x, br_y]).T - class_idxs = rng.randint(1, num_classes, size=num_boxes) - - gt_bboxes.append(torch.FloatTensor(boxes)) - gt_labels.append(torch.LongTensor(class_idxs)) - - mm_inputs = { - 'imgs': torch.FloatTensor(imgs), - 'img_metas': img_metas, - 'gt_bboxes': gt_bboxes, - 'gt_labels': gt_labels, - 'gt_bboxes_ignore': None, - } - return mm_inputs