Pytorch -> [Onnx -> tensorflow] -> tflite 生成大量冗余的 conv2d 运算符

Pytorch -> [Onnx -> tensorflow] -> tflite generates lots of redundant conv2d operators

我正在将 efficientnet 从 onnx 转换为 tensorflow,以便进一步转换为 tflite。从 onnx 到 tensorflow 的转换产生奇怪的结果

Onnx 有 1 个 conv2d 运算符

在转换为 tensorflow 和后来的 tflite 模型后,我得到了这堆 convs(所有这些都不能放在图片中,总共有 32 个,作为 onnx 中的内核数)

我怀疑问题出在 onnx-tf 转换上。似乎 conv2d 输出被分成 32 个单独的输出,然后它们在单独的 conv2d 运算符上单独处理,然后连接在一起。

他们的 github 上有 2 个相关问题。

首先修复了深度转换,但不能应用于我的情况

https://github.com/onnx/onnx-tensorflow/issues/473

https://github.com/onnx/onnx-tensorflow/issues/754

查看 https://github.com/onnx/onnx-tensorflow/blob/master/onnx_tf/handlers/backend/conv_mixin.py 的来源 他们确实拆分输出产生单独的卷积,然后将它们连接起来。

是否可以避免拆分为多个卷积?

经过一些额外的挖掘,我发现了以下内容

  • 我的 convs 是深度的(conv2d 在 pytorch 和 onnx 中是深度的,如果它有组参数 > 1)
  • 这一堆转换是一种低效的深度转换方式。为了有效地做到这一点,我们需要使用 tf.depthwiseconv

要在 onnx-tf v1.7.0 中修复此问题,您应该对此处发布的 onnx-tf 源代码应用补丁 https://github.com/onnx/onnx-tensorflow/issues/473#issuecomment-533522917

在当前的 master 分支中,尝试通过检测深度转换来解决问题,但它目前包含一个错误。要修复 master 分支中的错误,您可以应用我在此处发布的修复 https://github.com/onnx/onnx-tensorflow/issues/754#issuecomment-801775203 我使用了 master 分支和上面的修复程序,生成了一个带有 depthwise conv

的小图

我还用上面的修复程序创建了一个分支,所以你可以这样做

pip install git+https://github.com/Vozf/onnx-tensorflow

应用它而不是自己打补丁

看来这个问题应该会在下一个主要版本(可能是 1.8.0)中得到解决

还可以考虑使用 https://github.com/nerox8664/onnx2keras,因为它支持深度卷积,而且还支持允许删除所有转置操作的完整 nhwc 转换。