Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

c++推理结果与python推理结果不一致问题 #28

Open
1404561326521 opened this issue Jan 29, 2024 · 16 comments
Open

c++推理结果与python推理结果不一致问题 #28

1404561326521 opened this issue Jan 29, 2024 · 16 comments

Comments

@1404561326521
Copy link

1404561326521 commented Jan 29, 2024

博主您好,我最近遇到一个问题想请教一下,我在训练完模型后使用官方的predict脚本预测能得到比较满意的分割结果,但是在转换onnx模型后使用该项目的c++代码推理,同一张图片,c++未检测到目标,输出的结果也为空白,这可能是什么原因造成的(如图,c++推理未检测出牙齿区域,但是python可以检测出并进行分割)
image

@UNeedCryDear
Copy link
Owner

看旁边黄色的好像没问题,你要不多运行一下看下是不是mask颜色的问题?

@1404561326521
Copy link
Author

看旁边黄色的好像没问题,你要不多运行一下看下是不是mask颜色的问题?

大佬你好,感谢回复,我运行了几次查看结果,中间牙齿那部分区域确实没有识别出来,目前出现的情况是我在同时预测多张图片时,只有几张图片会出现上述这种情况,其他的都很正常,不知道这是python转c++造成的精度损失问题还是onnx模型的问题

@UNeedCryDear
Copy link
Owner

你可以试一试调整下nms阈值,我比较怀疑是因为nms阈值过低导致你左下角那个检测框数据覆盖掉大图的情况了。你可以看下不经过nms的检测框有没有你丢失的这部分区域(会有很多重叠,但是按理来说应该要有这个区域的检测框才对)。

@1404561326521
Copy link
Author

大佬您好:
yolov5_pt2onnx

我测试了很多例子,发现只有部分图片会出现上述情况,如图:用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++中怎么修改数据预处理过程呢

@UNeedCryDear
Copy link
Owner

  1. pt的resize规则是动态的,也就是他的padding是32的倍数。举个例子来说,比如你一张1280x640的图片,输入为640的情况下,他最终输入到模型中推理的大小是640x320,而不是padding为640x640输入,
  2. cpp下面,LetterBox中的auto设置为true即可,但是这个会影响性能,除非你能保证你每张图片经过改处理之后大小都一致,否者一直在变性能下降的很厉害,或者你可以将onnx导出为dynamic,然后根据输入图片实时padding到32的整数倍看看。
  3. 另外,我说的nms阈值你尝试过了吗?如果可以,你将pt模型和图片给我我看下有什么区别。

@1404561326521
Copy link
Author

我把pt模型和图片发您一下吧,感谢帮我看看,qq:1404561326,先谢谢大佬

@1404561326521
Copy link
Author

大佬是否方便留个联系方式,请教一下,万分感谢!!!

@UNeedCryDear
Copy link
Owner

直接传个云盘吧,qq群里喷策划7天还没放出来呢

@1404561326521
Copy link
Author

@UNeedCryDear
Copy link
Owner

share权限不对,无法访问

@1404561326521
Copy link
Author

我更改了权限,大佬再试下

@UNeedCryDear
Copy link
Owner

你可以试一试调整下nms阈值,我比较怀疑是因为nms阈值过低导致你左下角那个检测框数据覆盖掉大图的情况了。你可以看下不经过nms的检测框有没有你丢失的这部分区域(会有很多重叠,但是按理来说应该要有这个区域的检测框才对)。

实际上,你只需要按照这个调整一下,比如你给我的这些图片,将nms调整到0.6就可以了。并不是resize或者padding策略不一样,只是nms里面计算iou的方式不一样导致的,或者你可以试一下自己实现一下opencv的cv::dnn::NMSBoxes这个函数,然后将其中的IoU换成你运行python源码的时候对于的IoU方式 _nmsThreshold

@1404561326521
Copy link
Author

好的,感谢大佬,我调整了_nmsThreshold的值后确实可以正确识别了,太感谢啦

@1404561326521
Copy link
Author

大佬您好,再请教一下问题哈:
我又测试了大量数据,增大了_nmsThreshold的值(从0.45到0.8)确实可以检测到之前未检测到的目标,但是还是有少部分图片会漏掉目标情况,这个时候再增大_nmsThreshold的值也没效果了,但是python中的_nmsThreshold就是0.45却能检测到所有目标,这是因为c++中nms计算过程和python中nms计算过程不一致导致的嘛?是否可以将c++中nms计算过程和python保持完全一致?还是有什么原因导致两者无法保持一致嘛,纯小白,真心请教大佬!

@UNeedCryDear
Copy link
Owner

  1. 我上面不是跟你说了吗,你可以自己实现nms部分,然后获得和python一样的功能,这个你找一下我记得是又别人实现过了。
  2. 除开这个之外,你得对比下python下面的onnx和cpp的onnx结果区别,你这少部分漏掉的python下面运行onnx是又结果还是漏掉?
  3. 至于resize部分,你可以试试看下c++中resize中不同的方法的区别,这个对比下python下面的opencv方法即可。python下面好像resize放大和resize缩小是两个参数来着,我嫌弃麻烦,只用了一种,就目前而言我没有出现你说的这么极限的情况。
  4. 如果真的上面两三点改完之后你还是会出现这种问题,你应该去研究一下网络和数据集的改进,也就是你的模型泛化能力不足导致细微的结果不一样。
  5. 如果如果最终真的都不行,并且这个模型对你很重要,我比较建议你换libtorch,这个就是python的c++版本,你只要按照python下面的功能一样实现的话,推理结果是一摸一样的。

@1404561326521
Copy link
Author

好的大佬,我目前的情况是python加载onnx可以检测到所有目标,c++加载onnx时只有少部分图片会漏掉一些目标(调整了_nmsThreshold的值也检测不出来),应该可以判断是c++中nms实现过程和python的不一致,我现在先尝试着改成一致,再看看结果吧,感谢大佬指点

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants