对象检测模型 (PyTorch) 到 ONNX:ONNX 推理的空输出

Posted

技术标签:

【中文标题】对象检测模型 (PyTorch) 到 ONNX:ONNX 推理的空输出【英文标题】:Object Detection Model (PyTorch) to ONNX:empty output by ONNX inference 【发布时间】:2020-07-05 21:07:00 【问题描述】:

我尝试将我的 PyTorch 对象检测模型 (Faster R-CNN) 转换为 ONNX。我有两个设置。第一个工作正常,但出于部署原因,我想使用第二个。不同之处在于我用于导出函数 torch.onnx.export() 的示例图像。

在第一个设置中,我使用真实图像作为 ONNX 导出的输入。但是在官方tutorial 中,他们说我可以使用虚拟输入,它的大小应该与模型期望的输入相同。所以我创建了一个形状相同但具有随机值的张量。两种设置中的导出都正常工作。但在使用 ONNX 运行时进行推理后,第二个设置并没有提供预期的结果。代码和示例输出可以在下面找到。

设置 1

model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained = True)
...
checkpoint = torch.load(model_state_dict_path)
model.load_state_dict(checkpoint['model_state_dict'])
model.eval()

to_tensor = transforms.ToTensor()
img_rgb = Image.open(image_path_model).convert('RGB')
img_rgb = to_tensor(img_rgb)
img_rgb.unsqueeze_(0)    

torch.onnx.export(model, img_rgb, "detection.onnx", opset_version=11) 

我没有收到任何错误,并且导出工作正常。之后,我使用 ONNX 运行时运行模型,得到以下输出:

[array([[704.0696  , 535.19556 , 944.8986  , 786.1619  ],
         ...], dtype=float32),
array([2, 2, 2, 2, 2, 1, 1], dtype=int64),
array([0.9994363 , 0.9984769 , 0.99816966, ...], dtype=float32)]

输出与我预期的一样(边界框、对象类和概率)。

设置 2

model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained = True)
...
checkpoint = torch.load(model_state_dict_path)
model.load_state_dict(checkpoint['model_state_dict'])
model.eval()

img_rgb = torch.randn(1, 3, 1024, 1024)   

torch.onnx.export(model, img_rgb, "detection.onnx", opset_version=11) 

就像在设置 1 中一样,我没有收到任何错误,并且导出工作正常。之后,我使用 ONNX 运行时并使用与设置 1 中相同的图像运行模型,我得到以下输出:

[array([], shape=(0, 4), dtype=float32),
array([], dtype=int64),
array([], dtype=float32)]

它只是一个空数组。

第二个设置有什么问题?我是 ONNX 的新手。导出运行模型。我是否必须提供模型也可以识别对象的输入,因此具有随机值的虚拟输入不起作用?语句“只要类型和大小正确,这里的值可以是随机的。”仅对提供的​​教程有效?

【问题讨论】:

【参考方案1】:

在第二个设置中,您有一个随机张量,因此没有选择检测分数足够高的边界框。检查您是否有一个带有可检测对象的图像作为输入。

我假设关于随机输入的短语在大多数情况下(分类、分割等)是正确的,但检测模型使用 NonMaxSuppression 并抑制低分检测。

【讨论】:

但是 ONNX 为导出做了什么?我只是将随机输入用于函数 torch.onnx.export()。导出后,我使用 ONNX 运行时和真实图像运行我的 ONNX 模型,得到空输出。那么导出在内部对模型有什么作用呢? 抱歉,我没注意到你跑的是同一张图片。我不确定您的情况,但是如果您在与用于导出的图像不同的图像上运行您的第一个设置,输出会改变吗?

以上是关于对象检测模型 (PyTorch) 到 ONNX:ONNX 推理的空输出的主要内容,如果未能解决你的问题,请参考以下文章

来自 PyTorch 模型的 ONNX 对象,无需导出

模型推理教你简化 onnx upsample 算子

PyTorch模型导出到ONNX文件示例(LeNet-5)

无法将 PyTorch 模型导出到 ONNX

PyTorch 1.0 中文官方教程:使用ONNX将模型从PyTorch传输到Caffe2和移动端

yolov5pytorch模型导出为onnx模型