当前位置: 首页 > news >正文

【工程】mmcls中EfficientNet网络转onnx格式问题记录

转换问题

针对mmcls中EfficientNet网络转onnx文件,出现如下错误:
1)首先,使用mmcls项目中提供tools/deployment/pytorch2onnx.py脚本进行转换,命令如下:

python tools/deployment/pytorch2onnx.py your/config/path  --checkpoint your/model/path --verify --show --output-file save/onnx/path --shape 224 224

2)虽然转换为onnx文件成功,但加载并检查该onnx文件时如下报错:

onnxruntime.capi.onnxruntime_pybind11_state.Fail: [ONNXRuntimeError] : 1 : FAIL : Node (Concat_42) Op (Concat) [ShapeInferenceError] All inputs to Concat must have same rank. Input 4 has rank 1 != 2

错误信息大概意思是:对于concat算子输入的多个张量元素的维度不一致。

Tip: 所使用的mmcls是1.0版本之前,目前官方项目名更改为mmpretrain

定位问题

对于onnx转换不适配问题,需要定位清楚是哪个算子导致的错误。
1.首先使用Netron软件打开onnx文件模型,可以查看网络中各节点连接和节点信息;
2.根据错误提示中说的Node (Concat_42) Op 节点信息,找到对应的节点,并对应到深度学习框架中的具体算子。
3.根据分析,是EfficientNet中的Conv2dAdaptivePadding算子转换产生的转换错误,具体分析如下:

  1. Conv2dAdaptivePadding算子定义
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    Conv2dAdaptivePadding算子含义:针对输入特征图的维度进行自适应padding,然后再进行卷积操作;如果卷积步长为1,需要输入特征图的维度与输入特征图维度一致;如果卷积步长为2,输出特征图的size是输入特征图的一半。
    对应的转换具体问题是:ONNX 导出不直接支持 Python 中的 math.ceil 操作;ONNX 中支持 torch.nn.functional.pad 和 torch.nn.functional.conv2d

自定义算子转onnx模型

对于这种算子不适配问题,解决思路是替换模型中相应的算子层。具体的思路:
1、重写该算子层,使其能够适配;
2、遍历模型中各个子模块,找到待替换的算子层进行替换;
具体地:
1、重写Conv2dAdaptivePadding算子的forward逻辑,自定义算子:CustomConv2dAdaptivePadding,并修改forward逻辑。
1)正确处理 math.ceil
ONNX 导出不直接支持 Python 中的 math.ceil 操作。在 ONNX 中,你需要确保张量操作能够被支持。通常,可以使用张量上的 torch.ceil() 作为替代,因为 ONNX 支持张量操作,而不支持 Python 的内建函数如 math.ceil。这将使 output_h 和 output_w 的计算与 ONNX 导出兼容。
在这里插入图片描述
2)pad_h/pad_w的类型处理
在Conv2dAdaptivePadding 实现中,在 F.pad 函数调用时将计算结果传递给 pad 参数,导致产生浮点数。
原始的转换还存在错误:typeError: constant_pad_nd(): argument 'pad' must be tuple of ints, but found element of type float at pos 1
该错误通常表示在调用 constant_pad_nd 时,传递给 pad 参数的值不是预期的整数元组,而是包含浮点数的元组。因此需要确保将所有填充值转换为整数类型。
解决:
通过强制转换所有计算结果为整数来解决。以确保 pad_h 和 pad_w 变量是整数:
由于F.pad中处理的是int,所以需要将pad_h,pad_w转换为int.
在这里插入图片描述
2、替换带权重的Conv2dAdaptivePadding算子
将带权重的Conv2dAdaptivePadding算子替换为修改的CustomConv2dAdaptivePadding
具体地,遍历模型中的所有模块层,将带权重的Conv2dAdaptivePadding替换为可转的CustomConv2dAdaptivePadding.
代码如下:

for k, m in model.named_modules():if isinstance(m, Conv2dAdaptivePadding):# 获取层的属性in_channels = m.in_channelsout_channels = m.out_channelskernel_size = m.kernel_sizestride = m.stridepadding = m.paddingdilation = m.dilationgroups = m.groupsbias = m.bias is not None# 用自定义卷积层替换new_conv = CustomConv2dAdaptivePadding(in_channels, out_channels, kernel_size,stride, padding, dilation, groups, bias)new_conv.weight.data.copy_(m.weight.data)  # 复制权重if m.bias is not None:new_conv.bias.data.copy_(m.bias.data)  # 复制偏置# 将新层替换到模型中parent_module = modelfor part in k.split('.')[:-1]:parent_module = getattr(parent_module, part)setattr(parent_module, k.split('.')[-1], new_conv)

总结

在已训练的模型进行onnx文件格式转换时,如果遇到不支持的算子,可以采取的思路:首先定位转换出错的算子;然后对相应算子进行重写,确保其中的操作支持onnx转换;最后,将重写后的算子替换原模型中对应的算子。当然,也可以重写onnx算子,需根据个人对onnx掌握情况进行选择。


http://www.mrgr.cn/news/59983.html

相关文章:

  • Spring Boot Druid 数据库连接池入门
  • Redis集群配置
  • 一站式学习 Shell 脚本语法与编程技巧,踏出自动化的第一步
  • HTTP Content-Type
  • javascript实现aes算法(支持微信小程序)
  • Ubuntu服务器搭建Tailscale Derp节点
  • 最近阶段的状态的复盘
  • 32位的ARMlinux的4字节变量原子访问问题
  • Vue2自定义指令及插槽
  • MySQL主主SQL线程异常修复大作战,一失足成千古恨啊!
  • 四期书生大模型实战营(【入门岛】- 第4关 | 玩转HF/魔搭/魔乐社区)
  • P11232 [CSP-S 2024] 超速检测(民间数据)
  • 【热门主题】000010 深入 Vue.js 组件开发
  • 【办公类-53-14】2024年9月周计划系列优化(5天、6天、7天模版)
  • vue3 debounce 作用:函数会从其被调用时延迟执行到调用结束的这段时间内,如果该函数被再次调用,则重新计算时间。
  • 使用 BERT 和逻辑回归进行文本分类及示例验证
  • 在数据库访问中,使用localhost、127.0.0.1和IP地址有什么差异
  • Java 中的 队列(Queue)与双端队列(Deque)
  • Host Key Verification Failed
  • 软件测试学习总结
  • 【Python】为Pandas加速(适合Pandas中级开发者)
  • PG数据库之数据类型入门
  • 【mysql】什么是当前读
  • JMeter 接口和性能测试常用函数最全解析!
  • ICP之点云特征计算
  • 只需要写几行 SQL,这个网站就搭好了?