5
from collections import OrderedDict
6
from typing import List, Mapping, Tuple
11
import pytorch_test_common
16
from pytorch_test_common import skipIfUnsupportedMinOpsetVersion, skipScriptTest
18
from torch.testing._internal import common_utils
19
from torchvision import ops
20
from torchvision.models.detection import (
38
acceptable_error_percentage=None,
40
opset_versions = opset_versions if opset_versions else [7, 8, 9, 10, 11, 12, 13, 14]
42
for opset_version in opset_versions:
43
self.opset_version = opset_version
44
self.onnx_shape_inference = True
45
onnx_test_common.run_model_test(
51
acceptable_error_percentage=acceptable_error_percentage,
54
if self.is_script_test_enabled and opset_version > 11:
55
script_model = torch.jit.script(model)
56
onnx_test_common.run_model_test(
62
acceptable_error_percentage=acceptable_error_percentage,
68
(pytorch_test_common.ExportTestCase,),
70
test_models.TestModels.__dict__,
71
is_script_test_enabled=False,
73
exportTest=exportTest,
79
TestModels_new_jit_API = type(
80
"TestModels_new_jit_API",
81
(pytorch_test_common.ExportTestCase,),
84
exportTest=exportTest,
85
is_script_test_enabled=True,
87
onnx_shape_inference=True,
92
def _get_image(rel_path: str, size: Tuple[int, int]) -> torch.Tensor:
93
data_dir = os.path.join(os.path.dirname(__file__), "assets")
94
path = os.path.join(data_dir, *rel_path.split("/"))
95
image = PIL.Image.open(path).convert("RGB").resize(size, PIL.Image.BILINEAR)
97
return torchvision.transforms.ToTensor()(image)
100
def _get_test_images() -> Tuple[List[torch.Tensor], List[torch.Tensor]]:
102
[_get_image("grace_hopper_517x606.jpg", (100, 320))],
103
[_get_image("rgb_pytorch.png", (250, 380))],
107
def _get_features(images):
108
s0, s1 = images.shape[-2:]
110
("0", torch.rand(2, 256, s0 // 4, s1 // 4)),
111
("1", torch.rand(2, 256, s0 // 8, s1 // 8)),
112
("2", torch.rand(2, 256, s0 // 16, s1 // 16)),
113
("3", torch.rand(2, 256, s0 // 32, s1 // 32)),
114
("4", torch.rand(2, 256, s0 // 64, s1 // 64)),
116
features = OrderedDict(features)
120
def _init_test_generalized_rcnn_transform():
123
image_mean = [0.485, 0.456, 0.406]
124
image_std = [0.229, 0.224, 0.225]
125
return transform.GeneralizedRCNNTransform(min_size, max_size, image_mean, image_std)
129
anchor_sizes = ((32,), (64,), (128,), (256,), (512,))
130
aspect_ratios = ((0.5, 1.0, 2.0),) * len(anchor_sizes)
131
rpn_anchor_generator = rpn.AnchorGenerator(anchor_sizes, aspect_ratios)
133
rpn_head = rpn.RPNHead(
134
out_channels, rpn_anchor_generator.num_anchors_per_location()[0]
136
rpn_fg_iou_thresh = 0.7
137
rpn_bg_iou_thresh = 0.3
138
rpn_batch_size_per_image = 256
139
rpn_positive_fraction = 0.5
140
rpn_pre_nms_top_n = dict(training=2000, testing=1000)
141
rpn_post_nms_top_n = dict(training=2000, testing=1000)
143
rpn_score_thresh = 0.0
145
return rpn.RegionProposalNetwork(
146
rpn_anchor_generator,
150
rpn_batch_size_per_image,
151
rpn_positive_fraction,
155
score_thresh=rpn_score_thresh,
159
def _init_test_roi_heads_faster_rcnn():
163
box_fg_iou_thresh = 0.5
164
box_bg_iou_thresh = 0.5
165
box_batch_size_per_image = 512
166
box_positive_fraction = 0.25
167
bbox_reg_weights = None
168
box_score_thresh = 0.05
170
box_detections_per_img = 100
172
box_roi_pool = ops.MultiScaleRoIAlign(
173
featmap_names=["0", "1", "2", "3"], output_size=7, sampling_ratio=2
176
resolution = box_roi_pool.output_size[0]
177
representation_size = 1024
178
box_head = faster_rcnn.TwoMLPHead(
179
out_channels * resolution**2, representation_size
182
representation_size = 1024
183
box_predictor = faster_rcnn.FastRCNNPredictor(representation_size, num_classes)
185
return roi_heads.RoIHeads(
191
box_batch_size_per_image,
192
box_positive_fraction,
196
box_detections_per_img,
200
@parameterized.parameterized_class(
203
class_name_func=onnx_test_common.parameterize_class_name,
205
class TestModelsONNXRuntime(onnx_test_common._TestONNXRuntime):
206
@skipIfUnsupportedMinOpsetVersion(11)
208
def test_faster_rcnn(self):
209
model = faster_rcnn.fasterrcnn_resnet50_fpn(
210
pretrained=False, pretrained_backbone=True, min_size=200, max_size=300
213
x1 = torch.randn(3, 200, 300, requires_grad=True)
214
x2 = torch.randn(3, 200, 300, requires_grad=True)
215
self.run_test(model, ([x1, x2],), rtol=1e-3, atol=1e-5)
219
input_names=["images_tensors"],
220
output_names=["outputs"],
221
dynamic_axes={"images_tensors": [0, 1, 2], "outputs": [0, 1, 2]},
225
dummy_image = [torch.ones(3, 100, 100) * 0.3]
226
images, test_images = _get_test_images()
230
additional_test_inputs=[(images,), (test_images,), (dummy_image,)],
231
input_names=["images_tensors"],
232
output_names=["outputs"],
233
dynamic_axes={"images_tensors": [0, 1, 2], "outputs": [0, 1, 2]},
240
additional_test_inputs=[(dummy_image,), (images,)],
241
input_names=["images_tensors"],
242
output_names=["outputs"],
243
dynamic_axes={"images_tensors": [0, 1, 2], "outputs": [0, 1, 2]},
248
@unittest.skip("Failing after ONNX 1.13.0")
249
@skipIfUnsupportedMinOpsetVersion(11)
251
def test_mask_rcnn(self):
252
model = mask_rcnn.maskrcnn_resnet50_fpn(
253
pretrained=False, pretrained_backbone=True, min_size=200, max_size=300
255
images, test_images = _get_test_images()
256
self.run_test(model, (images,), rtol=1e-3, atol=1e-5)
260
input_names=["images_tensors"],
261
output_names=["boxes", "labels", "scores", "masks"],
263
"images_tensors": [0, 1, 2],
272
dummy_image = [torch.ones(3, 100, 100) * 0.3]
276
additional_test_inputs=[(images,), (test_images,), (dummy_image,)],
277
input_names=["images_tensors"],
278
output_names=["boxes", "labels", "scores", "masks"],
280
"images_tensors": [0, 1, 2],
292
additional_test_inputs=[(dummy_image,), (images,)],
293
input_names=["images_tensors"],
294
output_names=["boxes", "labels", "scores", "masks"],
296
"images_tensors": [0, 1, 2],
306
@unittest.skip("Failing, see https://github.com/pytorch/pytorch/issues/66528")
307
@skipIfUnsupportedMinOpsetVersion(11)
309
def test_keypoint_rcnn(self):
310
model = keypoint_rcnn.keypointrcnn_resnet50_fpn(
311
pretrained=False, pretrained_backbone=False, min_size=200, max_size=300
313
images, test_images = _get_test_images()
314
self.run_test(model, (images,), rtol=1e-3, atol=1e-5)
318
input_names=["images_tensors"],
319
output_names=["outputs1", "outputs2", "outputs3", "outputs4"],
320
dynamic_axes={"images_tensors": [0, 1, 2]},
324
dummy_images = [torch.ones(3, 100, 100) * 0.3]
328
additional_test_inputs=[(images,), (test_images,), (dummy_images,)],
329
input_names=["images_tensors"],
330
output_names=["outputs1", "outputs2", "outputs3", "outputs4"],
331
dynamic_axes={"images_tensors": [0, 1, 2]},
338
additional_test_inputs=[(dummy_images,), (test_images,)],
339
input_names=["images_tensors"],
340
output_names=["outputs1", "outputs2", "outputs3", "outputs4"],
341
dynamic_axes={"images_tensors": [0, 1, 2]},
346
@skipIfUnsupportedMinOpsetVersion(11)
348
def test_roi_heads(self):
349
class RoIHeadsModule(torch.nn.Module):
352
self.transform = _init_test_generalized_rcnn_transform()
353
self.rpn = _init_test_rpn()
354
self.roi_heads = _init_test_roi_heads_faster_rcnn()
356
def forward(self, images, features: Mapping[str, torch.Tensor]):
357
original_image_sizes = [
358
(img.shape[-1], img.shape[-2]) for img in images
361
images_m = image_list.ImageList(
362
images, [(i.shape[-1], i.shape[-2]) for i in images]
364
proposals, _ = self.rpn(images_m, features)
365
detections, _ = self.roi_heads(
366
features, proposals, images_m.image_sizes
368
detections = self.transform.postprocess(
369
detections, images_m.image_sizes, original_image_sizes
373
images = torch.rand(2, 3, 100, 100)
374
features = _get_features(images)
375
images2 = torch.rand(2, 3, 150, 150)
376
test_features = _get_features(images2)
378
model = RoIHeadsModule()
380
model(images, features)
385
input_names=["input1", "input2", "input3", "input4", "input5", "input6"],
387
"input1": [0, 1, 2, 3],
388
"input2": [0, 1, 2, 3],
389
"input3": [0, 1, 2, 3],
390
"input4": [0, 1, 2, 3],
391
"input5": [0, 1, 2, 3],
392
"input6": [0, 1, 2, 3],
394
additional_test_inputs=[(images, features), (images2, test_features)],
398
@skipIfUnsupportedMinOpsetVersion(20)
399
def test_transformer_encoder(self):
400
class MyModule(torch.nn.Module):
401
def __init__(self, ninp, nhead, nhid, dropout, nlayers):
403
encoder_layers = nn.TransformerEncoderLayer(ninp, nhead, nhid, dropout)
404
self.transformer_encoder = nn.TransformerEncoder(
405
encoder_layers, nlayers
408
def forward(self, input):
409
return self.transformer_encoder(input)
411
x = torch.rand(10, 32, 512)
412
self.run_test(MyModule(512, 8, 2048, 0.0, 3), (x,), atol=1e-5)
415
def test_mobilenet_v3(self):
416
model = torchvision.models.quantization.mobilenet_v3_large(pretrained=False)
417
dummy_input = torch.randn(1, 3, 224, 224)
418
self.run_test(model, (dummy_input,))
420
@skipIfUnsupportedMinOpsetVersion(11)
422
def test_shufflenet_v2_dynamic_axes(self):
423
model = torchvision.models.shufflenet_v2_x0_5(weights=None)
424
dummy_input = torch.randn(1, 3, 224, 224, requires_grad=True)
425
test_inputs = torch.randn(3, 3, 224, 224, requires_grad=True)
429
additional_test_inputs=[(dummy_input,), (test_inputs,)],
430
input_names=["input_images"],
431
output_names=["outputs"],
433
"input_images": {0: "batch_size"},
434
"output": {0: "batch_size"},
441
if __name__ == "__main__":
442
common_utils.run_tests()