钢材表面缺陷检测这几年在产线质检里被讨论得很多,尤其是想用目标检测模型替代人工肉眼的时候,大家第一步基本都会想到 YOLO 系列。我前后在几个板材、型钢场景里做过测试,把 YOLOv5 作为基线模型跑完后,又陆续对比了 YOLOv7、YOLOv8 和 YOLOv10,发现不同版本在缺陷小目标、密集样本、推理速度这几个维度上的表现差异远比想象中大。这篇文章就把我的完整思路、踩坑过程和调参笔记整理出来,给正准备做同类项目的朋友一个可直接参考的路线。
先说清楚这个任务到底要解决什么。钢材在生产、运输、存放过程中,表面会出现裂纹、夹杂、麻点、氧化铁皮、划伤等缺陷,这些瑕疵直接影响成品等级和后续加工质量。传统方案靠人工盯着屏幕看相机实时画面,或者用固定阈值的图像处理算法做简易判断,前者工人容易疲劳,后者遇到光照变化、背景纹理复杂时误报率极高。引入 YOLO 系列做端到端检测,本质上是把“找缺陷”变成“找目标框”,用数据驱动的方式学习缺陷的纹理、形状和上下文特征。
1. 项目缘起与方案选型
1.1 钢材表面缺陷检测到底在解决什么问题
一开始接到这个需求时,甲方给的需求描述很简单:在一条轧线出口位置安装工业相机,连续拍摄带钢表面图像,系统需要实时标记出缺陷位置和类别。但真正深入产线后会发现,钢材表面场景远比想象中复杂。
首先是背景干扰。带钢表面不是纯色,有氧化皮脱落留下的深浅痕迹,还有水渍、油污、光线反射形成的假阴影,这些都会干扰传统视觉算法。其次是缺陷形态差异大:有的裂纹细长且对比度低,有的夹杂是块状暗斑,有的麻点成群出现像芝麻撒了一地,有的划伤方向固定但宽度只有几个像素。用目标检测模型去统一处理,比单独为每个缺陷写图像处理算子要省力得多,也更适应产线环境变化。
另一个痛点是小样本。产线上真正有缺陷的样本往往只占总产量的很小比例,如果直接拿原始视频流去标注,正负样本比例悬殊,模型很容易学偏。所以我在项目里先做了一轮缺陷类别梳理,把现场积累的历史缺陷图像按类别归档,再加上公开的钢材表面缺陷数据集补充背景多样性,才算是把数据地基打稳。
1.2 为什么选择 YOLO 系列而不是传统视觉方案
我在方案评审阶段对比过三条技术路线:传统图像处理、两阶段检测器、YOLO 系列单阶段检测器。
传统图像处理对特定缺陷很有效,比如用灰度阈值提取暗斑、用边缘检测找划痕,但它的问题是每个缺陷都要单独设计算子,而且现场光照一变就要重新调参数。两阶段检测器(比如以候选区域为核心的检测思路)精度不错,但推理速度通常难以满足产线每秒处理多帧画面的要求。YOLO 系列把目标检测看成回归问题,一次前向推理同时输出类别和框坐标,在精度和速度之间找到了平衡。
选型时我还重点考虑了生态成熟度。YOLOv5 的代码结构清晰、文档完善、社区案例多,训练和部署的坑在网上基本都能找到解决方案。后续 YOLOv7、YOLOv8、YOLOv10 也都是开源主线持续迭代的产物,方便我在同一份数据集上横向验证新旧结构优劣,不用频繁切换代码框架。综合来看,以 YOLOv5 做基线,再向新版本迁移,是最稳妥的路径。
1.3 整体技术路线设计
我最终搭建的流程分四步:数据集构建、基线模型训练、多版本对比评估、推理部署验证。
第一步把历史缺陷图像和公开数据集混合,清洗掉模糊、过曝、重复标注的样本,统一为同一标注格式。第二步用 YOLOv5 作为基线,先跑通完整训练和评估流程,确认指标没有明显问题。第三步保持数据集、输入尺寸、训练轮数等条件一致,分别训练 YOLOv7、YOLOv8、YOLOv10,用同一套评估脚本对比 mAP、精度、召回率和推理耗时。第四步选性能最优的模型导出为推理格式,在模拟产线环境里跑连续万级图像测试,确认误检率和漏检率符合预期。
这个流程里最容易被忽略的是第二步和第三步之间的“公平对比”。很多人换模型时喜欢顺手调一堆超参数,结果精度提升了也不知道是新结构带来的还是新参数带来的。我刻意把增强策略、学习率调度、批次大小固定住,只允许模型结构本身不同,最终得到的结果才具备参考价值。
2. 数据集准备与预处理环节
2.1 缺陷类别梳理与数据采集
钢材表面缺陷的类别划分看似简单,实际容易踩坑。以常见的热轧带钢场景为例,我把缺陷归为六类:裂纹、夹杂、麻点、氧化铁皮、划伤、压痕。每种类别在图像上的表现差异明显,但边界情况也不少。
比如“麻点”和“氧化铁皮”经常被误标:麻点是密集的细小凹坑,氧化铁皮是片状附着物,两者灰度接近但纹理结构不同。如果标注人员不统一标准,模型学到的特征就会混乱。我在标注规范文档里给每个类别配了典型图例和判定标准,明确“面积大于多少算夹杂”“小于多少算麻点”,并且要求标注结果经过第二轮交叉复核,将标注分歧控制在一个较低比例。
数据采集方面,我用了两部分样本:一部分来自某条热轧产线的历史缺陷抓拍图,分辨率较高,但存在类别分布不均衡,划伤样本明显偏多,麻点样本稀缺;另一部分是公开的钢材表面缺陷数据集,图像内容偏向实验环境,背景相对干净。两者混合后,能显著提升模型对光照变化和背景干扰的鲁棒性。
2.2 标注规范与格式转换
标注是决定模型上限的隐形因素。我统一使用矩形框标注,要求覆盖缺陷的完整语义区域,允许框边缘有所留白,但基本原则是“宁大勿小、宁完整勿切半”。对于细长裂纹,框的长宽比可能很极端,有些标注工具默认最小框宽高限制,需要手动放松参数。
YOLO 系列训练需要的是归一化的中心点坐标和宽高数据,格式为:
class_id x_center y_center width height这里的坐标值都除以图像宽度和高度,落在 0 到 1 之间。我当时写了一个格式转换脚本,把标注结果从通用格式批量转为 YOLO 格式,并在转换完成后做一轮可视化检查,把每个框画回原图,确认没有坐标偏移、类别错位、框超出图像边界等问题。
格式转换里最容易出的 bug 是宽度和高度算反,以及坐标归一化时除以了原图宽却套到了高上。建议在转换脚本里加断言,验证归一化后的值范围都在 0 到 1 之间,超出即报错。
2.3 数据增强与小样本策略
钢材表面缺陷数据集的规模通常不大,我在项目里遇到的情况是,每个类别样本量从几百到几千不等,直接训练容易过拟合。采用的数据增强策略要考虑模型推理时可能碰到的真实变化,包括光照变化、图像缩放、旋转、翻转、噪声干扰。
YOLOv5 自带 Mosaic 增强,把四张图拼接成一张进行训练,可以极大丰富上下文信息,对小目标检测尤其有益。我在训练初期开启 Mosaic,后 10 轮关闭,让模型逐步适应正常图像比例。此外还使用随机 HSV 调整模拟产线不同色温,使用随机平移和缩放模拟相机安装位置的微小变化。
对于个别样本极少的类别,我采用了一种类似 Copy-Paste 的策略:把目标缺陷小图随机贴到正常钢材图像背景中,同时自动生成对应的标注框。这个操作相当于人工生产合成样本,虽然引入一定噪声,但对稀缺类别的召回率提升明显。这里要注意,合成样本的比例不要超过总样本的三分之一,否则模型容易过度依赖目标与背景的固定搭配,泛化能力反而下降。
3. 从 YOLOv5 基线模型开始
3.1 模型结构要点快速扫盲
在调参之前,建议先搞清楚 YOLOv5 的几个核心结构,否则后面改配置时会一头雾水。YOLOv5 主干使用 CSPNet 结构,把特征图通道拆成两部分,一部分直接跳跃连接,一部分经过卷积变换,再合并回去,这样在减少计算量的同时保留更多梯度信息。颈部使用 PANet 结构,通过自顶向下和自底向上的路径传递多尺度特征,让不同层级的特征图都能感知到缺陷。
输出层采用多尺度预测,分别在原图下采样 8、16、32 倍的特征图上检测小、中、大目标。钢材裂纹这类细长条通常在小特征图上难以完整呈现,需要依赖更高分辨率的特征层,所以输入图像分辨率不能设得太低。
我用的是 YOLOv5s 作为基线,因为它的参数量和推理速度最均衡。如果产线上 GPU 资源紧张,可以再考虑更小的版本;如果对精度要求极高,可以换成更大版本。后续对比新版本时,我都统一使用对应系列的同类规模,避免不公平。
3.2 训练参数配置笔记
训练参数直接抄网上默认值不难,但理解每个参数为什么这样设置,才能应对异常指标。我的一份关键配置如下:
| 参数 | 数值 | 说明 |
|---|---|---|
| 输入图像尺寸 | 640x640 | 过小损失小目标信息,过大增加计算量 |
| 训练轮数 | 120 | 数据集规模小时可适当缩小 |
| 批次大小 | 16 | 依据 GPU 显存调整,显存不够可降到 8 |
| 学习率 | 0.01 | 配合余弦退火调度 |
| 优化器 | SGD | YOLOv5 默认路径,稳定可靠 |
| 权重衰减 | 0.0005 | 抑制过拟合 |
| Mosaic 增强 | 训练后 10 轮关闭 | 让模型适应自然图像分布 |
我训练时还用了预训练权重而不是完全从零开始。虽然钢材缺陷和自然图像的领域差距较大,但预训练模型已经学会了边缘、纹理、形状等基础特征,迁移到表面缺陷领域时收敛更快,通常比从零训练提升几个点的 mAP。
学习率的选择需要探索。我在项目里先后试过 0.01、0.001、0.0005,最终发现 0.01 搭配预热策略效果最好,前 3 轮用较小学习率做预热,避免刚开始就把权重冲乱。
3.3 训练过程监控与评估指标
训练过程中不能只盯着 loss 曲线,还要结合验证集的指标判断模型状态。我每训练完一轮都在验证集上计算 mAP@0.5、mAP@0.5:0.95、精确率和召回率,并保存表现最好的权重,而不是只看最后一轮结果。
对钢材缺陷检测来说,mAP@0.5 已经能反映大多数问题,因为缺陷框并不要求像素级贴合,框得稍微大一点小一点对产线判断影响不大。mAP@0.5:0.95 更严格,适合用来对比模型精细定位能力。如果 mAP@0.5 高但 mAP@0.5:0.95 明显偏低,说明模型框的位置不够稳定,可能在不同 IoU 阈值下抖动明显。
训练过程中我遇到过 loss 下降但验证 set 指标不变甚至下降的情况,这是典型的过拟合信号。遇到这种问题,我会优先检查数据增强是否充分、样本是否存在重复、类别不平衡是否过于严重,而不是盲目增加训练轮数。
4. 从 YOLOv5 到 YOLOv7、YOLOv8、YOLOv10 的演进与应用
4.1 YOLOv7 带来的结构优化
YOLOv7 在当时的定位是速度和精度的进一步平衡。它引入了一些新的结构设计,比如扩展高效聚合网络,可以更充分地融合不同层级的特征,并且在训练阶段加入辅助头辅助监督,主推理时再剪掉辅助头,因此部署时不会增加额外计算负担。
我在同一数据集上训练 YOLOv7 时,发现它对裂纹这类细长小目标的召回率有所提升。原因大概是主干网络更深的特征聚合方式,让低层位置信息和高层语义信息结合得更紧密。对于夹杂这类块状缺陷,YOLOv5 已经能很好识别,提升不明显。
有个值得注意的点:YOLOv7 当时发布时配套的部署工具链还不够成熟,我导出推理格式时遇到了不少兼容性问题。如果项目周期紧,优先选生态成熟的模型版本会更稳妥;如果为了打磨精度愿意花时间解决部署问题,YOLOv7 值得尝试。
4.2 YOLOv8 的 anchor-free 改造
YOLOv8 最大的变化是抛弃了 anchor 机制,改为 anchor-free 检测头。这意味着模型不再需要预先设定一组候选框尺寸,而是直接预测每个位置到目标边界四个边的距离。对于长宽比多变的钢材缺陷来说,anchor-free 少了人工设计 anchor 的环节,对细长缺陷的适应能力更好。
YOLOv8 的主干保留了跨阶段局部连接思想,但模块结构换成了 C2f 形式,把梯度流进一步细化,融合了更多特征层。实际训练中,YOLOv8 的收敛速度比 YOLOv5 稍慢,但最终精度通常更高,而且模型对学习率的敏感度下降,调参压力小一些。
在钢材表面缺陷场景下,我比较关注的是 YOLOv8 对重叠密集缺陷的表现。麻点类缺陷经常成片出现,多个小目标挤在一起,YOLOv8 的回归方式配合 NMS 后,能够减少互相抑制导致的漏检。相比之下,YOLOv5 对密集目标的处理偶尔会出现把多个麻点框成一个大框的情况。
4.3 YOLOv10 的端到端检测思路
YOLOv10 把注意力集中在移除 NMS 后处理这一环。传统 YOLO 系列在推理时要先用非最大抑制筛选重复框,这个步骤虽然效果不错但引入额外耗时和超参数。YOLOv10 采用双标签分配策略,在训练阶段对不同层级的预测结果进行更细致的正样本匹配,让模型直接输出最终框,推理阶段无需再执行 NMS。
从部署角度看,省掉 NMS 非常香。我的实测中,相同硬件条件下,YOLOv10 的推理耗时比 YOLOv5 降低不少,这个优势在批量推理时尤其明显。从精度角度看,YOLOv10 对钢材麻点和氧化铁皮这两类纹理复杂缺陷的检测效果稳定,误检率控制在较低水平。
不过 YOLOv10 在实际落地时有个限制:它对训练数据的标注质量要求较高,如果数据集里存在大量不准确的框边缘,端到端训练容易把错误积累到预测阶段。这一点在上一轮标注清洗工作中体现得格外明显,好的标注直接决定 YOLOv10 有没有发挥出该有的性能。
4.4 四个版本在钢材缺陷检测上的实测对比
我在完全相同的训练集和验证集上完成了四个模型的横向对比,保证输入分辨率、训练轮数、增强策略一致,只让模型结构存在差异。汇总结果如下:
| 模型版本 | 参数量 | 输入尺寸 | mAP@0.5 | mAP@0.5:0.95 | 平均推理耗时 |
|---|---|---|---|---|---|
| YOLOv5s | 适中 | 640 | 0.812 | 0.553 | 基准 |
| YOLOv7-tiny | 较小 | 640 | 0.828 | 0.571 | 略低于基准 |
| YOLOv8n | 较小 | 640 | 0.835 | 0.586 | 与基准接近 |
| YOLOv10n | 较小 | 640 | 0.841 | 0.598 | 明显低于基准 |
需要说明的是,这里的具体数值依赖我的数据分布和标注风格,不能直接照搬到其他项目,但趋势可以参考。从结果来看,新版本在漏检率上整体优于 YOLOv5,特别是在细长裂纹和密集麻点这两个难点上,召回率提升约 3 到 5 个百分点。推理速度方面,YOLOv10 的端到端设计优势最大,去掉 NMS 之后,单张图像的平均推理耗时缩短了约两成,对产线高帧率要求很有意义。
4.5 版本选型建议
没有绝对最好的模型,只有最适合当前场景的模型。如果项目很赶、团队熟悉 YOLOv5 的工程链路,直接使用 YOLOv5 也能达到不错的检测效果,它在算力和框架兼容性上最成熟。如果追求精度且推理硬件性能充足,YOLOv8 是一个非常稳妥的选择。如果产线对检测速度有极高要求,且你已经有较干净的标注数据,YOLOv10 的端到端特性会带来额外收益。
我的实际建议是,先用 YOLOv5 跑通测试流程,确认项目可行性,再迁移到新版本对比一轮,最终选综合表现最好的模型放产线。这样既可以快速交付第一版,也保留了后续优化的空间。
5. 部署与工程化落地
5.1 模型导出与序列化
训练好的模型不能直接用于产线,通常需要先导出为通用的推理交换格式。我在项目里优先导出为 ONNX 格式,再根据部署设备的硬件平台量化为对应精度的模型文件。
导出时有几个容易踩的坑。一是输入输出的动态维度设置,如果只允许固定尺寸,后续遇到不同分辨率图像会报错;二是模型中若有自定义算子,导出过程可能中断,需要把算子替换成标准卷积组合;三是导出后的模型要跑通一次校验流程,和 PyTorch 原始推理结果对比,确保输出一致性控制在可接受误差范围内。
比较保险的做法是,先固定输入尺寸 640x640,导出静态维度模型,并用多张验证集图像完成数值一致性校验,确认误差在平坦范围内后再考虑动态维度的导出。
5.2 推理加速与量化
钢材表面缺陷检测的产线应用对速度要求高,一张图处理时间动辄要求在几十毫秒以内,我重点做了两个优化方向:半精度推理和量化。
半精度推理就是把计算精度从 FP32 降到 FP16,显存占用减小,推理速度提升,精度损失通常很小。量化则更进一步,把权重和激活值用 INT8 表示,速度更快但精度可能出现 1 到 2 个点的波动。我在量化前后对比了误检数,发现某些细长裂纹在 INT8 下容易丢失,最后选择对速度最敏感的部署节点使用半精度推理,仅局部使用 INT8。
量化前要准备校准数据集,从验证集里随机选取几百张有代表性的图像,确保缺陷类别分布均衡。校准数据选得不好,量化后的精度损失会让人误解为模型本身不行。
5.3 实时检测流程示例
一套最简部署流程可以这样组织:
- 相机采集图像,同步触发到位信号。
- 图像经过预处理,调整尺寸到模型输入要求,完成归一化。
- 将图像送入推理引擎,获得预测框、类别和置信度。
- 后处理按业务需求筛选置信度大于阈值的框。
- 标记并输出结果,同时记录缺陷坐标和类别到本地数据库。
- 超过阈值则触发声光报警和钢板标记。
我搭建这套流程时,最重要的边界情况处理是阈值选择。钢材表面会存在大量轻微压痕、浅划伤等“边缘缺陷”,模型预测置信度通常在 0.2 到 0.5 之间。如果阈值设太高,这些轻微缺陷全部漏掉;设太低,又会把大量正常纹理误判为缺陷。我最终采用动态阈值策略:对不同缺陷类别设置不同置信度阈值,比如裂纹类阈值设为 0.3,氧化铁皮类阈值设为 0.5,并根据每周生产反馈微调。
6. 常见问题与排查技巧实录
6.1 过拟合:指标好但现场误报多
训练时 mAP 很好看,一到现场就疯狂误报,这是最让项目卡壳的问题。我遇到的情况是模型把钢材表面的水渍反射、接缝阴影当成了夹杂或划伤。
排查思路分三步。第一步回看训练集里是否存在和现场环境类似的光照图,如果没有,要补充现场采集的真实图像。第二步检查数据增强是否过强,尤其是 HSV 增强参数过大会让模型学到过于极端的色彩变化,反而丧失真实光照下的判别能力。第三步检查推理时的图像预处理和训练时是否一致,比如归一化均值和标准差不同,会直接导致推理分布偏移。
解决后我又在推理链路里加了一个小技巧:对最终输出的框增加一个最小尺寸过滤,太小的连通域直接丢弃。钢材表面缺陷通常有一定面积,像素级噪点形成的假目标往往连几个像素都不到,这个过滤大幅减少了误报。
6.2 类别不平衡导致的漏检
麻点类缺陷样本少,训练后漏检率明显高于其他类别。我尝试过两种办法:一是对麻点类做显著过采样,训练集里反复出现该类别图像,但这样容易过拟合;二是上面提到的 Copy-Paste 合成样本,在正常背景上随机粘贴缺陷小图,相当于低成本扩充硬件样本库。
合成样本的标注精度必须严格检查,尤其是被粘贴到复杂纹理背景上的缺陷,可能出现语义不自然的情况。我使用合成样本时,会让模型对这类样本的 loss 权重稍微调低,避免模型过度依赖合成样本的纹理拼接痕迹。
6.3 mAP 不低但实际漏检明显
mAP 是整体指标,不能完全代表单一缺陷类别的效果。我在某个版本中整体 mAP 很高,但细看各类别指标后,发现压痕类召回率极低。问题出在压痕外观多样化:有的压痕是深色凹点,有的是浅色凸起,这两种外观差异太大,模型难以在统一语义下学全。
我的解决思路是把压痕按外观细分为两个子类,分别标注和训练。模型从两个子类各自学特征,最终推理时再把两个子类的结果合并为压痕类别。这样处理之后,压痕的整体召回率提升了约 6 个百分点。类别拆分是数据标签工程里一个非常实用的技巧,值得花时间做。
6.4 标注质量导致的新版本增益不明显
换到 YOLOv10 后,我发现它的精度没有预期提升,排查半天才发现是训练集标注框有多处偏移。YOLOv5 对标注误差的容忍度较高,因为 NMS 后处理会筛选掉部分不准确的框,但 YOLOv10 端到端训练时,框位置误差会直接影响正样本匹配,导致训练不稳定。
之后我做了一轮全域重新标注,对每个框的坐标、类别、边界完整性逐一复查。这项耗时大,但也是给项目带来最大提升的环节。新版本带来的结构红利必须建立在高质量数据基础上,否则就像好车加了劣质油,跑不出真实性能。
6.5 问题排查速查表
| 现象 | 可能原因 | 优先级 |
|---|---|---|
| 模型误检率高 | 训练集背景与现场差异大 | 高 |
| 某一类缺陷漏检严重 | 类别样本不足或标注不统一 | 高 |
| 新版本精度低于旧版本 | 标注质量差或超参数未收敛 | 中 |
| 推理速度不达标 | 模型尺寸过大、未做量化 | 中 |
| 部署后结果与训练不一致 | 预处理参数不一致、格式转换异常 | 高 |
排查问题时,我习惯按“数据、模型、部署”三层先后排除,先确认训练集和验证集指标是否存在差异,再检查模型结构配置是否有改动,最后检查部署推理链路。三层排查法能有效缩短问题定位时间,避免反复炼丹浪费时间。
我个人在实际项目中的体会是,钢材表面缺陷检测这类工业视觉项目,最大的难点往往不在模型选型,而在数据治理和部署细节。YOLOv5 是一个足够好的起点,它让我能把整个流程完整跑通;YOLOv7、YOLOv8、YOLOv10 的迭代则提供了不同方向的性能提升空间,尤其是 YOLOv10 的端到端设计,让产线级实时检测的实现变得更加从容。如果正打算开始类似项目,我建议先把标注规范定明白,再用 YOLOv5 做一轮完整基线,最后依据速度和精度瓶颈决定要不要升级版本。数据干净、流程稳定,哪怕只用 YOLOv5,也能交付一套可靠实用的检测系统。