今天在调试yolov7模型转化加载问题的时候遇上了很多OpenCV加载模型的报错,由于标题长度限制的问题没有办法完全展示,这里将其完整贴出来。
[ERROR:0] global D:\opencv-python\opencv\modules\dnn\src\onnx\onnx_importer.cpp (720) cv::dnn::dnn4_v20211004::ONNXImporter::handleNode DNN/ONNX: ERROR during processing node with 5 inputs and 1 outputs: [NonMaxSuppression]:(onnx::Gather_384)
cv2.error: OpenCV(4.5.4) D:\opencv-python\opencv\modules\dnn\src\onnx\onnx_importer.cpp:739: error: (-2:Unspecified error) in function 'cv::dnn::dnn4_v20211004::ONNXImporter::handleNode'
cv2.error: OpenCV(4.5.4) D:\opencv-python\opencv\modules\dnn\src\onnx\onnx_importer.cpp:739: error: (-2:Unspecified error) in function 'cv::dnn::dnn4_v20211004::ONNXImporter::handleNode'
> Node [NonMaxSuppression]:(onnx::Gather_384) parse error: OpenCV(4.5.4) D:\opencv-python\opencv\modules\dnn\src\dnn.cpp:615: error: (-2:Unspecified error) Can't create layer "onnx::Gather_384" of type "NonMaxSuppression" in function 'cv::dnn::dnn4_v20211004::LayerData::getLayerInstance'
可以说OpenCV加载转化好的模型必然会遇上很多坑,不管是版本的坑还是OpenCV本身的坑,总之很难说会一帆风顺。
排查的有点懵,实在是没有头绪了,这时候我想到一个办法就是拿自己的模型跟官方的模型来一一比对,一个节点一个节点的对比,终于在最后发现了问题所在。
【官方模型】
【自己的模型】
看到这里我在想差异这么大的吗?不应该的啊,都是同一套代码构建出来的模型啊,于是我开始向上溯源,果然发现了问题。
在我红框的位置处,官方的模型在这里就结束掉了,而我的后面还有一大串,通过打印调试二者的tensor shape,我猜想可能是在模型export过程中参数的设置出现了问题,于是乎我尝试验证了基本所有不确定的参数,果然找到了问题。
为了方便大家理解我这里给出来我原始的转化操作命令:
python export.py --weights best.pt --grid --end2end --simplify --topk-all 100 --iou-thres 0.65 --conf-thres 0.35 --img-size 640 640 --max-wh 640
这是之后的命令:
python38 export.py --weights best.pt --grid --simplify --topk-all 100 --iou-thres 0.65 --conf-thres 0.35 --img-size 640 640 --max-wh 640
看到区别了吧,实则就是end2end这个参数导致的,修改之后我的模型如下:
因为我这里做的是但类别的检测,所以最后的输出是:1x25200x6,而官方的是:1x25200x85.