ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

基于深度学习的PCB板缺陷检测系统实战:从模型训练到部署

基于深度学习的PCB板缺陷检测系统实战:从模型训练到部署

PCB板缺陷检测这个方向,这几年热度一直没降过。制造业质检场景里,AOI(自动光学检测)设备早就普及了,但传统视觉方案的底子摆在那里:光源打光的角度要反复调、特征阈值靠工程师拍脑袋定、换一款板子或者换一条产线就得重新标一遍参数。时间一长,产线上的工程师基本都清楚这种事——不是设备不行,是传统方案适应不了多品种、小批量的生产节奏。我见过很多厂子的质检环节卡在这上面,漏检率压不下去,误检率高的时候一天能报几百个假缺陷,让复判工人骂娘。

我最近在做的就是一套基于深度学习的PCB板缺陷检测系统,从数据处理、模型训练、性能评估到界面部署完整走了一遍。这篇文章不打算写那种“复制粘贴就能跑”的教程,更多是把整个项目从零到落地的思路、参数怎么定、哪些地方容易翻车讲清楚,给后面要在这条路上淌一遍的人一点参考。系统本身不算复杂,核心就是目标检测那一套,但把工程细节处理好,和把模型训出来,是两个完全不同的难度。这篇文章主要面向三类人:准备做相关课题的学生、在产线上想引入AI质检的工程师、以及单纯对工业视觉落地感兴趣的人。

1. 项目整体思路与模型选型分析

1.1 PCB质检的现状与核心痛点

PCB蚀刻完成之后的缺陷,常见的大类就那么几种:短路、断路、缺口、针孔、毛刺、余铜。传统AOI设备用的方法,说白了就是一通图像处理操作——灰度化、二值化、找轮廓、做模板差分,然后拿一个固定阈值去卡。这套逻辑在电路板设计固定、来料位置和角度都受控的情况下,确实能跑得不错,但在今天这个多品种小批量的生产方式下就露怯了。板子一换,线路特征全变,旧参数马上失效,调试工程师得重新花好几天打光、调阈值。更麻烦的是,很多缺陷本身对比度很低,缺一点点铜箔、多一点点毛刺,在灰度图上和正常纹路混在一起,传统算法根本分不出来。

深度学习方案的思路不一样。我们把手动设计特征这件事换掉了,让网络自己从数据里学什么是“正常”、什么是“缺陷”。实际效果就是,面对同一块板子,传统方案需要一个一个写规则,深度方案只需要标注一批图,剩下的交给训练。换产线换板子也没那么痛苦,重新标注、重新训练就行,速度比调传统算法快一个量级。

但深度学习也不是没有代价。它吃数据,吃算力,吃标注质量。这三样东西在项目里每一个都不可缺席,任何一个环节掉链子,最后模型的mAP都会直接反映出来。所以在项目启动之前,先把目标定清楚:这是一个离线检测场景,还是产线实时检测?如果是离线抽检,对推理速度的要求没那么苛刻;如果是产线在线检测,单张图必须在几百毫秒内出结果。我这次设定的目标是适配离线半自动检测,图片输入从工位读取,推理时间控制在单张0.1秒以内,这个量级用GPU可以达到,硬件成本也能接受。

1.2 为什么不用传统视觉方案硬扛

传统方案在某些固定场景下其实很好用,这是实话。比如板子的mark点定位、尺寸测量,这些用OpenCV的轮廓查找和几何计算已经做得很成熟。但一旦到了缺陷识别这个层面,传统方案的脆弱性就暴露了。核心原因是:缺陷样本的形态千奇百怪,短路的形状可能是一条线,也可能是一块铜箔粘在两个焊盘之间;缺口可能是一个角,也可能是半圆形的凹坑。你很难用有限的几个几何特征把这些形态全部覆盖住,而深度学习模型天然就不会去死记某一个模板,它学的是“语义”层面的特征。

