别急着调参数:YOLO检测效果不好时,应该按照什么顺序排查?
完成螺丝检测Demo的数据采集和标注后,我很快开始了第一次YOLO模型训练。
原本以为,只要数据集准备完成,模型训练结束后就能得到一个比较理想的检测结果。但实际测试时,我发现模型存在不少问题:有些螺丝没有被检测出来,有些相似型号会被错误分类,螺丝密集排列时还会出现漏检。
看到这些结果后,我最开始的想法是继续调参数:
- 增加训练轮数;
- 调整学习率;
- 更换更大的模型;
- 修改置信度阈值;
- 调整数据增强强度。
但经过几次训练后,模型效果并没有明显改善。
后来我才逐渐意识到,在工业视觉项目中,模型效果不好时,最先应该检查的通常不是参数,而是任务定义、图像质量、数据分布和标注质量。
如果前面的环节存在问题,后面无论怎样调参,都只能在错误的数据基础上反复训练。
因此,在后续项目中,我逐渐形成了一套比较固定的 YOLO 问题排查流程。
一、先不要笼统地说“模型效果不好”
很多人在模型训练结束后,会直接给出一个结论:
这个模型效果不太好。
但“效果不好”其实并不是一个具体的问题。
在开始排查之前,首先要明确模型到底出现了什么错误。通常可以分为以下几类。
1. 漏检
图像中明明存在目标,但模型没有检测出来。
例如,在螺丝计数项目中,一张图里实际有 20 颗螺丝,模型只检测出了 18 颗,那么缺少的两颗就是漏检。
漏检通常会直接影响数量统计结果。如果系统要求根据螺丝数量判断是否缺料,那么只漏掉一颗,就可能导致整次检测结果错误。
常见原因包括:
- 目标在图像中占用的像素太少;
- 螺丝之间发生遮挡或重叠;
- 金属表面反光,导致局部纹理丢失;
- 训练集中缺少类似场景;
- 标注数据中存在漏标;
- 置信度阈值设置过高;
- 输入图像缩放后,小目标特征被进一步压缩。
2. 误检
图像中本来不是目标的区域,却被模型识别成了目标。
例如:
- 夹具被识别成螺丝;
- 金属反光区域被识别成螺丝头;
- 背景中的圆形结构被模型错误检测;
- 两颗重叠螺丝之间的区域被重复识别。
误检通常和以下因素有关:
- 缺少纯背景图片;
- 背景纹理和目标过于相似;
- 标注框中包含了过多背景;
- 训练场景过于单一;
- 置信度阈值设置过低。
3. 类别混淆
模型能够检测出目标,但预测的类别不正确。
在多类别螺丝识别项目中,这类问题尤其常见。
不同型号的螺丝可能只在长度、螺帽形状、螺纹结构或者局部尺寸上存在细微差别。如果这些特征在图像中不够明显,模型就很容易将 A 型号识别成 B 型号。
类别混淆通常和以下因素有关:
- 类别之间外观差异太小;
- 类别定义本身不够清晰;
- 某些类别样本数量不足;
- 图像分辨率无法体现关键差异;
- 关键特征被遮挡;
- 类别标签存在错标。
4. 重复检测
同一个目标被多个检测框重复识别。
这类问题通常需要检查:
- NMS 阈值是否合理;
- 两个预测框的重叠程度;
- 目标是否出现严重遮挡;
- 后处理代码是否正确;
- 模型输出解析是否存在问题。
只有先判断问题属于哪一种,后续的排查才有方向。
二、第一步:确认任务定义是否合理
在检查数据和模型之前,还需要先确认一个容易被忽略的问题:
这个任务是否真的适合按照当前方式进行目标检测?
例如,在螺丝混料识别项目中,需要提前明确以下规则:
- 相互重叠的螺丝是否必须全部识别?
- 只露出一部分的螺丝是否计数?
- 位于图像边缘、目标不完整的螺丝是否参与判断?
- 两种外观非常相似的螺丝,能否仅通过当前拍摄角度区分?
- 混料判断依据是“出现其他类别”,还是“数量和类别同时满足条件”?
- 同一颗螺丝出现不同姿态时,是否仍然属于同一个类别?
如果这些规则没有提前统一,那么数据标注人员、算法人员和现场使用人员可能会对同一张图片得出不同结论。
例如,一颗螺丝只有一半位于图像中:
- 标注人员认为它不完整,因此没有标注;
- 算法人员认为只要出现就应该检测;
- 现场人员又希望它能够计入数量。
这种情况下,模型很难学到稳定的判断标准。
所以,工业项目首先要制定的不是训练参数,而是检测规则和标注规范。
三、第二步:检查原始图像质量
确认任务定义后,我通常会先检查原始图片,而不是马上打开训练曲线。
因为对于工业视觉项目来说,图像质量往往决定了模型能够达到的上限。
这个项目使用的是海海机器人 500 万像素工业相机。虽然相机分辨率并不低,但相机像素高,并不代表目标特征一定清晰。
真正需要关注的是:目标在最终图像中到底占了多少像素。
1. 检查目标尺寸
假设原始图像分辨率较高,但训练时统一缩放到 640×640。
如果某颗螺丝在原始图像中本身就很小,经过缩放后,可能只剩下几十个像素。此时螺纹、螺帽和长度差异都会被进一步压缩。
因此需要检查:
- 最小目标的宽度和高度是多少;
- 缩放到训练尺寸后还剩多少像素;
- 不同类别的关键差异能否保留;
- 是否需要提高训练输入尺寸;
- 是否需要调整相机工作距离或镜头焦距。
2. 检查对焦
工业相机安装完成后,需要确认整个检测区域是否都处于清晰范围内。
如果图像中心清晰,但边缘模糊,那么位于边缘的目标就更容易漏检。
需要重点观察:
- 螺丝边缘是否清晰;
- 螺纹结构是否能够分辨;
- 图像四角是否失焦;
- 不同高度的目标能否同时保持清晰;
- 相机或工件振动是否造成运动模糊。
3. 检查曝光和反光
螺丝属于金属零件,表面容易产生高亮反光。
如果局部区域过曝,原本应该存在的纹理和边缘可能会完全消失。模型看到的就不再是完整螺丝,而是一片接近纯白的区域。
除了过曝,还需要检查欠曝。当整体亮度过低时,深色螺丝和背景可能无法形成足够对比。
这时需要从成像端进行优化,例如:
- 调整曝光时间;
- 调整光源角度;
- 使用漫射光;
- 使用环形光或穹顶光;
- 调整相机增益;
- 必要时考虑偏振方案。
在工业视觉中,相机、镜头和光源并不是模型之外的独立部分,它们共同决定了模型最终拿到什么样的数据。
如果前端成像质量很差,后端模型通常很难完全补救。
四、第三步:检查标注质量
确认图像质量没有明显问题后,下一步是检查标注。
相比训练参数,标注质量对模型结果的影响通常更加直接。
1. 检查是否存在漏标
漏标指图像中存在目标,但对应目标没有标注框。
这是目标检测任务中非常严重的问题。
因为在训练过程中,没有被标注的真实目标会被模型当作背景。如果漏标数量较多,模型就会收到互相矛盾的训练信号:
- 在某些图片中,这种外观是螺丝;
- 在另一些图片中,相同外观却被当作背景。
最终模型很容易出现漏检。
对于密集排列的螺丝图片,漏标尤其常见。因为目标数量多、相互遮挡,人工标注时很容易遗漏其中一颗。
2. 检查是否存在错标
错标主要包括两种情况:
第一种是类别错误。
例如,A 型号螺丝被错误标注成 B 型号。对于本来就外观相似的类别,少量错标也可能明显增加类别混淆。
第二种是目标区域错误。
例如:
- 标注框只框住了螺丝头;
- 标注框没有包含完整螺丝;
- 标注框包含了相邻螺丝的一部分;
- 标注框偏离了真实目标。
3. 检查标注框是否统一
目标检测的标注框不一定要追求极端贴合,但必须保持规则一致。
不能在同一个数据集中出现以下情况:
- 有些框紧贴目标;
- 有些框包含大量背景;
- 有些框标完整螺丝;
- 有些框只标螺帽;
- 有些遮挡目标被标注;
- 有些相似遮挡目标又没有标注。
模型并不知道哪一种标注方式才是正确的,它只能从数据中寻找规律。
标注标准越混乱,模型学习难度越大。
4. 制定遮挡目标的标注规则
对于螺丝重叠场景,需要提前制定统一规则。
例如:
- 可见面积超过一定比例时进行标注;
- 严重遮挡且无法判断类别时不标注;
- 位于图像边缘但仍能确认类别时继续标注;
- 两颗螺丝相互重叠时分别标注;
- 无法区分类别的目标不强行标注为某一类。
具体规则可以根据项目要求调整,但必须保证整个数据集执行同一套标准。
五、第四步:检查数据集分布
标注没有明显问题后,还需要检查数据集的分布是否合理。
很多数据集看起来图片数量不少,但真正有效的信息非常有限。
例如,采集了 2000 张图片,但这些图片可能都是:
- 同一个背景;
- 同一种摆放方式;
- 同一个曝光参数;
- 同一个目标数量;
- 同一种光照状态;
- 相邻时间连续拍摄的高度相似图片。
这种数据集虽然数量多,但场景覆盖不足,模型很容易过拟合。
1. 检查类别是否均衡
假设一个数据集中:
- A 类螺丝有 5000 个;
- B 类螺丝有 3000 个;
- C 类螺丝只有 300 个。
那么 C 类通常更容易出现漏检和误分类。
需要分别统计每个类别的:
- 图片数量;
- 标注框数量;
- 单张图中的目标数量;
- 不同姿态数量;
- 遮挡样本数量;
- 反光样本数量;
- 密集排列样本数量。
不能只看总图片数量。
2. 检查困难样本是否足够
工业现场真正容易出问题的,通常不是标准样本,而是困难样本。
在螺丝检测中,困难样本主要包括:
- 螺丝相互重叠;
- 螺丝紧密排列;
- 螺丝位于图像边缘;
- 金属表面强反光;
- 局部阴影;
- 不同方向和角度;
- 背景出现相似结构;
- 少数类别和相似类别。
如果训练集中大部分都是排列整齐、光照均匀、目标完整的图片,那么模型在标准测试图片上可能表现很好,但到了真实现场就容易失败。
3. 检查是否有负样本
负样本是指不包含目标的背景图片,或者包含容易被误识别结构的图片。
例如:
- 空托盘;
- 夹具;
- 金属垫片;
- 圆形孔洞;
- 局部强反光;
- 与螺丝外观相似的零件。
适当加入负样本,可以帮助模型学习“什么不是螺丝”,降低误检率。
4. 检查训练集和验证集是否存在数据泄漏
如果一段连续采集的视频被拆成图片,然后相邻帧分别进入训练集和验证集,那么训练集和验证集中的图片可能几乎完全相同。
这种情况下,验证指标可能看起来很好,但并不能代表模型具有真正的泛化能力。
更合理的划分方式是按照:
- 不同采集批次;
- 不同日期;
- 不同工件批次;
- 不同光照状态;
- 不同摆放场景;
进行划分,而不是简单随机打乱所有图片。
六、第五步:分析指标,而不是只看总mAP
数据检查完成后,才进入训练结果分析。
很多人训练 YOLO 后,首先关注的是 mAP。但在工业项目中,只看一个总体 mAP 往往不够。
1. Precision
Precision 表示模型预测出来的目标中,有多少是真正正确的。
可以简单理解为:
模型说“这里有螺丝”时,有多大概率是真的。
Precision 较低,通常意味着误检较多。
2. Recall
Recall 表示实际存在的目标中,有多少被模型成功检测出来。
可以理解为:
图像中所有真实螺丝,模型找回来了多少。
Recall 较低,通常意味着漏检较多。
在螺丝计数项目中,我会更加关注 Recall,因为漏掉一颗螺丝就会直接导致计数错误。
不过,这并不代表 Precision 不重要。如果误检出一个不存在的目标,同样会影响最终数量。
因此,实际项目需要在 Precision 和 Recall 之间寻找平衡。
3. 分类别查看指标
总体 mAP 可能会掩盖某些类别的问题。
例如:
- A 类检测效果很好;
- B 类检测效果很好;
- C 类效果非常差。
由于 A 类和 B 类样本数量更多,最终总体指标仍然可能比较高。
因此,需要分别查看每个类别的:
- Precision;
- Recall;
- AP;
- 误检数量;
- 漏检数量。
4. 查看混淆矩阵
对于多类别螺丝识别,混淆矩阵非常重要。
它可以帮助判断:
- 哪两个类别最容易混淆;
- 某个类别是否经常被识别为背景;
- 某个类别是否大量吸收其他类别;
- 类别混淆是否具有固定规律。
如果 A 类经常被识别成 B 类,不一定要立即修改网络结构。
首先应该回到原始图片中查看:
- A 和 B 的关键区别是什么;
- 当前拍摄角度能否看到这个区别;
- 图像分辨率是否足够;
- 两个类别是否存在错标;
- 样本数量是否均衡。
5. 不要只看训练曲线
训练损失持续下降,不代表模型一定能够正常交付。
验证指标很高,也不代表所有工业场景都能稳定检测。
除了曲线和指标,还必须查看实际预测图片,尤其是失败样本。
工业项目最终交付的不是一个漂亮的 mAP,而是稳定可靠的检测结果。
七、第六步:逐张分析错误样本
当模型出现问题时,最有效的方法之一,就是将所有错误图片单独保存并分类。通过这种方式,可以逐渐看出模型错误是否具有规律。
例如:
- 漏检是否主要集中在强反光场景;
- 类别混淆是否只发生在某两个型号之间;
- 小目标是否普遍检测困难;
- 图像边缘目标是否更容易被忽略;
- 误检是否总是出现在同一种夹具上。
如果模型错误具有明显规律,那么优化方向通常已经比较清楚。
八、第七步:有针对性地补充数据
发现问题后,不能只是继续随机采集大量图片。
有效的数据补充应该围绕模型错误进行。
例如:
如果强反光场景漏检
应该补充:
- 不同反光位置;
- 不同曝光程度;
- 不同螺丝姿态;
- 不同光源亮度;
- 局部过曝但仍可识别的样本。
如果密集排列时漏检
应该补充:
- 不同数量的密集排列;
- 不同重叠程度;
- 不同方向组合;
- 部分遮挡;
- 目标紧贴的场景。
如果两个类别经常混淆
应该重点采集能够体现二者差异的图片。
例如两种螺丝主要区别在螺帽,那么就要确保:
- 螺帽区域清晰;
- 螺帽没有严重反光;
- 不同角度下仍能体现区别;
- 两个类别样本数量相对均衡。
如果背景容易误检
应该补充对应背景负样本,而不是继续增加标准螺丝图片。
数据补充不是继续随机拍照,而是根据模型错误,有针对性地增加困难样本。
九、第八步:最后再调整训练参数
只有完成前面的检查后,才应该开始系统调参。
此时调参才是有依据的,而不是盲目尝试。
可以重点检查以下内容。
1. 输入图像尺寸
如果目标较小,提高训练和推理输入尺寸可能有帮助。
但输入尺寸越大,通常会带来:
- 训练速度下降;
- 推理耗时增加;
- 显存占用增加;
- TensorRT 部署成本提高。
因此需要根据目标尺寸和实时性要求进行权衡。
2. 模型大小
更大的模型通常具有更强的特征提取能力,但不一定能解决所有问题。
如果类别区分特征在原始图像中根本不存在,更换更大的模型也无法创造出这些特征。
同时,大模型还可能带来:
- 推理速度下降;
- 部署资源增加;
- 过拟合风险提高。
3. 训练轮数
训练轮数太少可能导致模型尚未收敛,但训练轮数并不是越多越好。
需要结合:
- 训练损失;
- 验证损失;
- Precision;
- Recall;
- mAP;
- 实际预测结果;
共同判断。
如果训练集指标持续提高,而验证集指标开始下降,说明模型可能出现过拟合。
4. 数据增强
Mosaic、MixUp、随机缩放、旋转、亮度变化等数据增强能够提升泛化能力,但增强强度需要符合真实工业场景。
例如,现场螺丝不会发生严重透视变形,就没有必要使用过强的透视增强。
如果增强后的图片已经明显偏离真实成像分布,反而可能干扰模型学习。
5. 置信度阈值和NMS阈值
这两个参数属于推理后处理参数。
降低置信度阈值,通常可以提高 Recall,但也可能增加误检。
提高置信度阈值,通常可以减少误检,但可能增加漏检。
NMS 阈值则会影响重叠检测框的保留情况。
因此,阈值不能只根据单张图片调整,而应该在完整测试集上进行统计。
十、部署后还要检查训练与推理是否一致
有时模型在 Python 中测试效果正常,但导出 ONNX、转换 TensorRT 并集成到 C++ 上位机后,检测结果明显下降。
这时问题不一定出在模型本身,还要检查部署流程。
常见问题包括:
- 图像通道顺序错误,RGB 和 BGR 混用;
- 图像归一化方式不一致;
- Resize 和 Letterbox 处理不一致;
- 输入尺寸不一致;
- 输出张量解析错误;
- 坐标映射回原图时计算错误;
- 置信度计算方式不一致;
- NMS 实现不同;
- FP16 或 INT8 转换带来精度变化;
- C++端与Python端使用了不同阈值。
因此,在部署前后,应该使用同一批图片分别进行对比测试。
建议至少对比:
- 预处理后的输入数据;
- 模型原始输出;
- 检测框坐标;
- 类别编号;
- 置信度;
- NMS 后的最终结果。
只有确认 Python、ONNX、TensorRT 和 C++ 各阶段结果基本一致,才能排除部署实现问题。
更多推荐




所有评论(0)