TensorRT转换onnx的Transpose算子遇到的奇怪问题

近来把一个模型导出为onnx并用onnx simplifier化简后转换为TensorRT engine遇到非常奇怪的问题,在我们的网络中有多个检测头时,转换出来的engine的推理效果是正常的,当网络中只有一个检测头时,转换出来的engine的推理效果奇差,类别得分经sigmoid()计算出来的很多很大的值,导致输出上百万个3D box,这明显不正常。

开始以为3D box的C++后处理解码部分有问题,调查折腾了不少时间发现根本没什么大问题,然后想起模型只有一个检测头输出不正常,有多个头时检测头时反而正常,于是去仔细翻看模型网络的实现代码,也没发现什么不对的,很郁闷,想到把用于TensorRT生成engine的onnx可视化出来看有何差异,刚开始看也没发现什么特别的,感觉展示出来的结构都很正确没毛病啊:

那为何多个检测头就正常一个检测头就不行呢?再仔细看代码,发现heatmap这个分支的输出tensor在作permute(onnx里对应的是Transpose)后有这么一句有关:

      result['hm_preds'] =  torch.cat(hm_preds_list, dim=-1)

hm_preds_list是个list,当有多个head时,会有多个hm_preds加入到这个[ ]里,只有一个检测头时就只有一个hm_preds加入这个[ ]里,很显然,当hm_preds_list里只有一个hm_preds时,torch.cat()不会作实质操作,只是依据hm_preds_list里的数据直接输出tensor而已,那我强制只有一个检测头时也作和有多个检测头时一样的算子运算会如何?于是修改代码当网络只配置有一个检测头时,将这个hm_preds tensor自己和自己强制来个Concat,也就是相当于torch.cat([hm_preds, hm_preds], dim=-1),然后为保持输出tensort的维度不变进行了切片,得到的网络结果是这样:

然后导出onnx并用onnx simplifier化简,生成TensorRT engine后推理结果就正常了!

那为何强制加了Concat后输出结果就正常了呢?再回头看从pytorch导出onnx和onnx化简全过程中网络结构上的变化,发现上面有一个检测头和有多个检测头时的网络的onnx图,发现,只有一个检测头时,像上面提到,因为torch.cat()没有实质操作,pytorch导出onnx时虽然在onnx生成了Concat算子节点,但是后面用onnx simplifier化简时,它会把这个Concat算子节点删掉,Transpose算子的输出就直接作为网络的hm_preds输出了,而有多个检测头时,torch.cat()会有实质拼接操作,Concat算子自然被onnx simplifier保留了,所以生成的TensorRT engine的推理结果正常!

于是我修改脚本,当网络只有一个检测头时,在调用onnx simplifier化简网络后,在Transpose算子节点后和网络的输出节点hm_preds之间强制增加Concat算子节点(注意指定attrs={"axis":-1})

然后再生成TensorRT engine,然后用这个engine推理就一切正常了!

再回头仔细想想这个问题的最终原因,当只有一个检测头时,TensorRT在对hm_preds tensor 作Transpose后因为后续没有其他算子了,没有触发输出Transpose后的tensor值而是把原始tensor值输出了?或者因为Transpose输出的hm_preds tensor在加入hm_preds_list后,因为hm_preds_list不是tensor,TensorRT把它丢弃了,直接用的Transpose处理前的tensor值?只能等后面哪天有时间再实验找找根本原因。

附上增加Concat节点的相关代码(:

  hm_node = graph.outputs[1]check_node = hm_node.inputs[0]if check_node.op == 'Transpose':  # only one head, no concat, need to add it forciblytranspose_out = [gs.Variable("transpose_out", shape=hm_node.shape, dtype=hm_node.dtype)]check_node.outputs = transpose_outgraph.layer(name="Concat_199", op= 'Concat', inputs=transpose_out, outputs=[hm_node], attrs={"axis":-1})graph.cleanup().toposort()

我们修改onnx使用的NVIDIA的ONNX GraphSurgeon,它封装后用起来比较简单,感觉比直接使用onnx的API修改网络容易得多,具体文档和examples可参见:

ONNX GraphSurgeonicon-default.png?t=N7T8https://docs.nvidia.com/deeplearning/tensorrt/onnx-graphsurgeon/docs/index.html

 Examplesicon-default.png?t=N7T8https://github.com/NVIDIA/TensorRT/tree/main/tools/onnx-graphsurgeon/examples

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/475487.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

利用HTTP隧道在Linux系统上实现安全远程访问

在一个阳光明媚的下午,Linux小侠坐在电脑前,捋了捋他那一头乌黑亮丽的代码发,开始琢磨如何通过HTTP隧道实现安全远程访问。毕竟,在这个信息爆炸的时代,远程访问的安全性可是每个技术宅都绕不开的话题。 Linux小侠知道…

K8s进阶之路-有状态服务/守护进程/任务:

StatefulSet:专门针对有状态服务进行部署的一个控制器 (长连接) 实现:通过headless service网络固定、数据不能丢失、顺序得到保障, (配置:Headless Service: 对于 有状态 服务的DNS管理&#x…

泛域名SSL证书是什么?泛域名SSL证书价格多少钱?

SSL证书是一种数字证书产品,可保护网站数据传输安全及服务器身份可信。通常根据保护域名数量及域名类型的不同,SSL证书可以分为单域名SSL证书、多域名SSL证书、泛域名SSL证书、多域名和泛域名混合SSL证书。那么泛域名SSL证书是什么?泛域名SSL…

Unity求物体关于平面镜像对称后坐标以及旋转

前言:如题,我在已知一个平面L和物体A,我希望得到镜像后的物体B的位置和旋转。 效果: 推导: 首先我们需要知道物体的对称坐标A,我们现在能已知A坐标以及平面L的法线,如果我们能得到B的坐标&…

Maven - Plugins报错的正确解决之道

背景: 正确解决之道: 在自己本地Maven的安装目录中找到自己的仓库地址目录:直接搜索自己报错的插件文件,把它们删除,如图: 接着回到IDEA点击Maven刷新按钮重新加载即可:已解决 反例&#xff1…

第13章 基于Java Swing的图书管理系统

13.1 需求分析 在当今社会,随着信息技术的不断发展,信息管理系统已经进入到了人类社会的各个领域,人们对于信息技术的掌握也越来越迅速。在图书管理的过程中也引入图书管理体系,图书管理系统将大大节省人力、物力、时间、金钱等资…

根据Ruoyi做二开

Ruoyi二开 前言菜单代码生成新建微服务网关添加微服务的路由 vue页面和对应的js文件js中方法的url和controller中方法的url总结 前言 之前写过一篇文章,若依微服务版本搭建,超详细,就介绍了怎么搭建若依微服务版本,我们使用若依就…

RocketMQ订阅关系不一致和不能消费时如何排查?

订阅关系不一致 调整任意一个实例的订阅关系和另一个保持一致 消费者不能消费消息 它是最常见的问题之一,也是每个消息队列服务都会遇到的问题 1.确认哪个消息未消费。在这时消费者至少需要手机消息id、消息key、消息发送时间段三者之一 2.确认消息是否发送成功…

【plt.bar绘制条形图】:从入门到精通,只需一篇文章!【Matplotlib】

【📊plt.bar绘制条形图】:从入门到精通,只需一篇文章!【Matplotlib】 利用Matplotlib进行数据可视化示例 🌵文章目录🌵 🔍 一、初识plt.bar:条形图的基本概念💡 二、plt.…

Sqoop 入门基础

简介 Sqoop(SQL to Hadoop)是一个开源工具,用于在关系型数据库和Hadoop之间传输数据。它提供了一种快速高效的方式,将数据从关系型数据库导入到Hadoop集群进行分析,并支持将Hadoop集群中的数据导出到关系型数据库中。本…

dm_control 翻译: Software and Tasks for Continuous Control

dm_control: Software and Tasks for Continuous Control dm_control:连续控制软件及任务集 文章目录 dm_control: Software and Tasks for Continuous Controldm_control:连续控制软件及任务集Abstract1 Introduction1 引言1.1 Software for research1…

黑猫带你学NandFlash第2篇:NandFlash部分相关名词释义

1 前言 1.1 声明 本文依据ONFI5.1、网络资料及个人工作经验整理而成,如有错误请留言。 文章为付费内容,已加入原创侵权保护,禁止私自转载及抄袭。 文章所在专栏:《黑猫带你学:NandFlash详解》 1.2 本文背景 本文关…