完成螺丝检测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++ 各阶段结果基本一致,才能排除部署实现问题。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