|
""" |
|
CommandLine: |
|
pytest tests/test_utils/test_anchor.py |
|
xdoctest tests/test_utils/test_anchor.py zero |
|
|
|
""" |
|
import torch |
|
|
|
|
|
def test_standard_anchor_generator(): |
|
from mmdet.core.anchor import build_anchor_generator |
|
anchor_generator_cfg = dict( |
|
type='AnchorGenerator', |
|
scales=[8], |
|
ratios=[0.5, 1.0, 2.0], |
|
strides=[4, 8]) |
|
|
|
anchor_generator = build_anchor_generator(anchor_generator_cfg) |
|
assert anchor_generator is not None |
|
|
|
|
|
def test_strides(): |
|
from mmdet.core import AnchorGenerator |
|
|
|
self = AnchorGenerator([10], [1.], [1.], [10]) |
|
anchors = self.grid_anchors([(2, 2)], device='cpu') |
|
|
|
expected_anchors = torch.tensor([[-5., -5., 5., 5.], [5., -5., 15., 5.], |
|
[-5., 5., 5., 15.], [5., 5., 15., 15.]]) |
|
|
|
assert torch.equal(anchors[0], expected_anchors) |
|
|
|
|
|
self = AnchorGenerator([(10, 20)], [1.], [1.], [10]) |
|
anchors = self.grid_anchors([(2, 2)], device='cpu') |
|
|
|
expected_anchors = torch.tensor([[-5., -5., 5., 5.], [5., -5., 15., 5.], |
|
[-5., 15., 5., 25.], [5., 15., 15., 25.]]) |
|
|
|
assert torch.equal(anchors[0], expected_anchors) |
|
|
|
|
|
def test_ssd_anchor_generator(): |
|
from mmdet.core.anchor import build_anchor_generator |
|
if torch.cuda.is_available(): |
|
device = 'cuda' |
|
else: |
|
device = 'cpu' |
|
|
|
anchor_generator_cfg = dict( |
|
type='SSDAnchorGenerator', |
|
scale_major=False, |
|
input_size=300, |
|
basesize_ratio_range=(0.15, 0.9), |
|
strides=[8, 16, 32, 64, 100, 300], |
|
ratios=[[2], [2, 3], [2, 3], [2, 3], [2], [2]]) |
|
|
|
featmap_sizes = [(38, 38), (19, 19), (10, 10), (5, 5), (3, 3), (1, 1)] |
|
anchor_generator = build_anchor_generator(anchor_generator_cfg) |
|
|
|
|
|
expected_base_anchors = [ |
|
torch.Tensor([[-6.5000, -6.5000, 14.5000, 14.5000], |
|
[-11.3704, -11.3704, 19.3704, 19.3704], |
|
[-10.8492, -3.4246, 18.8492, 11.4246], |
|
[-3.4246, -10.8492, 11.4246, 18.8492]]), |
|
torch.Tensor([[-14.5000, -14.5000, 30.5000, 30.5000], |
|
[-25.3729, -25.3729, 41.3729, 41.3729], |
|
[-23.8198, -7.9099, 39.8198, 23.9099], |
|
[-7.9099, -23.8198, 23.9099, 39.8198], |
|
[-30.9711, -4.9904, 46.9711, 20.9904], |
|
[-4.9904, -30.9711, 20.9904, 46.9711]]), |
|
torch.Tensor([[-33.5000, -33.5000, 65.5000, 65.5000], |
|
[-45.5366, -45.5366, 77.5366, 77.5366], |
|
[-54.0036, -19.0018, 86.0036, 51.0018], |
|
[-19.0018, -54.0036, 51.0018, 86.0036], |
|
[-69.7365, -12.5788, 101.7365, 44.5788], |
|
[-12.5788, -69.7365, 44.5788, 101.7365]]), |
|
torch.Tensor([[-44.5000, -44.5000, 108.5000, 108.5000], |
|
[-56.9817, -56.9817, 120.9817, 120.9817], |
|
[-76.1873, -22.0937, 140.1873, 86.0937], |
|
[-22.0937, -76.1873, 86.0937, 140.1873], |
|
[-100.5019, -12.1673, 164.5019, 76.1673], |
|
[-12.1673, -100.5019, 76.1673, 164.5019]]), |
|
torch.Tensor([[-53.5000, -53.5000, 153.5000, 153.5000], |
|
[-66.2185, -66.2185, 166.2185, 166.2185], |
|
[-96.3711, -23.1855, 196.3711, 123.1855], |
|
[-23.1855, -96.3711, 123.1855, 196.3711]]), |
|
torch.Tensor([[19.5000, 19.5000, 280.5000, 280.5000], |
|
[6.6342, 6.6342, 293.3658, 293.3658], |
|
[-34.5549, 57.7226, 334.5549, 242.2774], |
|
[57.7226, -34.5549, 242.2774, 334.5549]]), |
|
] |
|
base_anchors = anchor_generator.base_anchors |
|
for i, base_anchor in enumerate(base_anchors): |
|
assert base_anchor.allclose(expected_base_anchors[i]) |
|
|
|
|
|
expected_valid_pixels = [5776, 2166, 600, 150, 36, 4] |
|
multi_level_valid_flags = anchor_generator.valid_flags( |
|
featmap_sizes, (300, 300), device) |
|
for i, single_level_valid_flag in enumerate(multi_level_valid_flags): |
|
assert single_level_valid_flag.sum() == expected_valid_pixels[i] |
|
|
|
|
|
assert anchor_generator.num_base_anchors == [4, 6, 6, 6, 4, 4] |
|
|
|
|
|
anchors = anchor_generator.grid_anchors(featmap_sizes, device) |
|
assert len(anchors) == 6 |
|
|
|
|
|
def test_anchor_generator_with_tuples(): |
|
from mmdet.core.anchor import build_anchor_generator |
|
if torch.cuda.is_available(): |
|
device = 'cuda' |
|
else: |
|
device = 'cpu' |
|
|
|
anchor_generator_cfg = dict( |
|
type='SSDAnchorGenerator', |
|
scale_major=False, |
|
input_size=300, |
|
basesize_ratio_range=(0.15, 0.9), |
|
strides=[8, 16, 32, 64, 100, 300], |
|
ratios=[[2], [2, 3], [2, 3], [2, 3], [2], [2]]) |
|
|
|
featmap_sizes = [(38, 38), (19, 19), (10, 10), (5, 5), (3, 3), (1, 1)] |
|
anchor_generator = build_anchor_generator(anchor_generator_cfg) |
|
anchors = anchor_generator.grid_anchors(featmap_sizes, device) |
|
|
|
anchor_generator_cfg_tuples = dict( |
|
type='SSDAnchorGenerator', |
|
scale_major=False, |
|
input_size=300, |
|
basesize_ratio_range=(0.15, 0.9), |
|
strides=[(8, 8), (16, 16), (32, 32), (64, 64), (100, 100), (300, 300)], |
|
ratios=[[2], [2, 3], [2, 3], [2, 3], [2], [2]]) |
|
|
|
anchor_generator_tuples = build_anchor_generator( |
|
anchor_generator_cfg_tuples) |
|
anchors_tuples = anchor_generator_tuples.grid_anchors( |
|
featmap_sizes, device) |
|
for anchor, anchor_tuples in zip(anchors, anchors_tuples): |
|
assert torch.equal(anchor, anchor_tuples) |
|
|
|
|
|
def test_yolo_anchor_generator(): |
|
from mmdet.core.anchor import build_anchor_generator |
|
if torch.cuda.is_available(): |
|
device = 'cuda' |
|
else: |
|
device = 'cpu' |
|
|
|
anchor_generator_cfg = dict( |
|
type='YOLOAnchorGenerator', |
|
strides=[32, 16, 8], |
|
base_sizes=[ |
|
[(116, 90), (156, 198), (373, 326)], |
|
[(30, 61), (62, 45), (59, 119)], |
|
[(10, 13), (16, 30), (33, 23)], |
|
]) |
|
|
|
featmap_sizes = [(14, 18), (28, 36), (56, 72)] |
|
anchor_generator = build_anchor_generator(anchor_generator_cfg) |
|
|
|
|
|
expected_base_anchors = [ |
|
torch.Tensor([[-42.0000, -29.0000, 74.0000, 61.0000], |
|
[-62.0000, -83.0000, 94.0000, 115.0000], |
|
[-170.5000, -147.0000, 202.5000, 179.0000]]), |
|
torch.Tensor([[-7.0000, -22.5000, 23.0000, 38.5000], |
|
[-23.0000, -14.5000, 39.0000, 30.5000], |
|
[-21.5000, -51.5000, 37.5000, 67.5000]]), |
|
torch.Tensor([[-1.0000, -2.5000, 9.0000, 10.5000], |
|
[-4.0000, -11.0000, 12.0000, 19.0000], |
|
[-12.5000, -7.5000, 20.5000, 15.5000]]) |
|
] |
|
base_anchors = anchor_generator.base_anchors |
|
for i, base_anchor in enumerate(base_anchors): |
|
assert base_anchor.allclose(expected_base_anchors[i]) |
|
|
|
|
|
assert anchor_generator.num_base_anchors == [3, 3, 3] |
|
|
|
|
|
anchors = anchor_generator.grid_anchors(featmap_sizes, device) |
|
assert len(anchors) == 3 |
|
|
|
|
|
def test_retina_anchor(): |
|
from mmdet.models import build_head |
|
if torch.cuda.is_available(): |
|
device = 'cuda' |
|
else: |
|
device = 'cpu' |
|
|
|
|
|
|
|
bbox_head = dict( |
|
type='RetinaSepBNHead', |
|
num_classes=4, |
|
num_ins=5, |
|
in_channels=4, |
|
stacked_convs=1, |
|
feat_channels=4, |
|
anchor_generator=dict( |
|
type='AnchorGenerator', |
|
octave_base_scale=4, |
|
scales_per_octave=3, |
|
ratios=[0.5, 1.0, 2.0], |
|
strides=[8, 16, 32, 64, 128]), |
|
bbox_coder=dict( |
|
type='DeltaXYWHBBoxCoder', |
|
target_means=[.0, .0, .0, .0], |
|
target_stds=[1.0, 1.0, 1.0, 1.0])) |
|
|
|
retina_head = build_head(bbox_head) |
|
assert retina_head.anchor_generator is not None |
|
|
|
|
|
featmap_sizes = [(80, 80), (40, 40), (20, 20), (10, 10), (5, 5)] |
|
|
|
expected_base_anchors = [ |
|
torch.Tensor([[-22.6274, -11.3137, 22.6274, 11.3137], |
|
[-28.5088, -14.2544, 28.5088, 14.2544], |
|
[-35.9188, -17.9594, 35.9188, 17.9594], |
|
[-16.0000, -16.0000, 16.0000, 16.0000], |
|
[-20.1587, -20.1587, 20.1587, 20.1587], |
|
[-25.3984, -25.3984, 25.3984, 25.3984], |
|
[-11.3137, -22.6274, 11.3137, 22.6274], |
|
[-14.2544, -28.5088, 14.2544, 28.5088], |
|
[-17.9594, -35.9188, 17.9594, 35.9188]]), |
|
torch.Tensor([[-45.2548, -22.6274, 45.2548, 22.6274], |
|
[-57.0175, -28.5088, 57.0175, 28.5088], |
|
[-71.8376, -35.9188, 71.8376, 35.9188], |
|
[-32.0000, -32.0000, 32.0000, 32.0000], |
|
[-40.3175, -40.3175, 40.3175, 40.3175], |
|
[-50.7968, -50.7968, 50.7968, 50.7968], |
|
[-22.6274, -45.2548, 22.6274, 45.2548], |
|
[-28.5088, -57.0175, 28.5088, 57.0175], |
|
[-35.9188, -71.8376, 35.9188, 71.8376]]), |
|
torch.Tensor([[-90.5097, -45.2548, 90.5097, 45.2548], |
|
[-114.0350, -57.0175, 114.0350, 57.0175], |
|
[-143.6751, -71.8376, 143.6751, 71.8376], |
|
[-64.0000, -64.0000, 64.0000, 64.0000], |
|
[-80.6349, -80.6349, 80.6349, 80.6349], |
|
[-101.5937, -101.5937, 101.5937, 101.5937], |
|
[-45.2548, -90.5097, 45.2548, 90.5097], |
|
[-57.0175, -114.0350, 57.0175, 114.0350], |
|
[-71.8376, -143.6751, 71.8376, 143.6751]]), |
|
torch.Tensor([[-181.0193, -90.5097, 181.0193, 90.5097], |
|
[-228.0701, -114.0350, 228.0701, 114.0350], |
|
[-287.3503, -143.6751, 287.3503, 143.6751], |
|
[-128.0000, -128.0000, 128.0000, 128.0000], |
|
[-161.2699, -161.2699, 161.2699, 161.2699], |
|
[-203.1873, -203.1873, 203.1873, 203.1873], |
|
[-90.5097, -181.0193, 90.5097, 181.0193], |
|
[-114.0350, -228.0701, 114.0350, 228.0701], |
|
[-143.6751, -287.3503, 143.6751, 287.3503]]), |
|
torch.Tensor([[-362.0387, -181.0193, 362.0387, 181.0193], |
|
[-456.1401, -228.0701, 456.1401, 228.0701], |
|
[-574.7006, -287.3503, 574.7006, 287.3503], |
|
[-256.0000, -256.0000, 256.0000, 256.0000], |
|
[-322.5398, -322.5398, 322.5398, 322.5398], |
|
[-406.3747, -406.3747, 406.3747, 406.3747], |
|
[-181.0193, -362.0387, 181.0193, 362.0387], |
|
[-228.0701, -456.1401, 228.0701, 456.1401], |
|
[-287.3503, -574.7006, 287.3503, 574.7006]]) |
|
] |
|
base_anchors = retina_head.anchor_generator.base_anchors |
|
for i, base_anchor in enumerate(base_anchors): |
|
assert base_anchor.allclose(expected_base_anchors[i]) |
|
|
|
|
|
expected_valid_pixels = [57600, 14400, 3600, 900, 225] |
|
multi_level_valid_flags = retina_head.anchor_generator.valid_flags( |
|
featmap_sizes, (640, 640), device) |
|
for i, single_level_valid_flag in enumerate(multi_level_valid_flags): |
|
assert single_level_valid_flag.sum() == expected_valid_pixels[i] |
|
|
|
|
|
assert retina_head.anchor_generator.num_base_anchors == [9, 9, 9, 9, 9] |
|
|
|
|
|
anchors = retina_head.anchor_generator.grid_anchors(featmap_sizes, device) |
|
assert len(anchors) == 5 |
|
|
|
|
|
def test_guided_anchor(): |
|
from mmdet.models import build_head |
|
if torch.cuda.is_available(): |
|
device = 'cuda' |
|
else: |
|
device = 'cpu' |
|
|
|
|
|
bbox_head = dict( |
|
type='GARetinaHead', |
|
num_classes=8, |
|
in_channels=4, |
|
stacked_convs=1, |
|
feat_channels=4, |
|
approx_anchor_generator=dict( |
|
type='AnchorGenerator', |
|
octave_base_scale=4, |
|
scales_per_octave=3, |
|
ratios=[0.5, 1.0, 2.0], |
|
strides=[8, 16, 32, 64, 128]), |
|
square_anchor_generator=dict( |
|
type='AnchorGenerator', |
|
ratios=[1.0], |
|
scales=[4], |
|
strides=[8, 16, 32, 64, 128])) |
|
|
|
ga_retina_head = build_head(bbox_head) |
|
assert ga_retina_head.approx_anchor_generator is not None |
|
|
|
|
|
featmap_sizes = [(100, 152), (50, 76), (25, 38), (13, 19), (7, 10)] |
|
|
|
expected_approxs = [ |
|
torch.Tensor([[-22.6274, -11.3137, 22.6274, 11.3137], |
|
[-28.5088, -14.2544, 28.5088, 14.2544], |
|
[-35.9188, -17.9594, 35.9188, 17.9594], |
|
[-16.0000, -16.0000, 16.0000, 16.0000], |
|
[-20.1587, -20.1587, 20.1587, 20.1587], |
|
[-25.3984, -25.3984, 25.3984, 25.3984], |
|
[-11.3137, -22.6274, 11.3137, 22.6274], |
|
[-14.2544, -28.5088, 14.2544, 28.5088], |
|
[-17.9594, -35.9188, 17.9594, 35.9188]]), |
|
torch.Tensor([[-45.2548, -22.6274, 45.2548, 22.6274], |
|
[-57.0175, -28.5088, 57.0175, 28.5088], |
|
[-71.8376, -35.9188, 71.8376, 35.9188], |
|
[-32.0000, -32.0000, 32.0000, 32.0000], |
|
[-40.3175, -40.3175, 40.3175, 40.3175], |
|
[-50.7968, -50.7968, 50.7968, 50.7968], |
|
[-22.6274, -45.2548, 22.6274, 45.2548], |
|
[-28.5088, -57.0175, 28.5088, 57.0175], |
|
[-35.9188, -71.8376, 35.9188, 71.8376]]), |
|
torch.Tensor([[-90.5097, -45.2548, 90.5097, 45.2548], |
|
[-114.0350, -57.0175, 114.0350, 57.0175], |
|
[-143.6751, -71.8376, 143.6751, 71.8376], |
|
[-64.0000, -64.0000, 64.0000, 64.0000], |
|
[-80.6349, -80.6349, 80.6349, 80.6349], |
|
[-101.5937, -101.5937, 101.5937, 101.5937], |
|
[-45.2548, -90.5097, 45.2548, 90.5097], |
|
[-57.0175, -114.0350, 57.0175, 114.0350], |
|
[-71.8376, -143.6751, 71.8376, 143.6751]]), |
|
torch.Tensor([[-181.0193, -90.5097, 181.0193, 90.5097], |
|
[-228.0701, -114.0350, 228.0701, 114.0350], |
|
[-287.3503, -143.6751, 287.3503, 143.6751], |
|
[-128.0000, -128.0000, 128.0000, 128.0000], |
|
[-161.2699, -161.2699, 161.2699, 161.2699], |
|
[-203.1873, -203.1873, 203.1873, 203.1873], |
|
[-90.5097, -181.0193, 90.5097, 181.0193], |
|
[-114.0350, -228.0701, 114.0350, 228.0701], |
|
[-143.6751, -287.3503, 143.6751, 287.3503]]), |
|
torch.Tensor([[-362.0387, -181.0193, 362.0387, 181.0193], |
|
[-456.1401, -228.0701, 456.1401, 228.0701], |
|
[-574.7006, -287.3503, 574.7006, 287.3503], |
|
[-256.0000, -256.0000, 256.0000, 256.0000], |
|
[-322.5398, -322.5398, 322.5398, 322.5398], |
|
[-406.3747, -406.3747, 406.3747, 406.3747], |
|
[-181.0193, -362.0387, 181.0193, 362.0387], |
|
[-228.0701, -456.1401, 228.0701, 456.1401], |
|
[-287.3503, -574.7006, 287.3503, 574.7006]]) |
|
] |
|
approxs = ga_retina_head.approx_anchor_generator.base_anchors |
|
for i, base_anchor in enumerate(approxs): |
|
assert base_anchor.allclose(expected_approxs[i]) |
|
|
|
|
|
expected_valid_pixels = [136800, 34200, 8550, 2223, 630] |
|
multi_level_valid_flags = ga_retina_head.approx_anchor_generator \ |
|
.valid_flags(featmap_sizes, (800, 1216), device) |
|
for i, single_level_valid_flag in enumerate(multi_level_valid_flags): |
|
assert single_level_valid_flag.sum() == expected_valid_pixels[i] |
|
|
|
|
|
assert ga_retina_head.approx_anchor_generator.num_base_anchors == [ |
|
9, 9, 9, 9, 9 |
|
] |
|
|
|
|
|
squares = ga_retina_head.square_anchor_generator.grid_anchors( |
|
featmap_sizes, device) |
|
assert len(squares) == 5 |
|
|
|
expected_squares = [ |
|
torch.Tensor([[-16., -16., 16., 16.]]), |
|
torch.Tensor([[-32., -32., 32., 32]]), |
|
torch.Tensor([[-64., -64., 64., 64.]]), |
|
torch.Tensor([[-128., -128., 128., 128.]]), |
|
torch.Tensor([[-256., -256., 256., 256.]]) |
|
] |
|
squares = ga_retina_head.square_anchor_generator.base_anchors |
|
for i, base_anchor in enumerate(squares): |
|
assert base_anchor.allclose(expected_squares[i]) |
|
|
|
|
|
|
|
assert (ga_retina_head.square_anchor_generator.num_base_anchors == [ |
|
1, 1, 1, 1, 1 |
|
]) |
|
|
|
|
|
anchors = ga_retina_head.square_anchor_generator.grid_anchors( |
|
featmap_sizes, device) |
|
assert len(anchors) == 5 |
|
|