关于cv2.dnn.readNetFromONNX(path)就报ERROR during processing node with 3 inputs and 1 outputs的解决过程【独家发布】

问题是什么:

如图,对vgg16使用opencv的dnn模块进行推理时出现错误。

关于cv2.dnn.readNetFromONNX(path)就报ERROR during processing node with 3 inputs and 1 outputs的解决过程【独家发布】
错误的详细日志为:

[ERROR:0@0.804] global D:\a\opencv-python\opencv-python\opencv\modules\dnn\src\onnx\onnx_importer.cpp (1021) cv::dnn::dnn4_v20220524::ONNXImporter::handleNode DNN/ONNX: ERROR during processing node with 3 inputs and 1 outputs: [Conv]:(onnx_node!StatefulPartitionedCall/vgg16/conv_bn_two_relu_pool1/conv_bn_one_relu/conv2d/Conv2D) from domain='ai.onnx'
Traceback (most recent call last):
  File "D:/DLAI/qwenAILearn/StudyDNN/trainOnnx/test2.py", line 6, in <module>
    net = cv2.dnn.readNetFromONNX(path)  # &#x52A0;&#x8F7D;&#x8BAD;&#x7EC3;&#x597D;&#x7684;&#x8BC6;&#x522B;&#x6A21;&#x578B;
cv2.error: OpenCV(4.6.0) D:\a\opencv-python\opencv-python\opencv\modules\dnn\src\onnx\onnx_importer.cpp:1040: error: (-2:Unspecified error) in function 'cv::dnn::dnn4_v20220524::ONNXImporter::handleNode'
> Node [Conv@ai.onnx]:(onnx_node!StatefulPartitionedCall/vgg16/conv_bn_two_relu_pool1/conv_bn_one_relu/conv2d/Conv2D) parse error: OpenCV(4.6.0) D:\a\opencv-python\opencv-python\opencv\modules\dnn\src\layers\convolution_layer.cpp:405: error: (-2:Unspecified error) Number of input channels should be multiple of 3 but got 0 in function 'cv::dnn::ConvolutionLayerImpl::getMemoryShapes'
>
</module>

错误的关键字是Number of input channels should be multiple of 3 but got 0 in function,通过搜索会发现大量文章,比如这一遍https://github.com/opencv/opencv/issues/20866 并没有给出解决方案

关于cv2.dnn.readNetFromONNX(path)就报ERROR during processing node with 3 inputs and 1 outputs的解决过程【独家发布】

还有这一篇,给出了解决方案 DNN/ONNX: outputs registration regression, feature request for new version of Clip operator · Issue #21698 · opencv/opencv · GitHub reshape一下维度,但是这个解决方案,是解决在net.setInput时出的问题,而本问题是在cv2.dnn.readNetFromONNX(path)就出现加载不了的问题,其实质是不一样的。

关于cv2.dnn.readNetFromONNX(path)就报ERROR during processing node with 3 inputs and 1 outputs的解决过程【独家发布】

其实网上搜索了很多,都没有给出解决方案。

那么为什么要会出现这个问题呢,这其实跟自已实现CNN的方法有一点关系,如下图这样来实现转换成onnx时就没有问题.

关于cv2.dnn.readNetFromONNX(path)就报ERROR during processing node with 3 inputs and 1 outputs的解决过程【独家发布】
&#x8BAD;&#x7EC3;&#x540E;&#x8F6C;&#x6362;&#x6210;onnx
path = "D:\\DLAI\\qwenAILearn\\StudyDNN\\TrainExample\\weights\\"
command = """python -m tf2onnx.convert  --saved-model  "{}vgg16"  --opset 12   --output {}vgg16.onnx """.format(path,path)
os.system(command)

使用opencv预测

关于cv2.dnn.readNetFromONNX(path)就报ERROR during processing node with 3 inputs and 1 outputs的解决过程【独家发布】

然后我换了一种实现方式,对conv进行了一些封装,如下代码:

关于cv2.dnn.readNetFromONNX(path)就报ERROR during processing node with 3 inputs and 1 outputs的解决过程【独家发布】

按上面的方法转换成vgg16_model.onnx,然后使用相同的推理代码去预测就会出现

onnx_importer.cpp (1021) cv::dnn::dnn4_v20220524::ONNXImporter::handleNode DNN/ONNX: ERROR during processing node with 3 inputs and 1 outputs 的错误。

因为我有相同的模型,不同推理出现不同结果的问题,所以我们可以使用Netron进行查看两个模型的不同点,如图:

关于cv2.dnn.readNetFromONNX(path)就报ERROR during processing node with 3 inputs and 1 outputs的解决过程【独家发布】

从上图可以看到能够进行推理的是左边的,有一个维度是unk_80,224,224,3,而右边不行的是unk_259,unk_260,unk_261,unk_262。结合上面的提示,猜应该是输入维度的问题。

经查询资料可知,opencv dnn并不支持动态尺寸输入,参考:https://github.com/opencv/opencv/issues/19347

关于cv2.dnn.readNetFromONNX(path)就报ERROR during processing node with 3 inputs and 1 outputs的解决过程【独家发布】

所以,我们的解决办法,就是想办法将onnx转换成指定的input_size,这个时候通过查询获知以下链接 Make dynamic input shape fixed – onnxruntime 给出了转换的命令,指定输入的维度

python -m onnxruntime.tools.make_dynamic_shape_fixed --input_name "input_1" --input_shape 1,224,224,3 "D:\DLAI\qwenAILearn\StudyDNN\TrainExample\weights\vgg16_model_3.onnx" "D:\DLAI\qwenAILearn\StudyDNN\TrainExample\weights\vgg16_model_3_back.onnx"

转换后的onnx内容如下。

关于cv2.dnn.readNetFromONNX(path)就报ERROR during processing node with 3 inputs and 1 outputs的解决过程【独家发布】

转换后使用以下脚本来运行

关于cv2.dnn.readNetFromONNX(path)就报ERROR during processing node with 3 inputs and 1 outputs的解决过程【独家发布】

会发现输出的结果是[[0. 0. 0. 1. 0.]]是不正确的,但是这个时候已经不报cv::dnn::dnn4_v20220524::ONNXImporter::handleNode DNN/ONNX: ERROR during processing node with 3 inputs and 1 outputs 错误了。修改上面的问题,只需要加上归一化即可。

关于cv2.dnn.readNetFromONNX(path)就报ERROR during processing node with 3 inputs and 1 outputs的解决过程【独家发布】

如上,预测正确。

综上,当opencv在读onnx时cv2.dnn.readNetFromONNX(path)就报convolution_layer.cpp RROR during processing node with 3 inputs and 1 outputs 错误的时候,只需要使用onnxruntime.tools.make_dynamic_shape_fixed –input_name “input_1” –input_shape 1,224,224,3 改为指定尺寸输入即可解决。

Original: https://blog.csdn.net/womengdoushizhongguo/article/details/125576920
Author: 那美那美
Title: 关于cv2.dnn.readNetFromONNX(path)就报ERROR during processing node with 3 inputs and 1 outputs的解决过程【独家发布】

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/651195/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球