钢铁表面缺陷检测这件事,我从头到尾踩了一年多的坑。最早接手这个需求的时候,想法特别朴素:不就是给钢板拍张照片,扔进网络里分出个类别来吗?后来真正站到产线边上,看着钢板以每秒一米的速度从眼前呼啸而过、头顶的冷却水雾糊住镜头、白天和晚上的光照完全不是一个样子,才知道这件事的难点根本不在于选哪个网络结构,而在于你有没有能力把“工业现场”这四个字翻译成一个能训得动、跑得起的深度学习任务。基于深度学习的钢铁缺陷识别,说到底是把一条高速运转的金属加工产线上那些肉眼都未必看得清、看久了还会漏判的表面异常,交给一套稳定可复现的视觉系统去判读,输出缺陷的有无、类别、位置和尺寸。它解决的问题很明确:人工目检的漏检率高、一致性差、疲劳度高,而且缺乏可追溯的结构化数据。这篇文章主要写给三类人看——刚接触到工业视觉检测、想把深度学习真正落地到产线上的算法工程师;负责产线质量管控、需要评估这套方案可行性的工艺人员;以及正在做相关课题、想了解工程侧会碰到哪些真实问题的同学。文中涉及的具体参数、相机配置和缺陷类别,我做了合理虚构与抽象处理,但推导逻辑和踩坑经验是我真实趟过来的。
1. 方案整体设计与技术路线拆解
1.1 钢铁缺陷到底难在哪些地方
先别急着建网络。我在动手写第一行训练代码之前,花了两周时间只是看图片、跟着班组去现场看实物。有不看这些的同行,模型在测试集上跑到 0.9 的 mAP,到了现场直接掉到 0.4,回头就怪数据集不够大。真正的原因是没理解缺陷的成像特性。
钢铁表面缺陷的难点,我总结成下面四条,每一条都直接决定了后面模型怎么设计。
第一是类内差异巨大、类间差异极小。同样叫“划痕”,有几十毫米长的细线,也有一小片磨花的区域;而“氧化铁皮压入”和“麻点”在低分辨率下几乎是一个灰度斑块。这意味模型的判别能力不能只靠低频的纹理信息,必须保留足够的局部细节,输入分辨率的选择就成了第一道关卡。
第二是缺陷尺寸跨越三个数量级。最小的针孔类缺陷宽度不到 0.5 mm,最长的边裂可以贯穿整个视场。同一套感受野去吃两端目标会很吃力,这是我后来采用多尺度输入、并在推理时做切片的原因。
第三是极端的样本不均衡。一整卷钢带出缺陷的比例大概在千分之一量级,一张 2000×2000 的图上可能一条划痕都没有。类别之间的分布也极不均衡,常见缺陷占了七八成,剩下几类每类只有几十个样本。这种数据分布下,任何用普通交叉熵、普通随机划分训出来的模型都只是在拟合类别先验。
第四是成像条件不稳定。反光、水渍、氧化色差、辊子转动带来的周期性明暗条纹,全都会被网络当成特征学进去。我见过一个模型在训练集上对“辊印”这类缺陷识别极好,结果一换班,灯光角度变了 3 度,全部漏检。这不是模型的问题,是数据覆盖问题。
注意:如果你的任务里出现了周期性的条状纹理规律,先怀疑是产线本身的辊道或光源造成的假特征,而不是缺陷本身。判断方法很简单:把这块区域裁出来看它是否在整幅图上等间距重复出现。
1.2 为什么这套场景最终选了“检测”而不是“分类”
最开始我确实想用分类网络解决问题——一个钢板表面图片二分:有缺陷、没缺陷。跑得很快,效果看着也不错,99.8% 的准确率。但这个数字是骗人的,因为如果缺陷样本只占 0.2%,模型全部输出“无缺陷”就能达到这个准确率。更要命的是,分类模型给不出位置,产线要的是缺陷在哪、多大,好决定是切掉这一段还是降级处理。
分割方案我也想过,语义分割或者实例分割理论上信息量最全,但在工业现场有两个绕不开的门槛:一是标注成本,像素级标注需要熟练质检员用多边形一点点抠,一张图常常要十几分钟,做三千张的数据集成本已经很难接受;二是推理速度,全分辨率分割模型的耗时在产线节拍面前很难交代。
最终落点是目标检测,理由很清楚:矩形框标注的成本可控,能提供位置与尺寸的近似估计,可以量化出缺陷长度和宽度,同时推理速度快,可以做实时。代价是稠密小目标、细长裂纹的框回归不好,所以我们把“极细长裂纹”和“粘连缺陷”单独做了切片分检和后处理拆分,这部分后面细说。
| 方案 | 标注成本 | 输出信息 | 推理速度 | 适配性 |
|---|---|---|---|---|
| 图像分类 | 低 | 仅有类别 | 最快 | 只能做初筛 |
| 目标检测 | 中 | 类别+位置+尺寸 | 快 | 主力方案 |
| 语义分割 | 高 | 像素级区域 | 中 | 小缺陷、复杂形状 |
| 实例分割 | 很高 | 逐实例掩码 | 慢 | 仅做研究验证 |
1.3 整体链路是怎么串起来的
整套系统我拆成五段:成像采集、数据治理、模型训练、推理加速、产线集成。很多人喜欢只盯着第三段,实际上真正决定成败的是第一段和第五段。
成像采集决定了下限。你采回来的图本身信噪比不够、对比度不够,后面再怎么调模型都是徒劳。这一段的核心是光源方案和相机参数,1.3 之后的第四章会专门算一遍。
数据治理决定上限。包括标注规范、类别体系、抽帧去重、困难样本回捞。
模型训练是常规工程,选型、增强、损失、调参。
推理加速决定能不能上产线,通常要考虑半精度、图优化、批处理、切片调度。
产线集成是所有人最容易低估的一段——报警要不要联动执行机构、NG 图片存多久、模型更新怎么灰度、误检由谁来复检,这些都是代码之外的活。
我习惯把每一段的验收标准先写出来,再动手。比如成像段的验收标准是“在正常工况下,最小可检缺陷在图像上不少于 8 个像素跨度”,数据段的验收标准是“每一类缺陷在验证集中至少有 50 个实例,且覆盖至少 3 个不同批次”。
2. 数据集构建与标注核心细节
2.1 类别体系怎么定才不自找麻烦
类别体系这件事,我建议开工第一天就找懂工艺的人一起定,不要自己拍脑袋。我第一版定了 12 类,训了两周发现有三类样本加起来不到 40 个,且相互之间工艺上本来就难区分,最后不得不合并回 8 类,前面的标注全白做。
我的做法是按“工艺上是否需要区分处理”来定类别,而不是按“视觉上看起来不一样”。如果两类缺陷的处理方式完全一样——都是切掉、都是降级,那模型上就没有区分它们的必要,合并成一类反而能显著提升样本量。反过来,如果工艺上要区别对待,哪怕它们长得像,也得分开,并在标注规范里写清楚判定依据。
最终落地的类别大概是这样一副骨架:
| 类别 | 典型形态 | 处理方式 | 样本稀缺度 |
|---|---|---|---|
| 划伤 | 线状、有方向性 | 降级或切除 | 中 |
| 压入氧化皮 | 不规则块状、边界模糊 | 降级 | 高 |
| 麻点 | 密集小凹坑 | 降级 | 中 |
| 夹杂 | 深色不规则斑 | 切除 | 很高 |
| 裂纹 | 细长、常沿轧向 | 切除,最高优先级 | 高 |
| 辊印 | 等间距周期性条纹 | 观察、溯源设备 | 低 |
| 边裂 | 板边开口 | 切除 | 中 |
| 镀层异常 | 色差型片状区域 | 降级 | 高 |
类别定完之后还有一个容易忽略的事:给每一类写上“不是这一类的样子”。比如“夹杂”和“深色氧化斑”的边界,我当时在标注规范里补了一句判定规则——低于某个灰度且边界锐利、内部无纹理延伸的算夹杂,边界逐渐过渡的算氧化斑。这一句话让三个人标注的一致性从七成多提升到了九成以上。
2.2 标注质量的坑比想象中深
标注这件事,我建议宁慢勿快。真实经验是:一个模型效果上不去,九成情况先回头查标注,别急着改网络。
踩过的几个具体坑,说给你听。
框贴边的问题。有的标注员习惯把框画得紧贴目标边缘,有的留一圈余量。这两种风格混在一起,模型学出来的回归目标就是矛盾的。我的规范是统一向外扩 2 到 3 个像素,理由是卷积特征在目标边界处本来就存在扩散,稍大一点的框能让正样本采样更稳。
长裂纹的框怎么画。一条沿轧向延伸 800 像素、宽度只有 6 像素的裂纹,如果用一个大框把整条裂纹框住,框内 90% 都是背景,回归目标的宽高比极端,任何基于 IoU 的匹配策略都会出问题。我的处理是把长裂纹分段标注,每段控制在宽高比不超过 1:8 的范围内,推理时再做线段合并。这个改动让裂纹类的召回率提升了十几个点。
模糊区域的处理。产线上总有水雾、失焦、反光造成的模糊图。这些区域如果有疑似缺陷,标注员会犹豫。我的规定是:无法确认的一律不标,但整张图打一个“低质量”标签,训练时做降权采样。反过来,如果低质量图里一个框都没有,也不要直接当负样本用,否则模型会学到“模糊=无缺陷”这个错误关联。
重复帧去重。产线是连续采样的,相邻两帧差别极小。如果不做去重,同一个缺陷会在训练集和验证集里同时出现,指标虚高得离谱。我用感知哈希做粗去重,再用图像相似度做二次过滤,阈值调到能过滤掉同卷相邻帧,但不误杀不同批次里长得像的正常图。这件事做完,验证集指标掉了一大截,但那是真实指标。
2.3 数据增强怎么做才有效
增强策略这块,抄袭图像分类的通用配方在钢铁缺陷上会翻车。我一个个说。
几何变换要谨慎。水平翻转一般没大问题,但垂直翻转要慎用——很多缺陷有明确的轧向,垂直翻转会制造出现实中不存在的方向性。大角度旋转更危险,90 度旋转对纹理类缺陷(麻点、氧化皮)可能还行,对划痕类会引入不真实的分布。我的取值是随机旋转限制在 ±10 度,翻转只用水平翻转,且只对不敏感类别开启。
色彩扰动要克制。钢板的整体色调由氧化程度决定,不是一个可以随便改的属性。亮度、对比度的小幅抖动是可以的,色相的大范围偏移会破坏缺陷与基体的相对关系。我的参数是亮度 ±0.15、对比度 ±0.15、饱和度 ±0.1,超过这个范围我实测过,会把“深色夹杂”改造成看起来像“氧化斑”。
MixUp 和 Mosaic 要分场景。Mosaic 对检测任务很有帮助,它强行让模型在一张图里见到多尺度目标,对小目标召回提升明显,这个我一直在用。MixUp 混合是把两张图线性叠加,对钢铁这种强纹理图会叠出根本不存在的灰度假象,我验证过反而掉点,直接关掉。
我加了一个自造的增强:光照模拟。做法是把图像转到与亮度无关的通道空间,只对亮度分量做不规则的非线性映射,模拟现场光照不均造成的明暗带。这个增强比任何通用增强都管用,因为它对付的正是“换班后模型崩掉”这个问题。
import numpy as np import cv2 def uneven_illumination(img, strength=0.25): """模拟产线光照不均:沿随机方向生成低频明暗梯度""" h, w = img.shape[:2] # 随机方向的低频条纹,模拟光源角度变化 angle = np.random.uniform(0, np.pi) xs = np.linspace(0, 1, w)[None, :] ys = np.linspace(0, 1, h)[:, None] proj = np.cos(angle) * xs + np.sin(angle) * ys freq = np.random.uniform(1.0, 3.0) grad = np.sin(proj * np.pi * freq) * strength grad = np.clip(1.0 + grad, 0.55, 1.45) img_f = img.astype(np.float32) out = img_f * grad[..., None] return np.clip(out, 0, 255).astype(np.uint8)这段代码我放在训练管线的最后一步,概率设 0.3。它不改变标注框位置,所以对检测任务完全安全,实测能把现场换班后的掉点幅度压掉一半以上。
3. 模型选型与训练实施要点
3.1 主干与检测头的选型逻辑
选型我一直遵循一个原则:能在同等精度下把推理耗时压下来的方案优先,因为产线的节拍是不等人的。所以我从单阶段检测器出发,先把基线跑通。
主干网络方面,工业缺陷检测的特征主要是中等尺度的纹理异常和细长的边缘结构。轻量级主干在高层语义上够用,但浅层的细节响应偏弱。我的做法是保留轻量主干,在浅层引出额外的高分辨率特征分支,并把检测头挂到更浅的层级上,代价是算力增加有限,收益是对针孔、细线类目标的召回。
这里有个具体的取舍我印象很深。早期我用了一个很轻的主干,参数量不到 3M,模型体积很小,推理飞快,但“麻点”这一类的召回一直在 0.6 附近上不去。我后来对比了特征图可视化,发现麻点在浅层响应其实很清楚,但经过几次下采样之后特征被稀释掉了。解决办法不是换大模型,而是把输入分辨率提高一档,并在特征融合时给浅层加权重。召回直接跳到 0.82,推理耗时只涨了不到 20%。
注意力机制我试过几类,结论是坐标注意力类(同时建模长宽方向)对细长裂纹有效,通用通道注意力收益有限。原因是细长缺陷在空间上的响应是沿一个方向延展的,只做通道加权捕捉不到方向性。但这个模块一定要放在融合层而不是主干里堆,堆在主干里参数一起涨,性价比很差。
3.2 正负样本分配与损失函数
这部分是很多教程略过的,但对不均衡数据影响最大。
正负样本分配。If 你用的是基于 IoU 阈值的分配策略,在钢铁缺陷上要小心:大片背景区域里的小缺陷,IoU 天然偏低,容易分不到足够正样本。我改成动态分配之后(依赖每个目标的统计特征决定分配数量),小目标的召回明显改善。这个改动我建议所有人都试一下,尤其你的数据里小目标占比超过三成的时候。
分类损失。极端不均衡下,普通二值交叉熵会被海量简单负样本主导。我用的是带聚焦系数的交叉熵,把易分样本的权重压下去,让梯度集中在难样本上。参数我用的 1.5,试过 2.0,太激进会导致训练后期震荡。同时配合一个正样本采样比例,控制每张图输入到损失里的正负比例在 1:3 左右。
回归损失。定位损失我用了带距离惩罚的形式,因为裂纹这类极窄目标,纯 IoU 形式的梯度在框不重叠时会消失,训练容易卡住。距离惩罚项能在框完全不重叠时仍然提供有效梯度,这一点对快速收敛帮助很大。
还有一个容易被忽略的处理:目标尺寸回归要做归一化。钢铁缺陷的宽高比分布极其极端,从 1:1 到 1:50 都有。如果不对宽高做对数空间的建模,回归目标会被少数巨大目标主导。我把宽高的回归放在对数空间里做,同时给极小目标的宽高加了一个最小值约束,防止训练早期框宽收缩到 0 导致数值问题。
3.3 训练参数与调参记录
参数这块我按实际跑过的配置说,但你要理解为什么这么设,直接抄数值意义不大,因为硬件和分辨率不同。
批次大小我定在 16,输入分辨率 640,这样一张卡(24G 显存)刚好可以开混合精度训练,显存占用在 80% 上下。我试过开到 32,学习率线性放大之后收敛更陡,但小批次那种“噪声带来的正则效果”反而更好,验证集更稳,所以我留在了 16。
学习率用分段加余弦退火的组合。初始值 0.01,前 3 个 epoch 做线性预热——这一步很重要,钢材图像输入分辨率高、浅层特征响应剧烈,不预热的话前几百步很容易把 BN 统计量带偏,后面一路都拉不回来。预热之后进入余弦退火,最小学习率设到初始值的 1%。
训练轮数我先跑 300 轮看曲线,实际收敛点大概在 220 到 260 之间。早停我设的是验证集上主要指标的滑动均值 15 轮不涨就停,不要用单轮最优点,噪声太大。
| 参数 | 取值 | 设定理由 |
|---|---|---|
| 输入分辨率 | 640 训练 / 1024 推理 | 训练省显存,推理补细节 |
| 批次大小 | 16 | 显存与正则效果的折中 |
| 初始学习率 | 0.01 | 配合预热与余弦退火 |
| 预热轮数 | 3 | 稳定浅层 BN 统计量 |
| 训练总轮数 | 300(实际约 240 早停) | 按验证曲线确定 |
| 权重衰减 | 5e-4 | 抑制过拟合 |
| 正负采样比 | 1:3 | 缓解极端不均衡 |
| 聚焦系数 | 1.5 | 聚焦难样本,避免震荡 |
训练过程中我盯的指标不止一个是 mAP。我加了两个自建指标:按尺寸分层的召回(小、中、大分开看)和关键类别的单类漏检率(裂纹这类必须单独看,因为它在总样本里占比小,容易被平均值掩盖)。裂纹的单类漏检率如果超过某个阈值,这次训练成果我是不认的,哪怕总体指标再漂亮。
3.4 轻量化的边界在哪
部署前总有人问能不能再小一点。我的判断标准是:先把耗时预算算清楚,再决定压到什么程度,而不是盲目追求小模型。
真实的教训是这样。我一开始做了一版特别轻的模型,延迟只有 6 毫秒,特别得意。结果集成到现场,一张全分辨率大图要切成几十个切片,全跑一遍总耗时接近 400 毫秒,根本满足不了产线节拍要求。这时候才发现,瓶颈不在单次推理,而在切片数量。
后来我改成了两阶段策略:先用下采样图做一遍快速粗检(分辨率降到原来的一半,切片数减少四分之三),只在粗检报出疑似区域的切片上做全分辨率精检。整体耗时降到一百多毫秒,精度几乎没掉,因为绝大多数切片本来就无缺陷,没必要精检。这个思路我强烈建议所有做大画幅工业检测的人思考,它比换更小的模型有用得多。
4. 成像与产线集成的工程细节
4.1 相机与光源参数怎么算
这一段很多人写方案时会跳过,但它直接决定了后面所有指标的天花板。我把我的算法过程摊开讲。
先定像素精度。设最小需要稳定检出的缺陷特征宽度为 1 mm,经验上要求这个特征在图像上至少跨越 8 到 10 个像素,才能保证检测网络有稳定的响应。取 10 像素,则像素精度 = 1 mm / 10 = 0.1 mm/pixel。
再定横向分辨率。设视场宽度为 1.0 m,则需要的横向像素数 = 1000 mm / 0.1 mm = 10000 像素。市面上单台线阵相机常见的横向像素在 4K 到 16K 之间,选 8K 的话,需要两台拼接覆盖,拼接处要做标定对齐和重叠裁剪。
接着算行频。产线速度取 60 m/min = 1 m/s,像素精度 0.1 mm,则行频 = 1 m/s / 0.0001 m = 10000 行/秒,也就是 10 kHz。这个行频在主流线阵相机的能力范围内,但要注意此时单帧的数据量:如果每帧取 2048 行,单帧就是 10000×2048 像素,约两千万像素,需要 16 位深度的话就是 40 MB 一帧。存储和传输都要提前规划。
像素精度 = 最小缺陷特征宽度 / 最小像素跨度 = 1.0 mm / 10 px = 0.1 mm/px 横向像素数 = 视场宽度 / 像素精度 = 1000 mm / 0.1 mm/px = 10000 px 行频 = 产线速度 / 像素精度 = 1 m/s / 0.0001 m/px = 10000 Hz 单帧数据量 = 10000 × 2048 × 2 Byte ≈ 40 MB光源方案上,我踩过的坑主要在两个地方。
一是明场和暗场的取舍。明场照明下,划痕类缺陷因为改变了反射方向,往往表现为暗线,对比度很好;但麻点这类凹陷在明场下几乎看不出来。暗场照明确实能把凹陷和边缘凸起照得非常明显,但对平面色差类缺陷又不敏感。我最终的方案是同工位两套光源交替频闪采集,得到明场图和暗场图两路输入,在特征层做融合,而不是简单地拼通道。代价是硬件成本翻倍,收益是麻点类的检出率提升非常显著。
二是反光控制。钢板表面本身就是镜面,光源角度稍微不对就会在图像上打出一片白。我用的是漫射穹顶加偏振片组合,把镜面反射压下去。这里有个细节:偏振片的方向必须和光源匹配,装反了等于没装,我第一次装的时候就犯了这个错,排查了半天。
4.2 推理加速与现场部署
推理加速这块我按优先级排了个序,实际做下来收益最大的排在最前。
第一是图级优化。把模型导出成标准的中间表示后,做算子融合、常量折叠,这一轮通常是零精度损失的,耗时能降两三成。
第二是半精度推理。显卡支持的情况下直接开,速度提升明显。有个坑要注意:半精度下极小的数值容易出现溢出,尤其你的回归头里如果有除法或者指数运算,建议在关键位置强制回到单精度计算,或者对这些环节做数值保护。
第三是批处理与流水线重叠。切片推理天然可以并行,把切片凑成批次送进去,比逐张推效率高得多。同时把图像预处理(缩放、归一化)放到独立线程里,和推理重叠执行,能再省一截。
第四是量化。整数量化收益很大,但精度风险也大。我的做法是只用一部分真实产线数据做校准,校准集要覆盖各种光照条件和各类缺陷,不能只用验证集。校准完之后一定要在完整的验证集上重测一遍,尤其盯住小目标召回,量化对小数精度敏感,小目标的回归损失最容易崩。
工程上还有几件不那么“算法”、但更影响落地的事。
报警联动要设防抖。单帧误检就触发切除,产线会被误动作搞崩。我的做法是要求同一个物理位置在连续 N 帧里被判定为缺陷,或者缺陷面积超过阈值,才触发动作,同时保留人工复检窗口。
NG 图片要落盘但要有策略。全存很快就把磁盘塞满。我存的是裁剪后的缺陷区域加周边余量,连同上下文信息和模型版本号一起落库,方便后面回捞做增量训练。
模型更新要灰度。新模型先只跑影子模式,输出结果不参与控制,只和现役模型对比,差异样本人工确认后再切。这个流程建立起来之后,迭代节奏会稳很多。
5. 常见问题与排查实录
5.1 问题速查表
下面这张表是我这一年多里频繁翻出来的东西,大部分问题都能在里面找到对应方向。
| 现象 | 首要怀疑 | 排查动作 | 处理办法 |
|---|---|---|---|
| 训练集指标很高,现场大幅掉点 | 数据分布覆盖不足 | 对比训练集与现场图的光照、色温、速度分布 | 补充现场数据,加入光照模拟增强 |
| 某一类召回始终偏低 | 样本量或标注规范问题 | 单独统计该类样本数、框尺寸分布 | 补齐样本,分段标注细长目标 |
| 小目标大量漏检 | 特征被稀释 | 可视化浅层与深层响应 | 提高推理分辨率,浅层加权重 |
| 误检集中在周期条纹位置 | 产线本身纹理被当特征 | 检查误检框是否等间距重复 | 裁剪时避开固定位置,或在后处理中过滤 |
| 训练损失震荡不收敛 | 学习率或批次问题 | 观察前 500 步损失曲线 | 加预热,降低初始学习率 |
| 验证集分数虚高 | 训练验证数据泄漏 | 检查同卷相邻帧是否重复 | 相似度去重后重新划分 |
| 量化后精度明显下降 | 校准集不具代表性 | 分类型、分光照重测 | 扩充校准集,关键层保精度 |
| 推理延迟不稳定 | 切片数波动或资源争抢 | 记录每帧耗时与切片数量 | 两阶段策略,预处理与推理并行 |
5.2 几条不方便写进文档的经验
说几条我真正吃过亏才明白的事。
不要相信第一次划分的数据集。我最初随机划分训练验证集,指标漂亮得不像话。后来发现同一卷钢带上的相邻帧被分到了两边,等于拿训练数据的近亲去测试。改成按卷、按批次划分之后,指标掉了近二十个点,但那个才是真的。划分单元一定要选“产线物理上独立的单元”,卷、批次、班次都可以,唯独不能是单张图。
类别不平衡不要在采样层面硬怼。我试过对稀缺类做过采样,重复采样到和其他类一样多,结果是模型对这几类过拟合,现场稍微变个样子就崩。更稳的做法是在损失层面做加权,同时适度提高这几类的采样概率(不超过三倍),并且给这几类单独留一份困难样本集做验证。
验证集里必须有一份“脏数据”。干净的验证集只会给你虚假的安全感。我专门留了一份从现场抓的、有水渍、有反光、有轻微失焦的验证子集,每次迭代都在这份数据上单独看指标。这份数据上的表现才更接近现场。
离线指标和现场表现之间有个换算系数。我实测下来,在充分去重的验证集上 mAP 达到某个水平后,现场首月的实际检出率大约要打八折到八五折。这个折损来自数据分布差、成像差异、阈值设定。所以在做验收标准的时候,我会把目标定得比工艺要求高一截,留出这个折损余量。
别忽略负样本的质量。所有人都盯着缺陷样本,其实无缺陷样本如果全是“干净得不像话”的图,模型就会把任何一点纹理波动都判成异常。我特意混入了大量“工艺正常但外观有轻微色差、有轻微辊纹”的负样本,让模型学会区分“正常的不完美”和“真正的缺陷”。这一步做完,误检率下降得非常明显。
阈值不是拍脑袋定的,是按代价算的。漏检一条贯穿裂纹和误报一个麻点,代价完全不同。我的做法是把现场的业务代价折算成权重,在验证集上扫描阈值,找到一个总代价最低的点,而不是简单取 0.5。这个点往往不是 0.5,而且不同类别应该用不同阈值。
6. 我对这套方案后续扩展的几个想法
如果这套东西还要往前走,我个人认为优先级最高的不是换更强的模型,而是把数据闭环搭起来。现场每次人工复检的结果、每次误检和漏检的图,都要能自动带着上下文回流到训练池里。工业场景的数据分布是会漂移的——换了供应商、换了轧辊、换了季节,成像和缺陷形态都会变。没有闭环的系统,上线三个月就开始慢慢退化。
其次是多模态融合。现在只用了可见光,其实产线上还有测厚、测宽、温度这些信号,如果能和视觉结果做交叉验证,很多疑难样本的判定会稳得多。比如某块区域同时出现了温度异常和视觉异常,那这条告警的可信度就完全不同了。
最后是缺陷尺寸的精确量化。检测框只能给个大概,但工艺侧真正关心的是“这条裂纹到底多长、深度大概多少”。这一块需要和实际的测量手段结合做标定,把像素尺寸换算成物理尺寸,并且要处理透视和板面弯曲带来的误差,工作量不小,但价值很大。
我在实际推进这个项目的过程里最深的体会是:模型只占整件事的三成,剩下七成是成像、数据和流程。那些在论文里看起来很关键的结构改进,落到现场往往不如把光源角度调对一度来得实在。所以如果你刚开始做这件事,我的建议是先花时间去现场看两百张真实的图,再决定你的第一个网络长什么样。