ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

YOLOv5s钢材表面缺陷检测实战:基于NEU-DET数据集训练与部署

YOLOv5s钢材表面缺陷检测实战:基于NEU-DET数据集训练与部署 1. 为什么钢材表面缺陷检测值得用YOLOv5s来做1.1 工业质检场景中的真实痛点钢材生产线上表面缺陷检测是个绕不开的环节。无论是热轧钢板还是冷轧带钢生产速度动不动就是每秒几米到十几米肉眼质检员盯着屏幕看两小时就会疲劳漏检率直线上升。传统机器视觉方案也不是不行但依赖人工设计的特征算子遇到光照变化、油污干扰、缺陷形态千奇百怪的情况鲁棒性确实不够好。我之前接触过几个钢厂的项目甲方最关心的从来不是你的模型有多先进而是三个问题能不能实时跑、漏检率多少、误报会不会把产线搞停。这三点恰恰决定了你不能上来就选一个特别重的检测模型。YOLOv5s在这类场景里几乎是万金油一样的存在体积小、推理快、精度够用配合开源数据集NEU-DET做验证和调优完全可以在入门阶段就跑通一整套数据标注→模型训练→效果评估→推理部署的流程。这篇教程面向的读者也很明确刚接触目标检测的学生、想转行做工业视觉的工程师或者公司里需要快速出demo验证可行性的小伙伴。我尽量不堆砌公式而是把每一步怎么操作、为什么这样操作讲清楚保证你照着做就能跑出结果。1.2 为什么选NEU-DET这个数据集NEU-DET是东北大学发布的热轧带钢表面缺陷数据集在工业视觉学习圈子里几乎是入门必刷的数据集。它一共包含1800张灰度图像每张分辨率是200×200像素划分成六个缺陷类别 crazing裂纹、inclusion夹杂、patches麻点、pitted_surface氧化铁皮压入、rolled-in_scale轧制氧化皮、scratches划伤。这个数据集的第一个好处是小。1800张图对深度学习训练来说不算多但正因为少你反而能更清楚地看到数据增强、超参数调整、迁移学习这些操作带来的效果差异。第二个好处是类别分布不均衡比如crazing和scratches的样本数量明显偏少这非常贴近真实工业场景——缺陷本身就是小概率事件模型很容易学过拟合到多数类上。第三是图像分辨率低、缺陷尺寸小很多目标只有二三十个像素直接考验检测器对小目标的感知能力。有这些特点在NEU-DET才值得反复拿来练手。你在它上面踩过的坑换到真实产线数据上大概率还会再踩一遍但至少你在实验室里已经知道怎么应对了。1.3 YOLOv5s在模型选型中的定位YOLO系列发展到现在已经有v5、v6、v8、v9、v10好几个版本但YOLOv5s依然是我给新手推荐的首选。原因不复杂生态成熟、资料多、部署方案齐全。v5的官方仓库里有完整的训练、验证、导出脚本改个yaml文件就能跑自定义数据集遇到问题搜一下基本都有答案。YOLOv5s里的s代表small版本网络结构比m、l、x版本更浅更窄但换来的是极快的推理速度和极小的模型体积。在NEU-DET这种小目标密集的数据集上s版本配合合适的输入尺寸和anchor设置mAP0.5能做到75%上下单张图片推理时间在GPU上只要几毫秒在CPU上也能跑到几十毫秒。这样的性能已经足够支撑产线相机每秒处理几十帧的需求。如果你要问为什么不上YOLOv8或者YOLOv9我只能说在工业项目里稳比新重要。v8的anchor-free设计确实在某些数据集上更优但v5的anchor机制在NEU-DET这种小目标场景下有更成熟的调优套路。deploy到TensorRT、OpenVINO的参考资料也是v5最丰富这点在实际落地时非常加分。2. 动手前的准备工作环境、数据集和配置2.1 环境配置清单我在Windows 11系统上跑通了整个流程PyCharm作为IDE显卡用的RTX 3060 Laptop6GB显存。这个配置不算高但跑YOLOv5s训练NEU-DET完全够用。如果你是纯CPU环境也能跑就是训练时间会长很多建议用官方预训练权重做迁移学习能省一半以上的时间。# 推荐环境版本 Python 3.8 PyTorch 1.10建议1.12或2.0CUDA 11.3 torchvision 0.11 opencv-python 4.5 numpy 1.21创建虚拟环境这一步千万别省我见过太多人把包装到系统Python里最后环境乱了只能重装系统。用conda或者Python自带的venv都行隔离环境出问题直接删了重建比排查依赖冲突快得多。git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txtYOLOv5的requirements.txt会把所有依赖一次性装好包括pycocotools、matplotlib、seaborn这些用于评估和可视化的库。装完之后建议跑一下官方预训练权重做推理测试确保环境没问题再开始训练自己的数据。2.2 数据集下载与目录整理NEU-DET数据集在官方源或者GitHub上都有镜像下载下来是一个压缩包里面包含JPEGImages图片、AnnotationsVOC格式的XML标注、ImageSets训练验证划分。我建了个统一的目录结构方便后续复用datasets/ NEU-DET/ images/ train/ val/ labels/ train/ val/这里有个关键步骤需要说明YOLOv5默认读取的是YOLO格式的txt标注文件每行一个目标格式是类别id 中心点x 中心点y 宽度 高度坐标是归一化后的0~1值而NEU-DET官方给的是VOC的XML格式。你需要用官方仓库里的convert_annotations.py脚本或者自己写个小工具做格式转换。转换脚本的核心逻辑不复杂解析XML文件提取每个object的name和bndbox坐标然后除以图片宽高做归一化最后写入对应的txt文件。类别id的映射关系要固定住我用的映射表是crazing0, inclusion1, patches2, pitted_surface3, rolled-in_scale4, scratches5。这个映射顺序对应到后续yaml配置文件里必须一致否则类别就对不上了。训练集和验证集的划分比例我习惯用9:1即1620张训练、180张验证。官方提供了划分好的train.txt和val.txt文件直接用就行。如果你要自己划分记得用随机种子固定结果保证实验可复现。2.3 模型配置文件修改YOLOv5s的模型结构定义在models/yolov5s.yaml文件里数据集配置在data/目录下新建。对NEU-DET来说你需要新建一个数据集配置文件指定训练和验证图片路径、类别数量、类别名称# data/NEU-DET.yaml train: datasets/NEU-DET/images/train val: datasets/NEU-DET/images/val nc: 6 names: [crazing, inclusion, patches, pitted_surface, rolled-in_scale, scratches]模型的nc参数会自动根据这个yaml文件调整不用手动改。YOLOv5s.yaml里默认的nc是80COCO数据集但训练脚本会读取你传入的数据集配置覆盖这个值。现在很多人初学搞不明白这里面的传递关系实际上一句话就能说清楚data参数告诉模型你要检测几类、分别叫什么名字model参数告诉模型网络结构长什么样两者相互独立又需要匹配。3. 手上的功夫训练全过程详解3.1 训练命令与关键参数环境就绪、数据整理完毕接下来就是最激动人心的训练环节。我在实际跑训练时用的命令是这样的python train.py \ --data data/NEU-DET.yaml \ --cfg models/yolov5s.yaml \ --weights yolov5s.pt \ --batch-size 16 \ --epochs 150 \ --img 640 \ --device 0 \ --project runs/NEU-DET \ --name yolov5s_640逐个解释这些参数的含义因为很多新手死磕半天train.py跑不起来就是参数没搞明白。--weights指定预训练权重这里强烈建议用官方提供的yolov5s.pt而不是从零训练。COCO数据集上训出来的权重已经学到了通用的特征提取能力迁移到钢材缺陷上只需要微调后面的检测头就行收敛速度快好几个量级。--img是输入图片尺寸NEU-DET原图只有200×200但YOLOv5会自动缩放到640×640psotine和mosaic增强都在这个尺度上进行。--batch-size要根据显卡显存调整6GB显存跑16是安全的batch太大容易OOM显存溢出。--epochs我设了150NEU-DET数据量小100轮其实就能看到不错的收敛效果多跑几十轮主要是为了验证后面会不会过拟合。还有几个不常改但需要留意的参数。--workers控制在数据加载时的子进程数Windows系统建议设成0否则容易报DataLoader worker进程错误。--patience是早停参数如果连续这么多轮验证集mAP没有提升就自动停止训练默认100对我来说这个值太长了一般改成30就够了。--cache可以把图片加载进内存以加速训练NEU-DET数据集小开了这个参数训练会快不少。3.2 训练过程日志解读训练开始后终端会实时打印每个batch的loss信息。新手看到一堆数字可能有点懵我教你快速抓重点。YOLOv5的loss分为三部分box_loss定位误差、cls_loss分类误差、obj_loss目标置信度误差三者加权求和就是总的train loss。正常训练过程中train loss应该是平滑下降的偶尔有小幅震荡很正常不必担心。真正需要盯紧的是每轮结束后的验证集指标。YOLOv5会打印每个类别的mAP0.5和mAP0.5:0.95以及Precision、Recall。在NEU-DET上训练到40-60轮时mAP0.5基本能到70%左右后面10-20轮是缓慢爬坡阶段提升幅度很小这时候你要判断是继续跑还是提前结束。我个人习惯看mAP0.5:0.95这个指标它对bounding box的定位精度更敏感如果它还在明显上升说明模型还有潜力可以继续训。训练结束后在runs/NEU-DET/yolov5s_640/目录下会生成一堆文件其中比较重要的有weights/best.pt验证集上表现最好的权重、weights/last.pt最后一轮的权重、results.pngloss曲线和指标曲线图、confusion_matrix.png混淆矩阵、F1_curve.pngF1分数曲线。我每次训练完都会先看results.png从曲线形态能快速判断有没有过拟合、学习率设置是否合理。3.3 数据增强对NEU-DET训练效果的影响YOLOv5默认开启了Mosaic增强把4张图拼成1张训练这对NEU-DET这种小目标数据集是相当友好的。因为拼接后的图片尺寸变大了小目标在训练中占比更高模型对小目标的感知能力会明显增强。我在NEU-DET上的试验显示关闭mosaic增强后mAP0.5直接掉了8-10个百分点差距非常明显。不过mosaic增强有一个副作用它会让模型在训练前期看到的目标分布和真实场景差异较大。YOLOv5官方在训练最后10轮会关闭mosaic改用正常的单图训练来做微调这个逻辑在hyp.scratch-low.yaml里配mosaic参数初始是1.0配合上述调度策略。如果你用默认配置不需要手动干预但如果自定义训练流程记得保留这个最后关闭mosaic的机制。除了mosaichsv_h、hsv_s、hsv_v这些颜色增强参数对灰度图的作用其实有限因为NEU-DET的所有图片都是单通道灰度图。你会发现改这些参数对效果影响不大。真正有效的是scale尺度变换和translate平移增强它们能让模型学习到缺陷在不同尺寸和位置下的形态增强泛化能力。翻转变换fliplr对NEU-DET部分类别有效——划伤和裂纹这类方向性强的缺陷翻转后语义不变但夹杂和麻点这类中心对称的缺陷翻转提升有限。4. 效果评估与推理部署4.1 使用训练好的权重做图片推理训练完成之后第一时间要做的就是用best.pt跑几张验证集图片看看真实效果。这一步的意义在于指标是抽象的而视觉结果能让你直观感受模型的优势和短板。python detect.py \ --weights runs/NEU-DET/yolov5s_640/weights/best.pt \ --source datasets/NEU-DET/images/val \ --conf-thres 0.25 \ --iou-thres 0.45 \ --save-txt \ --save-conf \ --project runs/detect \ --name NEU-DET_result--conf-thres是置信度阈值低于这个值的目标会被过滤掉。工业场景里这个阈值的选择直接关联误检和漏检的平衡调高阈值误检变少但漏检变多调低阈值则相反。我用0.25作为观察基准实际部署时会根据产线需求调成0.3~0.5。--iou-thres是NMS非极大值抑制的IoU阈值控制两个重叠框是否保留调高会让检测结果更拥挤调低则会过滤掉重叠度高的框。上一步会在runs/detect/NEU-DET_result/目录下生成带检测框的标注图片。我习惯挑几个严重缺陷的样本来做目视检查比如裂纹和划伤这类细长形的缺陷看看bounding box是否紧贴目标边缘、是否存在一个缺陷被拆成多个框的情况。如果检测框明显偏大或者漏掉了一部分缺陷区域这就是模型定位能力不足的信号需要在后续调优中针对性处理。4.2 导出ONNX与TensorRT加速训练只是第一步真正上产线跑还要考虑推理效率。YOLOv5s原生的PyTorch模型在GPU上已经很快了但要部署到工业现场通常还需要做一次模型转换和加速优化。常用的两个方向是ONNX和TensorRT。ONNX是个开放的模型交换格式好处是跨框架、跨平台。导出命令非常简单python export.py \ --weights runs/NEU-DET/yolov5s_640/weights/best.pt \ --include onnx \ --img 640 \ --dynamic--dynamic参数让模型的输入尺寸变得灵活这样部署时可以直接喂任意分辨率的图片不用再额外做resize。导出完成后可以用onnxruntime在CPU上推理或者用TensorRT在NVIDIA GPU上做int8量化推理速度能再快2-3倍。我在3060上实测TensorRT int8量化后的模型推理单张640×640图片只要2-3毫秒完全可以满足产线实时检测的需求。TensorRT转换稍微复杂一点需要先导出ONNX再用trtexec工具转成engine文件。转换过程中有个小坑YOLOv5的输出层是三个不同尺度的detection层拼接而成的TensorRT转换时如果版本不匹配会报维度错误。我的建议是直接使用YOLOv5官方提供的deploy脚本或者biliubili上很多博主写的TensorRT版本的推理代码避免自己从零写后处理逻辑。4.3 部署到实际生产环境的取舍模型部署到工业现场考量的维度跟实验室完全不一样。实验室里你只关心mAP生产环境你还要考虑工控机的CPU/GPU算力够不够、相机采集的图片分辨率是多少、PLC怎么接收检测结果、异常报警怎么联动。最轻量的方案是部署到纯CPU环境毕竟不是所有工厂都有NVIDIA显卡。一张640×640的图片在i5工控机上用ONNX Runtime CPU推理大概50-80毫秒换算过来是每秒12-20帧对大部分产线来说也够用了。如果帧率要求更高要么上GPU要么把输入尺寸从640降到416或320推理速度能翻倍但检测精度会有一定损失。我在NEU-DET上实测过416输入相比640mAP0.5会掉3-5个百分点需要你根据产线实际缺陷严重程度权衡。部署时还有一个容易忽略的环节图像预处理。训练时YOLOv5会做letterbox处理保持长宽比缩放到640×640多余部分填充灰色推理时也必须用完全相同的预处理方式否则检测效果会明显退化。很多人在部署阶段图省事直接resize结果模型性能暴跌排查半天才发现是预处理不一致导致的。5. 实战中的高频问题和排查思路5.1 类别不均衡是NEU-DET最大的坑NEU-DET数据集中crazing和scratches两个类别的样本明显少于其他四类。如果直接用原始数据训练模型会对这两个类别的召回率偏低混淆矩阵上也能看到大量漏检。解决这个问题有几个思路我按推荐程度排序说明。第一个思路是增加数据增强强度。YOLOv5里的copy_paste增强能直接把某个目标复制到图片的其他位置效果相当于免费的样本扩增。我试过在NEU-DET上把copy_paste参数从默认的0.0调到0.5mAP0.5提升了约2个百分点其中crazing类别的召回率提升最明显。第二个思路是类别加权在loss计算时给少数类更高的权重。YOLOv5官方没有直接暴露这个参数但你可以修改loss.py或者通过改变每个类别的置信度阈值来达到类似效果。第三个思路是收集更多数据这也是最费时但最有效的方法。NEU-DET毕竟只有1800张图真实项目中你肯定要自己采集和标注更多的缺陷样本做扩充。5.2 小缺陷目标检测效果差怎么办NEU-DET里大部分缺陷目标只有几十个像素在640×640输入下占整个画面的比例非常小。YOLOv5s通过FPN特征金字塔结构在三个尺度上检测目标理论上能兼顾大小目标但小目标的特征传递链路长、信息损失大实际效果容易不佳。我的经验是先从anchor参数入手。YOLOv5会根据你的数据集重新聚类anchor训练日志中会打印AutoAnchor的结果。如果autoanchor计算出的anchor尺寸跟你数据集中目标真实尺寸分布差异大检测效果会受影响。你可以用官方提供的check_anchors.py单独跑一下看看当前anchor的召回率是否在90%以上。如果低于这个值建议调大--img输入尺寸或者修改model yaml中的anchor定义。另一个有效策略是使用SAHISlicing Aided Hyper Inference这类切片推理工具把大图切成多个小图分别检测再把结果合并。NEU-DET原图只有200×200还好但如果你部署到实际产线用高分辨率相机一张图能到几千×几千像素切片推理几乎是必须的。代价是推理耗时成倍增加需要根据实际帧率要求做取舍。5.3 训练loss不下降的排查经验如果你按照上面的流程跑了一遍发现loss不下降或者过早收敛到很差的值先检查几个方面。第一是学习率YOLOv5默认开启了warmup和cosine annealing初始学习率一般在0.01左右如果出现梯度爆炸或者loss剧烈震荡可以把--lr0调低到0.001。第二是数据标注的质量我见过太多人花时间调参最后发现是标注框样本没有对齐目标边缘导致模型怎么学都学不准。NEU-DET官方标注质量不错但如果你自己标注数据一定要检查有没有漏标、错标的情况。第三是batch size太小导致梯度估计噪声过大在6GB显存上跑16已经比较极限如果你用更小的batch建议同步降低学习率。5.4 部署环境的取舍最近很多人在讨论用Ollama部署本地模型、用vLLM部署大模型这些跟我做的YOLOv5s部署是两套生态。目标检测模型的部署更轻量、对硬件要求更低不一定需要GPU服务器。如果你的产线现场没有GPU用Intel的OpenVINO工具包把ONNX模型转换成IR格式在集显或CPU上跑也能获得不错的性能。我在一台只有核心显卡的NUC上跑过OpenVINO量化的YOLOv5s640输入推理时间大约40毫秒虽然比不上TensorRT但至少让没有独立显卡的设备也具备了实时检测能力。还有一个容易被忽略的点是模型版本管理。部署到产线的模型不是训一次就完事后续还会根据新数据迭代。我在项目里习惯把每次训练的权重文件和对应的数据配置、训练参数一起打包存到一个目录里用时间戳命名。这样出问题时能快速回溯到之前效果好的版本不用瞎猜上次是哪个权重跑出来的结果。6. 写在最后的几点体会NEU-DET这个数据集我在不同阶段刷过好几遍。第一次跑通时觉得目标检测不过如此后来深入做工业项目才发现模型本身的知识只是冰山一角。真正决定项目成败的往往是你对数据的理解程度、对部署环境的把握能力以及面对脏乱差数据时的耐心。如果你刚接触这个领域我不建议一上来就折腾各种花哨的网络结构改进。老老实实把YOLOv5s在NEU-DET上跑通、理解每个参数的作用、学会看训练日志和评估指标这个基础打牢了后面换到任何数据集、任何检测框架都能很快上手。最后分享一个小经验训练过程中我把results.png的曲线图推到了手机上随时看每过几轮就瞄一眼loss和mAP的变化趋势。这种做法让我能在训练失控前及时手动干预而不是等两小时训练结束后才发现参数设置有问题。虽然YOLOv5支持早停机制但人工监控永远比自动判断更靠谱。
返回列表