c++推理结果与python推理结果不一致问题
博主您好,我最近遇到一个问题想请教一下,我在训练完模型后使用官方的predict脚本预测能得到比较满意的分割结果,但是在转换onnx模型后使用该项目的c++代码推理,同一张图片,c++未检测到目标,输出的结果也为空白,这可能是什么原因造成的(如图,c++推理未检测出牙齿区域,但是python可以检测出并进行分割)
看旁边黄色的好像没问题,你要不多运行一下看下是不是mask颜色的问题?
看旁边黄色的好像没问题,你要不多运行一下看下是不是mask颜色的问题?
大佬你好,感谢回复,我运行了几次查看结果,中间牙齿那部分区域确实没有识别出来,目前出现的情况是我在同时预测多张图片时,只有几张图片会出现上述这种情况,其他的都很正常,不知道这是python转c++造成的精度损失问题还是onnx模型的问题
你可以试一试调整下nms阈值,我比较怀疑是因为nms阈值过低导致你左下角那个检测框数据覆盖掉大图的情况了。你可以看下不经过nms的检测框有没有你丢失的这部分区域(会有很多重叠,但是按理来说应该要有这个区域的检测框才对)。
大佬您好:
我测试了很多例子,发现只有部分图片会出现上述情况,如图:用python加载训练的pt推理,牙齿、牙龈两个目标都正常识别,用python加载onnx模型,牙齿、牙龈两个目标也都正常识别(说明onnx文件没有问题),使用c++加载onnx模型时,只识别了牙龈一个目标,漏掉了牙齿目标,说明是c++推理过程中某一步与python不一致(python用的predict.py)导致的,我试过您写的yolov5和yolov8两个框架都有这样的问题,查阅资料说是数据预处理pt模型resize时的padding方式是不同的(链接:https://blog.csdn.net/kao_lengmian/article/details/126668561),不知道大佬清楚不,这个需要在c++中怎么修改数据预处理过程呢
- pt的resize规则是动态的,也就是他的padding是32的倍数。举个例子来说,比如你一张1280x640的图片,输入为640的情况下,他最终输入到模型中推理的大小是640x320,而不是padding为640x640输入,
- cpp下面,LetterBox中的auto设置为true即可,但是这个会影响性能,除非你能保证你每张图片经过改处理之后大小都一致,否者一直在变性能下降的很厉害,或者你可以将onnx导出为dynamic,然后根据输入图片实时padding到32的整数倍看看。
- 另外,我说的nms阈值你尝试过了吗?如果可以,你将pt模型和图片给我我看下有什么区别。
我把pt模型和图片发您一下吧,感谢帮我看看,qq:1404561326,先谢谢大佬
大佬是否方便留个联系方式,请教一下,万分感谢!!!
直接传个云盘吧,qq群里喷策划7天还没放出来呢
哈哈,好的,https://drive.google.com/file/d/1X0UMYUuIIy4UqjrO8PaCd_A4pjYOSCKM/view?usp=sharing
share权限不对,无法访问
我更改了权限,大佬再试下
你可以试一试调整下nms阈值,我比较怀疑是因为nms阈值过低导致你左下角那个检测框数据覆盖掉大图的情况了。你可以看下不经过nms的检测框有没有你丢失的这部分区域(会有很多重叠,但是按理来说应该要有这个区域的检测框才对)。
实际上,你只需要按照这个调整一下,比如你给我的这些图片,将nms调整到0.6就可以了。并不是resize或者padding策略不一样,只是nms里面计算iou的方式不一样导致的,或者你可以试一下自己实现一下opencv的cv::dnn::NMSBoxes这个函数,然后将其中的IoU换成你运行python源码的时候对于的IoU方式 _nmsThreshold
好的,感谢大佬,我调整了_nmsThreshold的值后确实可以正确识别了,太感谢啦
大佬您好,再请教一下问题哈: 我又测试了大量数据,增大了_nmsThreshold的值(从0.45到0.8)确实可以检测到之前未检测到的目标,但是还是有少部分图片会漏掉目标情况,这个时候再增大_nmsThreshold的值也没效果了,但是python中的_nmsThreshold就是0.45却能检测到所有目标,这是因为c++中nms计算过程和python中nms计算过程不一致导致的嘛?是否可以将c++中nms计算过程和python保持完全一致?还是有什么原因导致两者无法保持一致嘛,纯小白,真心请教大佬!
- 我上面不是跟你说了吗,你可以自己实现nms部分,然后获得和python一样的功能,这个你找一下我记得是又别人实现过了。
- 除开这个之外,你得对比下python下面的onnx和cpp的onnx结果区别,你这少部分漏掉的python下面运行onnx是又结果还是漏掉?
- 至于resize部分,你可以试试看下c++中resize中不同的方法的区别,这个对比下python下面的opencv方法即可。python下面好像resize放大和resize缩小是两个参数来着,我嫌弃麻烦,只用了一种,就目前而言我没有出现你说的这么极限的情况。
- 如果真的上面两三点改完之后你还是会出现这种问题,你应该去研究一下网络和数据集的改进,也就是你的模型泛化能力不足导致细微的结果不一样。
- 如果如果最终真的都不行,并且这个模型对你很重要,我比较建议你换libtorch,这个就是python的c++版本,你只要按照python下面的功能一样实现的话,推理结果是一摸一样的。
好的大佬,我目前的情况是python加载onnx可以检测到所有目标,c++加载onnx时只有少部分图片会漏掉一些目标(调整了_nmsThreshold的值也检测不出来),应该可以判断是c++中nms实现过程和python的不一致,我现在先尝试着改成一致,再看看结果吧,感谢大佬指点