我在实际对比中也验证了这一点。用同样一批图,传统Canny边缘+差分找缺陷的方案,对明显的大面积短路检测率还行,一旦遇到细小的针孔、微弱的余铜,漏检率就直线上升。而深度模型在训练充分的前提下,对这类小目标的鲁棒性要高很多。还有一个细节是光照鲁棒性。传统方案对打光非常敏感,光源稍微偏一点、板子表面反射有差异,检测结果就飘了。深度学习模型只要训练数据里有多样化的亮度样本,对光照的容忍度就会大幅提升,这在产线环境里非常宝贵,毕竟现场的光照条件不可能像实验室那么稳定。

1.3 目标检测框架怎么选:YOLO还是两阶段模型

当前做缺陷检测的主流选择,不外乎YOLO系列、SSD、Faster R-CNN这几条路线。我第一次做类似项目时吃过亏,一开始用的Faster R-CNN,觉得两阶段模型精度上线高,小目标检测理论上更强。但实际上训练速度慢、调参复杂,而且对数据量的需求比YOLO更大。后来换到YOLO系,真香了。YOLOv5/v8这一系,社区活跃、资料多、部署方便,一套流程走下来非常省心,这对项目进度来说是决定性的。

具体到YOLOv5和YOLOv8之间选哪个,我个人的建议是:如果团队对YOLOv5的配置非常熟,用v5完全没问题,它的生态非常成熟,各类工业项目的踩坑经验一搜一大把;如果是从零开始,直接用v8也行,更现代的训练接口、更好用的数据增强策略。我在这个项目里用的是YOLOv5的6.0版本,因为对应的部署文档和源码配套最完善,网上能找到的针对PCB缺陷检测的参考也最多,遇到问题更容易排查。

模型的尺寸选择也很关键。YOLOv5有n/s/m/l/x五种规格,我在项目里优先测试了s和m两个版本。s模型参数量小、速度快,但小目标的召回率稍微弱一点;m模型在精度上有明显提升,代价是推理时间增加。最终我选择了YOLOv5m,因为PCB板的缺陷特征通常比较细微,在640x640的输入尺寸下,过多依赖s模型往往会漏掉那种只有几十个像素的小缺陷。当然,如果你们的显卡性能很强,直接上l模型也不是不行,但收益边际会递减,训练时间却翻倍。

2. 数据准备与预处理:决定缺陷检测上限的关键环节

2.1 缺陷类型梳理与标注规范

模型的性能上限不是由模型本身决定的,而是由数据决定的。这句话在缺陷检测项目里特别真实。没有好的数据,再先进的网络结构也无济于事。我们在项目里的第一步就是梳理缺陷类型。按行业常见的分类,我把目标定为六个类别:short(短路)、open(断路)、hole(针孔)、missing(缺口)、burr(毛刺)、copper(余铜)。这六类基本覆盖了蚀刻环节的绝大多数缺陷。

标注环节用的是LabelImg和LabelStudio这两个工具,前者更轻量,适合一张图一张图地框;后者适合团队协作。标注格式我统一转成了Pascal VOC的XML格式,再通过脚本转成YOLO需要的txt格式,每条记录是“类别ID + 归一化中心坐标 + 归一化宽高”。

这里有一个非常容易忽视的坑:PCB板缺陷的尺寸差异极大。一个大的短路缺陷几乎占满整张图,而一个针孔可能只有几十乘几十个像素。标注的时候如果只图省事,把缺陷粗略地框一个大框,模型的定位精度会非常差。我要求标注的时候尽可能贴着缺陷的实际边缘画框,宁可多花时间也不能让框放大或缩小,否则后续训练出来的模型边框预测偏差很大。

数据来源部分是产线历史积累的缺陷样本,部分是模拟的不良板拍摄。这里要多说一句,数据不能只收集缺陷样本,还得把大量正常的板子图加进去。目的有两个:一是让模型学会区分“这是什么缺陷”和“这是不是缺陷”,二是防止模型产生偏向性,看到所有图都倾向于报缺陷。正常样本我按大约3:7的比例配比,缺陷图占三成,这样既有正样本学到特征,又不至于让模型过于激进。

