test_models_detection_negative_samples.py 6.28 KB
Newer Older
1
import pytest
2
3
import torch
import torchvision.models
4
from common_utils import assert_equal
5
6
from torchvision.models.detection.faster_rcnn import FastRCNNPredictor, TwoMLPHead
from torchvision.models.detection.roi_heads import RoIHeads
7
from torchvision.models.detection.rpn import AnchorGenerator, RegionProposalNetwork, RPNHead
8
from torchvision.ops import MultiScaleRoIAlign
9
10


11
class TestModelsDetectionNegativeSamples:
12
13
    def _make_empty_sample(self, add_masks=False, add_keypoints=False):
        images = [torch.rand((3, 100, 100), dtype=torch.float32)]
14
        boxes = torch.zeros((0, 4), dtype=torch.float32)
15
16
17
18
19
20
21
        negative_target = {
            "boxes": boxes,
            "labels": torch.zeros(0, dtype=torch.int64),
            "image_id": 4,
            "area": (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0]),
            "iscrowd": torch.zeros((0,), dtype=torch.int64),
        }
22

23
24
25
26
27
28
        if add_masks:
            negative_target["masks"] = torch.zeros(0, 100, 100, dtype=torch.uint8)

        if add_keypoints:
            negative_target["keypoints"] = torch.zeros(17, 0, 3, dtype=torch.float32)

29
        targets = [negative_target]
30
31
32
33
34
        return images, targets

    def test_targets_to_anchors(self):
        _, targets = self._make_empty_sample()
        anchors = [torch.randint(-50, 50, (3, 4), dtype=torch.float32)]
35
36
37

        anchor_sizes = ((32,), (64,), (128,), (256,), (512,))
        aspect_ratios = ((0.5, 1.0, 2.0),) * len(anchor_sizes)
38
        rpn_anchor_generator = AnchorGenerator(anchor_sizes, aspect_ratios)
39
40
        rpn_head = RPNHead(4, rpn_anchor_generator.num_anchors_per_location()[0])

41
        head = RegionProposalNetwork(rpn_anchor_generator, rpn_head, 0.5, 0.3, 256, 0.5, 2000, 2000, 0.7, 0.05)
42
43
44

        labels, matched_gt_boxes = head.assign_targets_to_anchors(anchors, targets)

45
46
47
        assert labels[0].sum() == 0
        assert labels[0].shape == torch.Size([anchors[0].shape[0]])
        assert labels[0].dtype == torch.float32
48

49
50
51
        assert matched_gt_boxes[0].sum() == 0
        assert matched_gt_boxes[0].shape == anchors[0].shape
        assert matched_gt_boxes[0].dtype == torch.float32
52
53
54
55
56
57
58

    def test_assign_targets_to_proposals(self):

        proposals = [torch.randint(-50, 50, (20, 4), dtype=torch.float32)]
        gt_boxes = [torch.zeros((0, 4), dtype=torch.float32)]
        gt_labels = [torch.tensor([[0]], dtype=torch.int64)]

59
        box_roi_pool = MultiScaleRoIAlign(featmap_names=["0", "1", "2", "3"], output_size=7, sampling_ratio=2)
60
61
62

        resolution = box_roi_pool.output_size[0]
        representation_size = 1024
63
        box_head = TwoMLPHead(4 * resolution**2, representation_size)
64
65

        representation_size = 1024
66
        box_predictor = FastRCNNPredictor(representation_size, 2)
67
68
69

        roi_heads = RoIHeads(
            # Box
70
71
72
73
74
75
76
            box_roi_pool,
            box_head,
            box_predictor,
            0.5,
            0.5,
            512,
            0.25,
77
            None,
78
79
80
81
            0.05,
            0.5,
            100,
        )
82
83
84

        matched_idxs, labels = roi_heads.assign_targets_to_proposals(proposals, gt_boxes, gt_labels)

