《YOLOv11 实战:从入门到深度优化》015、工业缺陷检测实战:小目标、复杂背景场景优化

张开发
2026/4/12 12:33:18 15 分钟阅读

分享文章

《YOLOv11 实战:从入门到深度优化》015、工业缺陷检测实战:小目标、复杂背景场景优化
015、工业缺陷检测实战小目标、复杂背景场景优化一、深夜产线的报警日志上周三凌晨两点产线质检系统又误报了。日志里写着“PCB板焊点检测连续12个误判漏检3处真实缺陷。”我盯着监控画面里那些芝麻大的焊点背景是杂乱的反光铜箔和丝印字符——典型的工业场景小目标、复杂背景、光照不均。用默认参数的YOLOv11跑出来的结果要么把字符当成缺陷要么把真实划痕给忽略了。这不是模型不够强是场景太“脏”了。二、小目标检测别只盯着高分辨率很多人第一反应是拉高输入分辨率从640直接怼到1280。这招有用但代价太大。推理速度掉一半显存直接报警。更麻烦的是背景杂波也跟着放大误检率可能不降反升。# 模型初始化时这样改modelYOLO(yolo11n.pt)model.overrides[imgsz]896# 取个折中别太极端model.overrides[conf]0.25# 初始置信度调低后面再过滤# 数据增强里必须加小目标专用增强# 这是实战中攒出来的配方augmentation{mosaic:0.8,# 马赛克增强对小目标有效mixup:0.3,# 但别开太高否则目标糊成一片copy_paste:0.3,# 小目标复制粘贴增强实测有效hsv_h:0.015,# 色相抖动要轻工业场景颜色很重要hsv_s:0.7,# 饱和度可以大胆调模拟不同光照hsv_v:0.4,degrees:5.0,# 旋转角度别太大PCB板不会倒着拍translate:0.1,scale:0.2,# 缩放幅度控制住别把焊点缩没了shear:2.0,}注意看那个copy_paste增强这是YOLOv11里藏的好东西。它会随机复制一些小目标贴到图上相当于给正样本加权重。但有个坑如果原图背景复杂复制时可能把背景缺陷也复制了建议先在干净数据集上试效果稳定后再上复杂场景。三、复杂背景教模型“看该看的地方”工业场景的背景往往比目标更有纹理。比如检测金属划痕背景可能是磨砂表面检测污渍背景可能是木纹。模型容易学会用背景纹理当特征换批原料就崩。# 数据标注阶段就得动手# 1. 把背景区域标为“困难负样本”# 2. 或者干脆在背景上画ignore区域如果标注工具支持# 训练时用上Class权重class_weights{0:1.0,# 背景类如果有1:3.0,# 缺陷类给更高权重2:1.5,# 其他类别}# 但别拍脑袋设权重先跑一遍看各类别的召回率# 哪类漏检多再针对性加权重# 模型结构微调需要改源码这里给思路# 1. 在Backbone浅层加SE注意力模块# 让模型学会关注空间重要区域# 2. 把SPPF换成SPPFCSPC提升感受野融合# 3. Head里用上解耦头分类和回归任务分开有个土办法但有效把训练集里所有背景块裁剪出来作为负样本单独训练一个二分类器。推理时先用这个分类器过滤一遍背景区域相当于做个预筛。这招在芯片丝印检测上帮我降了15%的误报率。四、损失函数调参别迷信默认值YOLO的损失函数由三部分组成分类损失、定位损失、目标损失。小目标场景下定位损失权重应该提高。# 修改loss.py里的权重示例值需调参loss_weights{box:7.5,# 默认7.5可提到8.0-9.0cls:0.5,# 分类损失权重可以降小目标分类难dfl:1.5,# Distribution Focal Loss权重}# 重点调这个dfl_loss# 它是v11里针对小目标定位的改进# 如果目标尺寸小于32x32把dfl权重提到2.0试试实际调试时我习惯用TensorBoard盯着损失曲线。小目标场景下cls_loss往往震荡大box_loss下降慢。如果训练中期box_loss还在高位徘徊试试把学习率降为原来的0.5再多训20个epoch。小目标定位需要模型“耐心”学。五、后处理优化三分模型七分后处理工业场景最大的优势是你知道目标大概在哪儿。PCB焊点不会出现在板子外面划痕不会出现在logo上。把这些先验知识写成规则比调模型参数管用。defpost_process(pred,img_info): pred: 模型原始输出 img_info: 包含图像尺寸、ROI区域、屏蔽区域等 results[]fordetinpred:# 规则1尺寸过滤ifdet[width]3ordet[height]3:# 小于3像素的忽略continue# 规则2位置过滤ifnotin_roi(det[bbox],img_info[roi]):# 不在感兴趣区域continue# 规则3上下文逻辑# 例如焊点附近必须有引脚ifdet[cls]solder:ifnothas_pin_nearby(det[bbox],pred):det[conf]*0.5# 置信度打折不直接删除# 规则4多缺陷关联# 如果检测到多个同类缺陷在一条线上可能是划痕ifis_line_pattern(det,pred):det[conf]*1.2# 置信度增强results.append(det)# 最后再用NMS阈值可以设宽松些resultsnms(results,iou_thresh0.4)# 默认0.45小目标可降到0.4returnresults这套规则引擎是我们项目里的“压舱石”。模型迭代时可以暂时关闭规则看纯精度但上线时必须打开这是工业场景的护城河。六、数据还是数据说一千道一万工业场景最缺的是坏样本。产线跑一个月可能就收集到几十个真实缺陷。怎么办# 缺陷生成大法谨慎使用# 1. 物理仿真用Blender做划痕、凹坑的3D渲染# 2. 2D合成用PS手工制作缺陷再贴到正常品上# 3. 对抗生成训练一个缺陷生成GAN# 但注意合成数据必须做domain adaptation# 简单做法加噪声、加模糊、调色温# 高级做法用CycleGAN做风格迁移# 这里踩过大坑# 直接拿干净背景上画的缺陷训练模型会过拟合到合成痕迹# 必须让合成缺陷“融”进真实图片里我的经验是先用100个真实缺陷1000个合成缺陷训练初版模型然后用这个模型去跑历史数据做困难样本挖掘。往往能筛出一些人工没注意到的疑似缺陷交给老师傅确认后就变成了高质量坏样本。七、部署时的内存陷阱训练时跑得好好的部署到工控机上就OOM内存溢出。工业现场常用Jetson、树莓派这类边缘设备内存紧张。# 部署优化清单# 1. 用TensorRT或ONNX Runtime别用原生PyTorch# 2. 量化到FP16小目标场景精度损失很小# 3. 启用GPU内存池复用# 4. 输入分辨率降到768x768如果允许# 5. 批处理大小设为1工业检测都是单张流# 模型剪枝要小心# 小目标检测需要细粒度特征别乱剪浅层# 建议从Head部分开始剪Backbone尽量保留有个细节工业相机拍出来的图往往带EXIF信息解码时如果没正确处理可能多占几十MB内存。预处理阶段记得先转成RGB数组再喂给模型。八、给后来者的几句经验谈先验大于训练把你对工艺的了解写成规则比收集一万张图都有用。老师傅看一眼就知道“这里不可能有缺陷”的经验模型得学很久。小目标检测数据标注质量决定上限框偏两个像素对小目标就是50%的误差。标注时放大到400%再标验收时同理。复杂背景下颜色空间比RGB好用试试转到LAB空间用L通道做亮度归一化用A、B通道做颜色分离。金属反光问题能缓解一半。模型别追新YOLOv11刚出时我在产线上硬扛了三个月才升级。工业场景稳定第一新版本先在其他项目踩坑。留个“人工复核”接口无论模型多准设计时都要留个按钮让操作工能一键把可疑图片发给老师傅复核。这是技术人的谦卑。凌晨四点的产线机器重新跑起来了。监控屏幕上绿色框稳稳地套住那些芝麻大的焊点缺陷误报栏终于清零。我关掉调试终端想起一位老工程师的话“工业AI不是比谁模型新是比谁更懂生产。”把这句话送给所有在工厂里调参的夜晚。

更多文章