2.2 数据增强策略与实战配置

数据量不足是所有工业视觉项目都要面对的现实。PCB缺陷样本不像互联网图片可以海量下载,每一张缺陷图都要等产线真实出现不良才能拍到。所以数据增强不是可选项,而是必选项。

我用的增强策略分为两块:常规增强和特殊增强。常规增强包括随机翻转、旋转90°/180°、平移、缩放、HSV颜色扰动、亮度对比度扰动。这些操作能提升模型的泛化能力,让模型对拍摄角度、光照变化不敏感。特殊增强用的是Mosaic——把四张图拼成一张大图再训练,这个操作可以大幅提升模型对中小目标的检测能力,因为每张图在Mosaic里都会被缩小,小尺寸缺陷在缩小后的图片里依然清晰可辨,模型被迫去学习更精细的特征。

增强相关的参数,我在复现给其他人的时候一般建议这样设置:

  • 翻转概率:0.5(水平翻转和垂直翻转都打开)
  • HSV扰动:H 0.015、S 0.7、V 0.4,这个数值区间比较温和,不会产生颜色严重失真的问题
  • 旋转角度:-5°到+5°,太大的角度在PCB这种规则几何场景反而有害
  • Mosaic:训练前中期打开,最后50个epoch关掉,让模型在接近真实数据分布的图片上做微调

这个配置不是随手拍的,是我试错试出来的。一开始旋转角度给了30°,结果模型对正常板子的检测都开始飘——因为板子的走线方向本来就是明确的,过度旋转破坏了真实数据的分布特征。后来改回5°以内,效果立刻稳定了。

2.3 数据划分与文件目录组织方式

数据划分这块,很多新手习惯用随机的train/val/test划分,但在工业项目里这不够。PCB板的拍摄经常会有一批板子来自同一块母板,图案相似性极高。如果把相似图片随机分到训练集和验证集,模型会“作弊”——它在训练时已经记过类似图案了,验证指标虚高,换上全新的板子立即翻车。

所以我在划分时按批次分组,一批次的图片整体分到同一侧,然后再按7:2:1的比例切成训练、验证、测试三份。这样能真实反映模型面对新板子时的表现,测试集的mAP才是有参考价值的。

目录组织方面,我按YOLOv5的默认方式建了data目录,内部结构是这样的:

datasets/ ├── PCB_defect/ │ ├── images/ │ │ ├── train/ │ │ ├── val/ │ │ └── test/ │ ├── labels/ │ │ ├── train/ │ │ ├── val/ │ │ └── test/ │ └── pcb_defect.yaml

pcb_defect.yaml是数据配置文件,里面指定类别数量和类别名称。这个文件在训练时会被模型反复读取,名称顺序必须和标注文件里的类别ID严格一致,差一位就全乱了。我见过有人把类别顺序排错,模型训练出来检测结果张冠李戴,排查了三天才发现是yaml文件里的名称顺序写错了。这一点值得反复提醒。

3. 模型训练过程与关键参数详解

3.1 训练环境配置与依赖清单

训练环境是整个项目的地基。我用的环境组合是:Ubuntu 20.04、Python 3.8、PyTorch 1.10、CUDA 11.2、显卡是单张8GB显存级别的卡。这个配置在现在的视角看不算高,但对这类数据集规模来说完全够用。

环境搭建的坑主要出在版本匹配上。PyTorch、CUDA、cuDNN三者必须配套,否则经常出现装了包但torch.cuda.is_available()返回False的情况。建议直接用Anaconda创建独立环境,然后从PyTorch官方渠道安装对应版本的组合。如果要用GPU推理和训练,务必在安装完成后跑一段小的张量运算验证GPU调用是否正常,不要等到训练开始才发现环境有问题,那会浪费大把时间。