85
86
87
88
89
90
91
92
        assert matched_idxs[0].sum() == 0
        assert matched_idxs[0].shape == torch.Size([proposals[0].shape[0]])
        assert matched_idxs[0].dtype == torch.int64

        assert labels[0].sum() == 0
        assert labels[0].shape == torch.Size([proposals[0].shape[0]])
        assert labels[0].dtype == torch.int64

93
94
95
96
97
98
99
100
    @pytest.mark.parametrize(
        "name",
        [
            "fasterrcnn_resnet50_fpn",
            "fasterrcnn_mobilenet_v3_large_fpn",
            "fasterrcnn_mobilenet_v3_large_320_fpn",
        ],
    )
101
    def test_forward_negative_sample_frcnn(self, name):
102
103
        model = torchvision.models.get_model(
            name, weights=None, weights_backbone=None, num_classes=2, min_size=100, max_size=100
104
        )
105

106
107
        images, targets = self._make_empty_sample()
        loss_dict = model(images, targets)
108

109
110
        assert_equal(loss_dict["loss_box_reg"], torch.tensor(0.0))
        assert_equal(loss_dict["loss_rpn_box_reg"], torch.tensor(0.0))
111
112

    def test_forward_negative_sample_mrcnn(self):
113
        model = torchvision.models.detection.maskrcnn_resnet50_fpn(
114
            weights=None, weights_backbone=None, num_classes=2, min_size=100, max_size=100
115
        )
116
117
118
119

        images, targets = self._make_empty_sample(add_masks=True)
        loss_dict = model(images, targets)

120
121
122
        assert_equal(loss_dict["loss_box_reg"], torch.tensor(0.0))
        assert_equal(loss_dict["loss_rpn_box_reg"], torch.tensor(0.0))
        assert_equal(loss_dict["loss_mask"], torch.tensor(0.0))
123
124

    def test_forward_negative_sample_krcnn(self):
125
        model = torchvision.models.detection.keypointrcnn_resnet50_fpn(
126
            weights=None, weights_backbone=None, num_classes=2, min_size=100, max_size=100
127
        )
128

129
        images, targets = self._make_empty_sample(add_keypoints=True)
130
131
        loss_dict = model(images, targets)

132
133
134
        assert_equal(loss_dict["loss_box_reg"], torch.tensor(0.0))
        assert_equal(loss_dict["loss_rpn_box_reg"], torch.tensor(0.0))
        assert_equal(loss_dict["loss_keypoint"], torch.tensor(0.0))
135

136
137
    def test_forward_negative_sample_retinanet(self):
        model = torchvision.models.detection.retinanet_resnet50_fpn(
138
            weights=None, weights_backbone=None, num_classes=2, min_size=100, max_size=100
139
        )
140
141
142
143

        images, targets = self._make_empty_sample()
        loss_dict = model(images, targets)

144
        assert_equal(loss_dict["bbox_regression"], torch.tensor(0.0))
145

146
147
    def test_forward_negative_sample_fcos(self):
        model = torchvision.models.detection.fcos_resnet50_fpn(
148
            weights=None, weights_backbone=None, num_classes=2, min_size=100, max_size=100
149
150
151
152
153
154
155
156
        )

        images, targets = self._make_empty_sample()
        loss_dict = model(images, targets)

        assert_equal(loss_dict["bbox_regression"], torch.tensor(0.0))
        assert_equal(loss_dict["bbox_ctrness"], torch.tensor(0.0))

157
    def test_forward_negative_sample_ssd(self):
158
        model = torchvision.models.detection.ssd300_vgg16(weights=None, weights_backbone=None, num_classes=2)
159
160
161
162

        images, targets = self._make_empty_sample()
        loss_dict = model(images, targets)

163
        assert_equal(loss_dict["bbox_regression"], torch.tensor(0.0))
164

165

166
if __name__ == "__main__":
167
    pytest.main([__file__])