retinanet pytorch转换onnx Unsample 问题 pytorch转onnx踩坑日记

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和官方论坛可以使用。

那怎么让报错暴露出来呢,下面是一些办法。
解决方法

按下列方法多半能找到问题所在。

  1. PyTorch2ONNX

    更新PyTorch到最新版,一般最新版中ONNX的OP支持应该会更多;
    按下列代码将日志等级调到最高,逐一分析。

import torch
torch.onnx.export(..., verbose=True, ...)
  1. 检测ONNX模型

下载Netron可视化自己的ONNX模型,分析是否与PyTorch模型一致,或者与自己想造的模型一致。多看看resize、shape、permute操作,ONNX对这些需要对tensor切片的操作不是很支持。

  1. 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)
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值