部署依赖方面,requirements.txt里需要包含torch、torchvision、opencv-python、numpy、matplotlib、PyYAML、tqdm等常用包。如果有绘制网络结构图的需求,还可以加上graphviz和pydot。注意opencv一定要安装opencv-python而不是opencv-contrib-python,后者体积大且容易和YOLOv5自带的某些图像处理工具冲突。

3.2 训练参数选择与Loss变化曲线分析

训练参数直接决定模型收敛速度和质量。我这次项目使用的核心参数如下:

  • 输入尺寸:640x640
  • batch size:16(8GB显存刚好够用,如果报OOM则降到8)
  • 初始学习率:0.01(SGD优化器)
  • 权重衰减:0.0005
  • 动量:0.937
  • 训练轮次:300 epochs
  • 预热轮次:3 epochs

学习率策略用的是cosine annealing,训练后期学习率会平滑下降,这对收敛到更优解有帮助。切换到AdamW也能跑,但YOLOv5仓库默认的SGD优化器配合上述参数已经调得比较成熟,非必要不建议换。Loss曲线这块,YOLOv5会同时输出box_loss、obj_loss、cls_loss三条曲线。正常的收敛趋势是三者都随epoch增加而下降,最后趋于平缓。如果发现某个loss持续震荡不下降,基本可以断定是数据里有标注错误或类别不均衡,先去查数据,不要死磕网络结构。

训练日志中还有一个容易误导人的指标——P、R、mAP。不要被某个epoch的峰值mAP迷惑,模型训练过程中,mAP在某个epoch突然冲到0.9然后又掉回0.7是常见现象,尤其是使用Mosaic增强的时候。正确的做法是看最后几十个epoch的稳定值,或者干脆启用YOLOv5自带的best权重保存机制,它会自动保留验证集mAP最高的权重,最后直接用best.pt测试就行。

3.3 性能评估:mAP、精确率、召回率如何权衡

评估模型好坏,不能只看一个指标,要多维度结合。mAP50表示IoU阈值为0.5时的平均精度,这个指标在实际工业落地中最贴近人的感知;mAP50:95则是更严格的评价,它综合了不同IoU阈值的精度,学术上更严谨,但工业上一般不以它作为绝对标准。

我练完模型后记录的核心数据大致是这样的:

  • mAP50:0.91
  • mAP50:95:0.63
  • 精确率:0.89
  • 召回率:0.87
  • 单张推理耗时:约38ms(GPU)

精确率和召回率的权衡在PCB质检场景里要特别留意。产线缺陷检测最怕的不是误检而是漏检——漏掉一个缺陷,不良品流到下一工序,后续维修成本和客户投诉风险远高于多看一次。所以训练时我通常会把置信度阈值放低一点,默认0.35,通过提高召回率来兜住漏检率。代价是误检率上来一点,但这可以通过复判工位的二次筛选消化掉,总成本反而更低。

类别层面的mAP也值得逐类看。如果某一类缺陷mAP明显低于整体水平,多半是这类缺陷的样本数量太少,或者标注质量有问题。我当时的“针孔”类别样本量最少,mAP只有0.72,后来专门补充了一批针孔的近景图和增强图,才勉强追到0.85。数据不均衡的问题会在评估阶段高概率暴露,不用急,补数据比换模型有效得多。

4. 系统部署与可视化界面实现

4.1 推理代码的工程化改造

训练和部署在工程上是两回事。训练脚本要考虑灵活性和可调试性,部署脚本只关心两件事:快速加载模型、准确输出结果。我把YOLOv5的detect.py做了一次精简,抽离出核心推理逻辑,写成了一个独立的推理模块。加载训练好的best.pt,传入一张图片,返回每个检测框的坐标、类别和置信度,这个模块就是整个系统的推理核心。

推理时有一些参数要提前固定下来,比如置信度阈值和NMS的IoU阈值。我在多次测试后确定:

  • 置信度阈值:0.35
  • NMS IoU阈值:0.45

