1. 工业缺陷检测的底层逻辑与方案选型
1.1 为什么工业缺陷检测和通用目标检测是两码事
做过通用目标检测的人,第一次接触工业缺陷检测,大概率会踩同一个坑:拿COCO预训练的YOLO权重直接去跑产线图片,结果要么什么都检不出来,要么把灰尘、反光、纹理全当成缺陷框出来。这不是模型不行,而是场景的底层假设完全不同。
通用目标检测面对的是“语义明确、边界清晰、样本充足”的目标,比如人、车、猫、狗。这些类别在ImageNet和COCO里有几十万张标注图撑着,模型见过足够多的变化。但工业缺陷检测面对的是另一套逻辑:缺陷本身是“非自然”的,它可能是划痕、气泡、脏污、缺料、毛刺、色差,这些形态在自然图像里几乎不存在先验。更麻烦的是,很多缺陷的类间差异极小,比如“浅划痕”和“正常纹理”在灰度上可能只差几个像素值,而“深划痕”和“异物”在形状上又高度相似。
我见过一个典型的3C结构件项目,缺陷类别有七种,但其中四种在低倍率下肉眼都难分辨,标注员之间的一致性只有70%左右。这种数据拿去做通用检测,模型学到的其实是标注噪声。所以工业缺陷检测的第一原则是:不要把它当成通用目标检测的缩小版,它是一个独立的问题域。
另一个关键差异是样本分布。通用检测里,一张图可能同时出现多个类别,背景复杂但语义丰富。工业检测里,一张图往往只有一个或几个缺陷,背景高度重复,甚至同一工位拍出来的图,背景像素级对齐。这种“低多样性、高重复性”的数据分布,会让模型快速过拟合到背景纹理上,而不是缺陷本身。表现出来就是:训练集mAP很高,产线一上就漏检。
1.2 小样本训练的核心矛盾:信息量不足与过拟合
小样本训练在工业场景里不是“可选优化”,而是“默认前提”。一条产线刚上线时,缺陷样本可能只有几十张,甚至个位数。这时候如果直接拿YOLO从头训,模型会迅速记住这几张图的每一个像素,包括噪声。我试过用20张缺陷图训YOLOv8n,100个epoch后训练loss降到0.01,但验证集上几乎全漏。这就是典型的过拟合。
小样本训练的核心矛盾在于:模型需要足够的类内变化来学习不变性,但实际数据只提供了极少的视角、光照、形态变化。解决这个矛盾有两条路:一是数据侧扩充,二是模型侧约束。数据侧扩充不是简单旋转翻转,工业缺陷的形态有物理约束,比如划痕有方向性,气泡有圆形度,乱做增强会引入不存在的缺陷形态。模型侧约束则包括冻结主干、只训检测头、引入对比学习或异常检测分支等。
这里要提一个常见误区:很多人觉得小样本就是“少标一点”,于是把正常样本也砍到很少。实际上,正常样本在工业检测里是“负样本”,它的多样性直接决定了模型对背景的鲁棒性。正常样本可以大量采集,不需要标注,成本极低。所以小样本训练的正确姿势是:缺陷样本少而精,正常样本多而杂。
1.3 漏检控制的本质:从“检出来”到“不漏掉”
漏检控制在工业场景里的优先级远高于误检。原因很简单:误检可以人工复判,漏检直接流出到客户手里,可能是批量召回。所以工业检测的指标不是mAP,而是召回率优先下的精确率平衡。我见过一个项目,客户明确说“宁可误检10个,不能漏检1个”,这就是典型的漏检控制导向。
漏检的来源主要有四个:一是缺陷对比度太低,模型特征提取不到;二是缺陷尺寸太小,下采样后信息丢失;三是缺陷形态超出训练分布,模型没见过;四是后处理阈值设得太高,把低置信度的真缺陷滤掉了。这四个来源对应四种控制手段:特征增强、多尺度检测、异常检测兜底、阈值动态调整。
其中异常检测兜底是最容易被忽视但最有效的手段。YOLO是监督学习,它只能检出“训练时见过的缺陷类型”。但产线上总会出现新缺陷,或者训练集里样本极少的缺陷。这时候用一个无监督的异常检测分支(比如基于特征重构或密度估计)去兜底,可以显著降低漏检。我通常的做法是:YOLO负责高置信度缺陷,异常检测负责低置信度但偏离正常分布的区域,两者取并集后再做NMS。
1.4 方案选型:为什么是YOLO加异常检测的混合架构
选YOLO作为主检测器,理由很直接:工业场景对速度有硬要求,产线节拍通常要求单帧推理在10ms到30ms之间,YOLO系列在TensorRT加速下可以轻松做到。而且YOLO的生态成熟,从训练到部署的链路短,适合快速迭代。
但纯YOLO有两个硬伤:一是小样本下容易过拟合,二是对未知缺陷类型零召回。所以我在实际项目中会加一个异常检测分支。异常检测不依赖缺陷标注,只用正常样本训练,学习“正常长什么样”。推理时,任何偏离正常分布的区域都会被标记为疑似异常。这个分支的召回率很高,但精确率低,正好和YOLO互补。
具体架构上,我通常用YOLOv8或YOLOv11作为检测主干,在Neck部分引出一个轻量异常检测头。异常检测头可以用基于特征重构的方法,比如在Neck的P3和P4层做特征压缩再重构,计算重构误差。误差超过阈值的区域,即使YOLO没检出,也会被标记。这个设计的好处是共享主干特征,推理时只增加少量计算量,实测在T4上单帧增加不到2ms。
注意:异常检测分支的训练必须只用正常样本,且正常样本要覆盖产线上可能出现的各种光照、角度、批次变化。如果正常样本本身多样性不足,异常检测会把正常波动也当成异常,导致误检爆炸。
2. 小样本训练的核心细节与实操要点
2.1 数据采集与标注:少而精的标注策略
小样本训练的第一步不是训模型,而是把数据采好。工业缺陷检测的数据采集有几个硬约束:一是缺陷出现频率低,可能几千张图才有一个缺陷;二是缺陷形态受工艺影响,不同批次可能不一样;三是标注成本高,需要懂工艺的人来标。
我的做法是分三步走。第一步,先采一批正常样本,至少500张,覆盖不同光照、角度、批次。这批数据不标注,只用于异常检测分支和背景建模。第二步,针对已知缺陷类型,每种至少采30到50个实例。如果某些缺陷极少,可以用产线停机时的模拟缺陷补充,比如人工制造划痕、脏污,但要在标注时注明是模拟样本,训练时降低权重。第三步,标注时采用“双人交叉验证”,两个人标同一批图,不一致的拿出来讨论,统一标准。这一步很关键,工业缺陷的边界往往模糊,标注一致性直接决定模型上限。
标注格式上,我推荐用YOLO格式的txt,每行是class_id x_center y_center width height,归一化到0到1。对于小缺陷,建议把框放大10%到20%,给模型一点上下文。但不要放太大,否则会引入太多背景。另外,对于划痕这类长条形缺陷,可以用旋转框,但YOLO原生不支持旋转框,需要改成水平框或分割掩码。如果划痕方向很重要,建议用YOLOv8-seg做实例分割,输出掩码后再拟合方向。
2.2 数据增强:工业场景下的克制与针对性
数据增强在小样本训练里是双刃剑。用得好,可以扩充类内变化;用不好,会引入不存在的缺陷形态。工业场景下,我通常只用以下几类增强:
- 光照增强:随机调整亮度、对比度、Gamma,模拟产线光照波动。幅度控制在±15%以内,太大可能把正常纹理变成伪缺陷。
- 噪声增强:加高斯噪声或椒盐噪声,模拟传感器噪声。标准差控制在0.02以内。
- 几何增强:水平翻转、垂直翻转、小角度旋转(±10度)。注意,对于有方向性的缺陷(如划痕),垂直翻转可能改变缺陷语义,要慎用。
- Cutout:随机遮挡一小块区域,模拟灰尘或遮挡。遮挡面积不超过图像的5%。
绝对不要用的增强:大角度旋转、透视变换、MixUp、CutMix。这些在通用检测里有效,但在工业场景会破坏缺陷的物理形态。比如MixUp会把两个缺陷叠在一起,产生现实中不存在的缺陷类型,模型学了反而会混淆。
另外,我强烈建议用Mosaic增强,但要把概率调低。YOLO默认Mosaic概率是1.0,小样本下建议调到0.3到0.5。Mosaic可以把四张图拼成一张,增加背景多样性,但也会让缺陷变小,增加漏检风险。所以Mosaic用的时候,要配合多尺度训练,让模型适应不同尺寸的缺陷。
2.3 模型初始化与冻结策略:从预训练到微调
小样本训练不建议从头训。从头训需要大量数据,小样本下必然过拟合。正确的做法是用COCO或ImageNet预训练权重初始化,然后冻结主干,只训Neck和Head。冻结的层数取决于数据量:如果缺陷样本少于50张,冻结整个Backbone;如果50到200张,冻结Backbone的前80%;如果超过200张,可以只冻结前50%。
冻结的实现很简单,在YOLO的配置里把对应层的requires_grad设为False。但要注意,BatchNorm层在冻结时也要设为eval模式,否则running_mean和running_var会更新,破坏预训练统计量。我见过有人只冻了卷积层,没冻BN,结果训练时BN统计量被小样本带偏,验证集直接崩。
学习率方面,小样本微调要用小学习率。我通常用预训练时的十分之一到百分之一。比如YOLOv8默认初始学习率是0.01,小样本微调就用0.001到0.0001。优化器用SGD或AdamW都可以,但SGD更稳,AdamW收敛快但容易过拟合。Weight decay设0.0005,防止权重过大。
还有一个技巧是分层学习率:Backbone用更小的学习率(比如0.0001),Neck和Head用稍大的学习率(比如0.001)。这样既保护了预训练特征,又让检测头快速适应新任务。在Ultralytics的框架里,可以通过参数组实现,把不同层的参数分到不同组,设不同lr。
2.4 损失函数调优:针对漏检的加权策略
YOLO的损失函数由三部分组成:分类损失、定位损失、置信度损失。小样本下,分类损失容易过拟合,定位损失容易欠拟合。我的调优策略是:降低分类损失权重,提高定位损失权重,并对正样本加权。
具体来说,YOLOv8默认的损失权重是box=7.5, cls=0.5, dfl=1.5。小样本下,我会把cls降到0.3,box提到10.0,dfl保持1.5。这样模型更关注“框得准不准”,而不是“分类对不对”。因为小样本下分类边界本来就不清晰,强行学分类会过拟合。
另外,对于漏检控制,可以在置信度损失里对正样本加权。YOLO的置信度损失是BCE,正样本是那些和GT框IoU大于阈值的anchor。小样本下,正样本数量很少,梯度被负样本淹没。我通常会把正样本的损失权重乘以2到3倍,让模型更关注正样本。这个在Ultralytics里可以通过修改BCEWithLogitsLoss的pos_weight参数实现。
还有一个高级技巧是Focal Loss。虽然YOLOv8默认不用Focal,但小样本下可以手动加。Focal Loss通过调制因子降低易分样本的损失,让模型聚焦难分样本。对于工业缺陷,难分样本往往是低对比度或小尺寸缺陷,正好是漏检的重灾区。我试过在YOLOv8的cls损失里加Focal,gamma设1.5,召回率能提升3到5个点。
注意:损失函数调优不要一次改太多参数。每次只改一个,跑完验证集看指标变化。我通常先调box和cls的权重比,再调正样本加权,最后考虑Focal。改太多会不知道哪个参数起了作用。
3. 漏检控制的全流程实现
3.1 多尺度检测与特征金字塔优化
漏检的第一大来源是小缺陷。YOLO默认的检测头在P3、P4、P5三个尺度上做预测,对应8、16、32倍下采样。如果缺陷在原图里只有10个像素,到P3就只剩1个多像素,特征几乎消失。所以小缺陷检测必须加强浅层特征。
我的做法是在YOLO的Neck里增加一个P2检测头,对应4倍下采样。P2的特征图分辨率是P3的两倍,对小缺陷更敏感。但P2的语义信息弱,容易误检。所以P2头要配合更强的特征融合,比如用BiFPN或PANet的变体,把浅层细节和深层语义充分融合。
具体实现上,可以在YOLOv8的配置里加一层- [from: 2, number: 1, module: nn.Upsample, args: [2, 'nearest']],然后和Backbone的C2层拼接,再过一个C2f模块,最后接检测头。这样P2头就有了足够的语义。实测在PCB缺陷检测上,加P2头后小缺陷召回率从72%提升到89%。
但P2头会增加计算量。在T4上,640分辨率下,加P2头后单帧推理从8ms增加到11ms,仍然满足25帧每秒的要求。如果产线节拍更紧,可以只对ROI区域做P2检测,或者用动态分辨率,小缺陷多的时候用高分辨率,正常时用低分辨率。
另一个优化是特征金字塔的通道数。小样本下,通道数太多容易过拟合。我通常把Neck的通道数减半,比如从256降到128。这样参数量减少,泛化更好。但也不能减太多,否则特征表达能力不够。128是个比较平衡的值。
3.2 异常检测兜底:无监督分支的设计与融合
异常检测兜底是漏检控制的最后一道防线。它的核心思想是:不管YOLO检没检出来,只要某个区域偏离正常分布,就标记为疑似异常。这样即使YOLO漏了,异常检测也能兜住。
我常用的异常检测方法是基于特征重构的PatchCore变体。具体做法是:用预训练CNN(比如ResNet18)提取正常样本的特征,在特征空间里建立一个记忆库。推理时,对每个patch提取特征,计算它到记忆库的最近邻距离。距离超过阈值的patch就是异常。
但PatchCore推理慢,不适合产线实时。所以我做了轻量化:把记忆库压缩成高斯混合模型,每个高斯分量代表一种正常纹理模式。推理时只算马氏距离,速度提升10倍。在T4上,640分辨率下单帧异常检测只要3ms。
融合策略上,YOLO和异常检测的输出做加权框融合。YOLO的框有类别和置信度,异常检测的框只有异常分数。我通常设两个阈值:YOLO置信度高于0.5的框直接保留;YOLO置信度在0.1到0.5之间的框,如果异常分数也高,就提升为缺陷;YOLO没检出但异常分数极高的区域,标记为“未知缺陷”,报警人工复判。
这个融合策略的关键是阈值调参。我通常用验证集画PR曲线,找召回率优先的平衡点。比如要求召回率不低于99%,那就把YOLO阈值降到0.1,异常阈值降到0.3,让更多疑似区域进入复判。虽然误检会增加,但漏检能压到极低。
注意:异常检测分支的训练数据必须和YOLO的训练数据严格分开。正常样本不能包含任何缺陷,否则异常检测会把缺陷也当成正常。我见过有人图省事,用同一批数据训两个分支,结果异常检测完全失效。
3.3 后处理优化:NMS与置信度阈值动态调整
后处理是漏检控制的最后一步,也是最容易调的一步。YOLO默认的NMS IoU阈值是0.7,置信度阈值是0.25。小样本下,这两个值都要调。
NMS IoU阈值调低到0.5,可以保留更多重叠框。因为小样本下,模型对同一个缺陷可能输出多个框,IoU阈值太高会把这些框合并成一个,如果合并后的框位置偏了,反而漏检。调低到0.5,让更多框保留,后续再通过异常检测或人工复判筛选。
置信度阈值要动态调整。固定阈值的问题是:不同批次、不同光照下,模型的置信度分布会变。我通常用滑动窗口统计:统计最近100帧的置信度分布,取第5百分位作为动态阈值。这样如果产线光照变暗,模型整体置信度下降,阈值也跟着降,避免漏检。
还有一个技巧是类别特定阈值。不同缺陷类型的置信度分布不一样。比如划痕的置信度普遍偏高,脏污的置信度偏低。如果统一用0.25,脏污容易漏。所以我会对每个类别单独设阈值,用验证集调。划痕设0.3,脏污设0.15,缺料设0.2。这样每类的召回率都能上去。
后处理还有一个容易忽视的点是框的合并策略。对于大缺陷,模型可能输出多个小框,NMS后变成多个框。如果直接输出,人工复判时看到一堆框,体验很差。我通常加一步框聚类:把IoU大于0.3的框聚成一类,取并集作为最终框。这样大缺陷输出一个框,小缺陷保持独立。
3.4 在线学习与模型迭代:产线反馈闭环
漏检控制不是一次性的,而是持续迭代的过程。产线上总会出现新缺陷,或者模型在某个批次上表现下降。所以必须建立在线学习闭环。
我的做法是:产线部署时,加一个难例挖掘模块。所有被人工复判为“漏检”的图,自动保存到难例库。每天或每周,把难例库里的图加入训练集,重新微调模型。微调时只训Neck和Head,Backbone冻结,学习率设0.0001,跑20到30个epoch。这样模型能快速适应新缺陷,又不会遗忘旧缺陷。
但在线学习有个风险:如果难例库里有标注错误,模型会学偏。所以难例入库前要人工确认。我通常设一个规则:只有连续三次被复判为漏检的图,才进入难例库。这样过滤掉偶发错误。
另一个技巧是模型集成。产线上同时跑两个模型:一个是稳定版,每周更新一次;一个是实验版,每天更新。两个模型的输出做投票,只有都检出的才直接放行,有分歧的送人工复判。这样既保证了稳定性,又能快速验证新模型。
4. 常见问题与排查技巧实录
4.1 训练不收敛或BN崩溃的排查
小样本训练最常见的问题是BN崩溃。表现是训练几个epoch后,loss突然变成NaN,或者验证集指标断崖式下跌。原因通常是batch size太小,BN的统计量估计不准。YOLO默认batch size是16,小样本下可能只有4或8,BN的running_mean和running_var波动很大。
解决方法有三个:一是改用GroupNorm或LayerNorm,不依赖batch统计量。YOLOv8支持把BN换成GN,在配置里改norm_type: gn即可。二是用SyncBN,多卡同步统计量,但单卡没用。三是冻结BN,用预训练的统计量。我通常用第一种,GN在小batch下更稳。
另一个原因是学习率太大。小样本下,梯度噪声大,学习率太大会让权重震荡。我通常先用0.001跑10个epoch,看loss曲线。如果loss震荡不下降,就降到0.0001。如果还是不行,就检查数据标注,看有没有框超出图像边界,或者宽高为0的无效框。
还有一个隐蔽的问题是数据不平衡。如果正常样本远多于缺陷样本,模型会偏向预测背景。YOLO的损失函数里,负样本的置信度损失会占主导。解决方法是加正样本权重,或者用Focal Loss。我通常先统计正负样本比例,如果超过1比100,就加正样本权重。
4.2 漏检与误检的平衡调参
漏检和误检是一对矛盾。降低漏检通常会增加误检,反之亦然。调参的目标是找到业务可接受的平衡点。我的做法是画DET曲线:横轴是误检率,纵轴是漏检率,曲线上的每个点对应一组阈值。然后根据业务要求选点。比如客户要求漏检率低于1%,那就选曲线上漏检率1%对应的误检率,看是否可接受。
如果曲线整体不理想,说明模型本身不行,调阈值没用。这时候要回到模型侧,检查是不是小样本过拟合,或者异常检测分支没起作用。我通常先看验证集上的PR曲线,如果PR曲线整体偏低,就是模型问题;如果PR曲线还行但产线上不行,就是域偏移问题。
域偏移是工业检测的常见问题。训练集和产线的光照、角度、批次不一样,模型表现会下降。解决方法是用域适应:在产线上采一批无标注图,用自监督学习微调模型。或者用风格迁移,把训练集的风格迁移到产线风格。我通常用前者,因为自监督不需要标注,成本低。
4.3 部署性能优化:TensorRT加速与多路并发
工业产线通常要求多路并发。比如一条产线有4个工位,每个工位一个摄像头,要求同时检测。这时候单帧推理时间要除以路数。如果单帧8ms,4路就是2ms每路,T4上很难做到。所以必须优化。
优化手段有三个:一是用TensorRT加速。YOLOv8导出ONNX后,用TensorRT的FP16或INT8量化。FP16通常能提速1.5到2倍,INT8能提速3到4倍,但精度会降。我通常先用FP16,如果速度不够再考虑INT8。INT8需要校准集,用产线上的正常样本做校准,精度损失可以控制在1%以内。
二是动态批处理。把多路图像拼成一个batch,一次推理。T4支持batch推理,batch=4时,单帧时间从8ms降到5ms。但batch太大会增加延迟,通常batch=4或8比较平衡。
三是ROI裁剪。如果缺陷只出现在图像某个区域,可以只裁ROI做推理,减少计算量。比如PCB检测,缺陷只在板子区域,板子占图像60%,裁掉边缘后计算量减少40%。
多路并发的实现上,我通常用多进程加共享内存。每个摄像头一个进程,负责拉流和解码,解码后的图像放到共享内存。推理进程从共享内存取图,拼batch后送TensorRT。这样解码和推理并行,吞吐量能提升2到3倍。
4.4 常见问题速查表
| 问题现象 | 可能原因 | 排查方法 | 解决方案 |
|---|---|---|---|
| 训练loss变NaN | BN崩溃或学习率太大 | 检查batch size和lr | 换GN,降lr到0.0001 |
| 验证集mAP高但产线漏检 | 域偏移或过拟合 | 对比训练集和产线图分布 | 域适应微调,加异常检测 |
| 小缺陷漏检 | P3特征丢失 | 可视化特征图 | 加P2检测头,多尺度训练 |
| 误检多 | 异常检测阈值太低 | 看误检区域的异常分数 | 提高异常阈值,加正常样本 |
| 推理速度慢 | 未量化或batch太小 | 测单帧时间 | TensorRT FP16,动态batch |
| 新缺陷零召回 | 监督学习局限 | 看新缺陷是否在训练集 | 异常检测兜底,在线学习 |
| 标注一致性差 | 缺陷边界模糊 | 双人交叉验证 | 统一标注标准,放大框 |
| 模型更新后旧缺陷漏检 | 灾难性遗忘 | 对比新旧模型输出 | 难例回放,冻结Backbone |
提示:这张表是我从多个项目里总结的,但每个项目情况不同。遇到问题先按表排查,如果解决不了,再回到数据侧看标注质量。我见过80%的“模型问题”其实是标注问题。
4.5 实操心得:那些文档里不会写的经验
第一个心得是不要迷信mAP。工业检测的mAP和产线表现往往脱节。我见过mAP 0.95的模型,产线上漏检率5%。原因是mAP是在验证集上算的,验证集和产线分布不一样。所以我在项目里会建一个产线模拟集:用产线摄像头实拍一批图,人工标注后作为最终验收标准。这个集合不参与训练,只用于验收。
第二个心得是异常检测的阈值要按工位调。不同工位的背景、光照、缺陷类型不一样,统一阈值效果差。我通常每个工位单独训一个异常检测模型,或者至少单独调阈值。虽然麻烦,但效果提升明显。
第三个心得是模型集成比单模型稳。产线上我通常跑两个模型:一个YOLO,一个异常检测。两个模型的输出做融合。如果只有一个模型,一旦模型在某批次上表现下降,整条线就崩了。两个模型互为备份,稳定性好很多。
第四个心得是标注质量比模型结构重要。我试过用同样的YOLOv8,一组用高质量标注,一组用低质量标注,mAP差15个点。所以小样本项目里,我宁愿花三天标100张图,也不愿花三天调模型。标注时用放大镜看,边界要精确到像素,不确定的缺陷宁可标“不确定”,也不要瞎标。
第五个心得是产线部署前一定要做压力测试。我见过模型在实验室跑得好好的,产线上跑一天就崩了。原因是产线光照会随时间变化,早上和下午的光照不一样。所以部署前要连续跑24小时,看模型在不同时段的表现。如果波动大,就要加光照归一化,或者用动态阈值。
第六个心得是保留人工复判通道。再好的模型也有漏检,所以产线上一定要有人工复判。我的做法是:模型检出的缺陷,置信度高于0.8的直接报警;0.5到0.8的送人工复判;低于0.5的如果异常检测分数高,也送复判。这样既保证了效率,又不会漏掉低置信度的真缺陷。
第七个心得是模型版本管理。每次更新模型,都要记录训练数据、超参数、验证指标。我通常用MLflow或WandB做实验管理。这样如果新模型表现下降,可以快速回滚到旧版本。没有版本管理,模型迭代就是一团乱麻。
第八个心得是不要过度追求SOTA。工业检测里,YOLOv5和YOLOv8的差距可能只有1到2个点,但部署复杂度差很多。我通常选成熟稳定的版本,而不是最新的。YOLOv8的生态好,文档全,遇到问题容易查。YOLOv11虽然新,但有些算子TensorRT支持不好,部署时坑多。
第九个心得是数据增强要可视化检查。我见过有人加了增强后,缺陷被旋转到图像外,或者被Cutout遮住,模型学了个寂寞。所以每次加新增强,都要把增强后的图可视化出来看。确保缺陷还在,且形态合理。
第十个心得是产线节拍决定模型选型。如果节拍要求10ms以内,只能用YOLOv8n或YOLOv11n,且必须TensorRT INT8。如果节拍宽松到30ms,可以用YOLOv8m,精度更高。所以选型前先问产线节拍,不要盲目上大模型。
最后再分享一个小技巧:用正常样本做背景建模。工业场景的背景高度重复,可以用正常样本算一个平均背景,推理时先减背景,再送模型。这样缺陷的对比度会增强,小缺陷更容易检出。我试过在LCD缺陷检测上用这招,召回率提升8个点。减背景的计算量很小,用OpenCV的absdiff就行,几乎不增加延迟。
这个内容后续还可以这样扩展:一是把异常检测分支换成基于Transformer的方法,比如用ViT做特征重构,可能对复杂纹理更鲁棒;二是引入主动学习,让模型自己挑出最有价值的样本送标注,减少标注成本;三是做跨产线的迁移学习,把一个产线训好的模型快速迁移到新产线,减少冷启动时间。这些方向我都在探索,有进展再分享。