import os.path as osp import mmcv import pytest import torch from mmdet import digit_version from mmdet.models.necks import FPN, YOLOV3Neck from .utils import ort_validate if digit_version(torch.__version__) <= digit_version('1.5.0'): pytest.skip( 'ort backend does not support version below 1.5.0', allow_module_level=True) # Control the returned model of neck_config() test_step_names = { 'normal': 0, 'wo_extra_convs': 1, 'lateral_bns': 2, 'bilinear_upsample': 3, 'scale_factor': 4, 'extra_convs_inputs': 5, 'extra_convs_laterals': 6, 'extra_convs_outputs': 7, } data_path = osp.join(osp.dirname(__file__), 'data') def fpn_config(test_step_name): """Return the class containing the corresponding attributes according to the test_step_names.""" s = 64 in_channels = [8, 16, 32, 64] feat_sizes = [s // 2**i for i in range(4)] # [64, 32, 16, 8] out_channels = 8 feats = [ torch.rand(1, in_channels[i], feat_sizes[i], feat_sizes[i]) for i in range(len(in_channels)) ] if (test_step_names[test_step_name] == 0): fpn_model = FPN( in_channels=in_channels, out_channels=out_channels, add_extra_convs=True, num_outs=5) return fpn_model, feats elif (test_step_names[test_step_name] == 1): # Tests for fpn with no extra convs (pooling is used instead) fpn_model = FPN( in_channels=in_channels, out_channels=out_channels, add_extra_convs=False, num_outs=5) return fpn_model, feats elif (test_step_names[test_step_name] == 2): fpn_model = FPN( in_channels=in_channels, out_channels=out_channels, add_extra_convs=True, no_norm_on_lateral=False, norm_cfg=dict(type='BN', requires_grad=True), num_outs=5) return fpn_model, feats elif (test_step_names[test_step_name] == 3): fpn_model = FPN( in_channels=in_channels, out_channels=out_channels, add_extra_convs=True, upsample_cfg=dict(mode='bilinear', align_corners=True), num_outs=5) return fpn_model, feats elif (test_step_names[test_step_name] == 4): fpn_model = FPN( in_channels=in_channels, out_channels=out_channels, add_extra_convs=True, upsample_cfg=dict(scale_factor=2), num_outs=5) return fpn_model, feats elif (test_step_names[test_step_name] == 5): fpn_model = FPN( in_channels=in_channels, out_channels=out_channels, add_extra_convs='on_input', num_outs=5) return fpn_model, feats elif (test_step_names[test_step_name] == 6): fpn_model = FPN( in_channels=in_channels, out_channels=out_channels, add_extra_convs='on_lateral', num_outs=5) return fpn_model, feats elif (test_step_names[test_step_name] == 7): fpn_model = FPN( in_channels=in_channels, out_channels=out_channels, add_extra_convs='on_output', num_outs=5) return fpn_model, feats def yolo_config(test_step_name): """Config yolov3 Neck.""" in_channels = [16, 8, 4] out_channels = [8, 4, 2] # The data of yolov3_neck.pkl contains a list of # torch.Tensor, where each torch.Tensor is generated by # torch.rand and each tensor size is: # (1, 4, 64, 64), (1, 8, 32, 32), (1, 16, 16, 16). yolov3_neck_data = 'yolov3_neck.pkl' feats = mmcv.load(osp.join(data_path, yolov3_neck_data)) if (test_step_names[test_step_name] == 0): yolo_model = YOLOV3Neck( in_channels=in_channels, out_channels=out_channels, num_scales=3) return yolo_model, feats def test_fpn_normal(): outs = fpn_config('normal') ort_validate(*outs) def test_fpn_wo_extra_convs(): outs = fpn_config('wo_extra_convs') ort_validate(*outs) def test_fpn_lateral_bns(): outs = fpn_config('lateral_bns') ort_validate(*outs) def test_fpn_bilinear_upsample(): outs = fpn_config('bilinear_upsample') ort_validate(*outs) def test_fpn_scale_factor(): outs = fpn_config('scale_factor') ort_validate(*outs) def test_fpn_extra_convs_inputs(): outs = fpn_config('extra_convs_inputs') ort_validate(*outs) def test_fpn_extra_convs_laterals(): outs = fpn_config('extra_convs_laterals') ort_validate(*outs) def test_fpn_extra_convs_outputs(): outs = fpn_config('extra_convs_outputs') ort_validate(*outs) def test_yolo_normal(): outs = yolo_config('normal') ort_validate(*outs)