置信度阈值降到0.35以下虽然能多召回几个低置信度目标,但误报的数量会不成比例地上升。把阈值设成0.35是我在漏检率和误检率之间找到的一个平衡点。如果后续换了一组数据,这个值大概率要重新标定,测试几个候选值后选一个在非缺陷图上误报最少、在缺陷图上召回最多的。

推理速度方面,如果追求极限性能,可以把训练好的权重导出成TorchScript格式,再配合TensorRT做FP16精度量化,单张图可以再降到15ms左右。不过这个优化的代价是环境配置复杂度上升,部署文档也要跟着多写一大截。我在项目里保留了基础PyTorch推理版本,同时提供了一个TensorRT优化说明,让用户按需选用。

4.2 UI界面设计与交互流程

一个只有训练脚本没有界面的系统,对不是开发背景的产线用户来说几乎不可用。所以这个项目里我配了一个桌面可视化界面,技术栈用的是PySide6(Qt)。界面不追求花哨,突出能用、够用、不卡。

界面核心功能是三个模块:图片加载、单图检测、批量文件夹检测。

图片加载支持jpg、png、bmp等常见格式,选择图片后立即在预览区显示。点击“开始检测”按钮,系统加载模型对当前图进行推理,检测结果会以彩色框叠放在原图对应位置,框的颜色按类别区分,右上角标注置信度。左侧栏同步显示当前图片的缺陷数量统计和每个缺陷的具体信息。批量检测功能适合处理一个文件夹内的所有图片,检测完成后自动生成CSV报告,包含每张图的文件名、检测到的缺陷类别、置信度、坐标位置、判定结果。这个CSV是给产线复判人员用的,他们可以直接按报告筛选存疑图片人工复核,比一张一张看图效率高得多。

界面设计上有一个细节,值得反复强调:检测结果的展示速度不能受GPU推理速度限制。如果每检测一张图都同步刷新界面的画框操作,界面会明显卡顿。我在实现时把推理放在独立线程,主界面线程只负责显示结果,检测期间界面还能自由操作。线程之间的数据传递用信号槽机制,不会阻塞界面响应。

4.3 部署文档中的关键环境配置说明

部署文档看起来像是个锦上添花的东西,实际上它是整个项目能否被顺利复现的核心。我写部署文档时按这个顺序组织内容:硬件环境说明、软件环境准备、依赖安装、权重文件放置、快速上手示例、常见错误对照。

硬件环境需要写清楚最低配置建议。按我的测试,CPU推理也能跑,但单张图耗时在1秒以上,面对批量检测会很吃力。所以建议的配置是:CPU至少是几年前的8核处理器,内存16GB以上,如果有GPU则建议专属显存6GB以上的独立显卡。如果用户只有纯CPU机器,也能运行界面,只是批量检测耗时会长很多。

软件环境方面,文档中详细写了Python版本、Anaconda创建环境的命令、PyTorch安装命令、requirements.txt的安装方式。权重文件需要放到项目指定目录,目录路径在配置文件中写明了,用户不需要去改代码。快速上手部分给了两个命令:一个命令用于启动界面,一个命令用于命令行批量检测并输出CSV报告。

部署文档里还应该收录用户在实际环境中最容易遇到的报错。比如torch版本不匹配导致无法导入、缺少opencv依赖、模型路径写错导致加载失败等。每一种都给出了对应的排查路径和修复命令。我遇到过的最经典报错是用户电脑上装了多个Python环境,pip和python来源不一致,装完依赖后启动立刻报ModuleNotFoundError。文档里我建议用户在部署机上统一使用conda环境,就能避开绝大多数环境错乱问题。

5. 常见问题与排错经验实录

5.1 数据集太小,模型不收敛怎么办

这个问题基本上是每个工业视觉项目都会遇到的。样本量少、缺陷类别不均衡是常态,模型不收敛的典型表现是验证集的mAP在小范围内震荡,上不去也下不来。这时候不要急着调模型结构,先想办法扩数据。我试过有效的做法有三种:

