1、export of nn.interpolate #pytroch Unsample 相当于 resize,nearst,不是反卷积实现的操作,下面是讨论
https://github.com/pytorch/pytorch/issues/34718
2、
该博客下的
pytorch1.0,1.0.1-- onnx --tensorRT5.0.2.6的upsample_nearest2d BUG
https://blog.csdn.net/xxradon/article/details/88803324
https://github.com/NVIDIA/retinanet-examples所做的那样,代码中加入upsample_nearest2d的重载
3、 pytorch转onnx问题讨论
Fail to export the model in PyTorch
https://github.com/onnx/tutorials/blob/master/tutorials/PytorchAddExportSupport.md#fail-to-export-the-model-in-pytorch
但是最终解决方式
pytorch 1.3.1 1.4 等高版本
opset_version=11改动 10
constant,节点就没了
import torch
import torch.nn as nn
import torch.nn.functional as F
import os
class TestModel(nn.Module):
def __init__(self):
super(TestModel, self).__init__()
def forward(self, x):
x = F.interpolate(x, (256, 256), mode = 'bilinear')
return x
torch_model = TestModel()
dummy_input = torch.randn((1, 3, 256, 256))
torch_out = torch.onnx.export(torch_model,
dummy_input,
'test_model.onnx',
verbose=True,
opset_version=11,)
很明显,这个Constant就是多余的输入节点。
解决:目前没有好的解决办法 设置opset_version=10,使用nearest上采样可以运行
更新:在https://github.com/NVIDIA/TensorRT/issues/284,开发者回复说 TensorRT only supports assymetric resizing at the moment,也就是说nearest是可以用的,但是bilinear上采样还没有得到TensorRT的支持。
F.interpolate(x, size=(128, 128), mode=‘bilinear’, align_corners=False)操作。
原因
目前ONNX2TRT的转换过程中,貌似不支持F.interpolate的bilinear模式,只支持linear和nearest。
以上还是没有height_scale 参数,所以按照这里的方式修改,重载这一个函数
pytorch 用插值上采样,导出的 onnx 模型无法转成 TRT model,报错:Attribute not found: height_scale
https://www.jianshu.com/p/dcd450aa2e41
修改如下,成功导出
# onnx 没有height_scale,这里重载这个函数,修改返回值,存在这个值
import torch.onnx.symbolic_opset10 as onnx_symbolic
@torch.onnx.symbolic_opset10.parse_args('v', 'is') #不加报错
def upsample_nearest2d(g, input, output_size):
height_scale = float(output_size[-2]) / input.type().sizes()[-2]
width_scale = float(output_size[-1]) / input.type().sizes()[-1]
print("****************")
print(output_size)
return g.op("Upsample", input,
scales_f=(1, 1, height_scale, width_scale),
mode_s="nearest")
onnx_symbolic.upsample_nearest2d = upsample_nearest2d
但是onnxruntime使用报错
Context: Bad node spec: input: “085_convolutional_lrelu” output: “086_upsample” name: “086_upsample” op_type: “Upsample” attribute
{ name: “mode” s: “nearest” type: STRING } attribute { name: “scales” floats: 1 floats: 1 floats: 2 floats: 2 type: FLOATS }
————————————————
版权声明:本文为CSDN博主「Ubuntu_ximi」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42279044/article/details/102819670
pip install onnx==1.4.1
onnx更新太快了,在官方1.5.1以后就取消了upsample层
所以1.6 报错,
但是我安装1.4.1还是报告一样的错误,所以继续降低版本,也没有用,还是报错误如此,
4、最推荐转换知识总结,
PyTorch2ONNX2TensorRT 踩坑日志
https://blog.csdn.net/github_28260175/article/details/103436020
ONNX并不支持AdaptivePooling操作,该操作仅存于PyTorch中。
截取
PyTorch2ONNX、ONNX2TRT到底哪里出了问题?
下面是遇到无法解决的问题后该找谁问的一个思路:
PyTorch2ONNX是调用的PyTorch内部的转换脚本,所以PyTorch2ONNX出了问题,需要去PyTorch那里的issue寻找解决办法;ONNX2TRT是使用ONNX自己写的转换脚本onnx-tensorrt,同理如果ONNX2TRT出了问题,就需要到它的那里找解决办法;在产生好TRT模型后,使用TRT模型进行推理出问题了,那就要去TRT那里问了,有GitHub和官方论坛可以使用。
那怎么让报错暴露出来呢,下面是一些办法。
解决方法
按下列方法多半能找到问题所在。
-
PyTorch2ONNX
更新PyTorch到最新版,一般最新版中ONNX的OP支持应该会更多;
按下列代码将日志等级调到最高,逐一分析。
import torch
torch.onnx.export(..., verbose=True, ...)
- 检测ONNX模型
下载Netron可视化自己的ONNX模型,分析是否与PyTorch模型一致,或者与自己想造的模型一致。多看看resize、shape、permute操作,ONNX对这些需要对tensor切片的操作不是很支持。
-
ONNX2TRT
更新onnx-tensorrt库,也就是libnvonnxparser.so。下面贴一段TRT的安装步骤:
安装TRT.
编译onnx-tensorrt.
将libnvonnxparser.so移到TRT的lib文件夹中.
按下列代码将日志等级调到最高,逐一分析。
最终解决办法
放弃ONNX2TRT吧,PyTorch与ONNX与TRT的版本难以互相支持,在版本的迭代中任意节点不支持了,整个链路就会断掉,另外TRT是闭源的项目,你完全不知道ONNX2TRT的过程中出了哪些问题,就算有堆栈信息,也不可能根据信息去trace它的错误。所以,直接使用TRT提供的api直接构建网络,是最复杂、也是最简单直接的方法。
Pytorch 2 TRT python API
使用TRT提供的python接口,构建网络,整个流程十分简单,大家可以看看TRT提供的示例<TRT_root>/samples/python/network_api_pytorch_mnist/sample.py,与之对照的是<TRT_root>/samples/python/network_api_pytorch_mnist/model.py:
————————————————
版权声明:本文为CSDN博主「麦克斯韦恶魔」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/github_28260175/article/details/103436020
5 pytorch 转换onnx,如果
test optimized_model_str = C.optimize(model_str, passes) IndexError: _Map_base::at
加,keep_initializers_as_inputs=True
torch_out = torch.onnx._export(net, inputs, output_onnx, export_params=True,\
# verbose=False,input_names=input_names, output_names=output_names,opset_version=9, keep_initializers_as_inputs=True)