第一种是基础增强策略继续加大力度,比如把HSV扰动范围调大、打开随机视野裁剪、旋转变换范围适当放宽。第二种是对少数类样本做过采样,把针孔、毛刺这类样本在训练过程中多复制几遍参与迭代。第三种是引入公开的PCB缺陷数据集做预训练,先把模型权重在一个大规模相似任务上练一遍,再在自己的小数据集上微调,收敛速度会明显加快。

另外一个容易被忽视的原因是学习率设置不合理。数据集小的时候,较大的初始学习率容易让模型震荡。可以把初始学习率从0.01降到0.005,同时增加预热轮次到5个epoch,让模型在短时间内适应数据分布后逐步加大步长,收敛会稳定很多。

5.2 小目标漏检严重怎么办

PCB缺陷里小目标占比很高,这是这类项目最具挑战性的地方之一。我一开始用YOLOv5s训练,针孔类缺陷的召回率只有60%多,很多明显的缺陷都没有被识别出来。排查下来发现核心原因不是模型不够强,而是输入分辨率不够——针孔在原始图上可能就20x20像素,进入网络后经过多次下采样,特征已经所剩无几。

解决小目标漏检的几条路都值得尝试:

  1. 将输入尺寸从640提高到960或1280。代价是训练和推理时间显著增加,但小目标的特征保留程度大幅改善。我在项目里用960输入试过一轮,针孔召回率从62%升到了78%,效果非常明显。
  2. 使用切片推理,把大图切成若干小块分别检测,再把结果合并。这种方法相当于变相提高了小目标在图像中的占比,适用于目标非常小而计算资源有限的场景。
  3. 调整anchor尺寸,让小尺寸anchor更适配目标分布。YOLOv5的anchor是自动学习的,如果小目标多,可以把anchor的尺度整体调低,让先验框更密集地覆盖小尺寸目标。

实际操作中,我优先用输入尺寸提升方案,因为它不需要改模型结构,代码改动最小。如果你的部署环境对推理速度有严格要求,那么大尺寸输入带来的推理耗时增加就需要通过TensorRT加速来弥补,两者需要平衡考虑。

5.3 部署环境版本冲突问题实录

部署阶段的坑主要集中在环境配置上。我在给另一台没装过深度学习的机器部署时,遇到过CUDA driver版本和PyTorch要求的CUDA runtime版本不匹配的问题。现象是安装顺利、import成功,但只要一调用GPU相关接口就报错,提示CUDA initialization failed。

排查思路是分层的:先看显卡驱动版本是否满足要求,再看PyTorch编译时的CUDA版本和显卡驱动的兼容性,最后确认cuDNN是否配置遗漏。如果用的是GPU,建议让PyTorch安装时绑定一个合理的CUDA版本,比如11.2,驱动版本至少满足建议的要求。如果机器上没有足够权限升级显卡驱动,那就只能退回CPU推理,这也更凸显了部署文档里写清楚“纯CPU环境如何运行”的重要性。

另一个常见问题是使用高版本Python导致的依赖冲突。YOLOv5秉承的是Python 3.8的思想,某些依赖在新版本Python下可能找不到预编译包,或者行为发生变化。我在部署文档中直接建议用Python 3.8创建conda环境,就是为了让对方省去这些反复折腾的时间。实测下来,只要严格按部署文档走,大部分用户都能在一小时左右跑起界面并完成一次完整的检测流程。

6. 项目文件结构与源码说明

6.1 源码目录结构与各模块职责

源码的目录结构,对使用者来说就像一本字典,索引清楚了,用起来才舒服。我在项目里做了一套标准的组织方式,各模块分工明确,下面是简化后的结构展示:

PCB_defect_detection/ ├── train.py # 训练入口,支持自定义数据配置、模型规格 ├── detect.py # 精简版推理入口,可对单张图/文件夹执行推理 ├── interface.py # PySide6可视化界面入口 ├── utils/ │ ├── datasets.py # 数据加载与增强工具 │ ├── metrics.py # 评估指标计算工具 │ └── plot.py # 训练曲线和混淆矩阵可视化 ├── models/ │ └── yolo.py # 模型定义与权重加载逻辑 ├── weights/ │ └── best.pt # 训练得到的最终权重 ├── data/ │ ├── pcb_defect.yaml # 数据配置 │ └── test_images/ # 测试用样例图 └── docs/ └── 部署文档.md # 从安装到运行的全流程说明

train.py是训练入口,支持在命令行传入训练数据路径、模型规格、训练轮次等参数。detect.py就是前面提到的推理模块,它能接收一张图片或者一个文件夹,然后输出检测结果和可视化图像。interface.py是PySide6界面程序的主入口,封装了模型加载和推理调用。weights目录下存放best.pt,这是模型训练完后验证集效果最好的权重。docs目录下的部署文档是整个项目交付时最不能缺的东西,里面除了环境配置,还写了模型训练和测试的完整操作流程。

6.2 源码阅读的顺序建议

拿到这套源码后,从哪个文件看起比较合理?我建议按这条路径走:先打开部署文档,把环境搭好;然后运行detect.py做一次最简单的图片推理,对整体流程有个感性的认知;接着看train.py的训练参数配置和数据加载逻辑;最后再读interface.py的界面代码,理解推理结果如何被展示。

不要一上来就啃models目录里的网络结构代码,那些对大多数使用者来说既难懂又不必需。你要知道怎么训练、怎么推理、怎么部署,这些信息在train.py、detect.py和部署文档里都有。真正需要改模型结构的情况在工业项目里非常少,预训练权重配合数据增强已经能解决绝大多数问题。这种“先跑通,再理解,最后才修改”的顺序,能帮你省掉大量不必要的摸索时间。

6.3 权重文件与数据配置的关联性

最后提醒一个容易忽略的细节:权重文件和数据配置的类别列表必须严格对应。训练时用的pcb_defect.yaml里写的是六个类别,序号0到5分别代表哪类缺陷,权重文件记住了这个顺序。部署时加载权重后,如果配置文件里的类别名称顺序变了,检测结果即使框的位置正确,标签也会全部错位。

为了避免这个问题,我在交付时会把训练用的数据配置文件和weights目录放一起,部署时直接复制即可,不让用户手动创建或修改。用户如果想增加新类别,必须回到train.py重新训练,这一步没有办法绕过。这个设计看似笨拙,但恰恰是工业交付中最稳妥的做法,能大幅减少因配置不一致导致的低级错误。

7. 项目后续扩展方向与个人体会

7.1 从单图检测到产线实时视频流的扩展

当前这套系统是离线图检测,但如果产线要求实时在线检测,扩展方向已经很明确了:把图片输入从文件夹读取切换为摄像头视频流读取,推理模块不变,界面增加视频流显示区域,每一帧都跑一次推理并将检测结果叠加到画面上。实时视频流的帧率一般在25到30帧每秒,如果单张推理耗时38ms,理论上能跑到25帧左右,处于可行范围。再往下走,如果发现性能不够,可以把推理部分换成TensorRT或者改用更轻量的模型规格,这些都是已经验证过的路径。

7.2 数据标注与模型迭代的运营机制

模型上线不是终点,持续迭代才是长期保持高准确率的关键。我的体会是:要让模型越用越准,必须建立一套产线数据回流机制。实际操作中,可以把复判岗位确认过的新缺陷图定期加入训练集,每两周做一轮增量训练,然后把新旧模型在测试集上对比mAP,如果没有明显提升就不用更换部署权重。这个过程机械化程度高、不太需要动脑,但它恰恰是工业视觉项目后期最重要的维护动作。很多项目上线时效果很好,过了三个月因为产线工艺参数调整、来料变化导致准确率下滑,就是因为缺少这套迭代机制。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进