简介这份资源面向计算机视觉学习者与工业质检方向的开发者提供基于YOLOv5的钢材表面缺陷检测完整项目与数据集可用于裂纹、凹坑、氧化皮、划痕等常见缺陷的识别训练与验证。压缩包共约2000个文件以jpg图像、txt标注与xml标签为主另含yaml配置、py训练脚本、pt权重、onnx模型及少量说明文档整体约501MB目录结构清晰便于直接投入训练与推理。资源完整覆盖CSPNet主干、SPP-Block、FPN与PANet多尺度特征融合、Mish激活函数等关键模块并包含数据增强、多尺度训练与实时检测流程读者可据此复现从数据预处理到模型部署的完整链路理解小目标检测与工业缺陷识别的调参思路。目前已有2502人学习下载适合希望将YOLOv5落地到实际检测任务的中高级读者参考。1. 钢材表面缺陷检测为什么首选 YOLOv5从产线痛点到数据集落地产线上钢板跑得飞快划痕、夹杂、氧化铁皮这些缺陷往往只有零点几毫米宽质检员盯着屏幕看一天漏检率能飙到三成以上。传统视觉方案靠阈值分割和形态学处理换个批次、换种光照就得重新调参维护成本高得离谱。YOLOv5 之所以在钢材表面缺陷检测这个场景里被反复拿出来用核心就两点一是单阶段检测器推理速度快TensorRT 量化后能在边缘设备上跑到实时二是工程化程度高数据标注、训练、导出、部署这条链路都有现成脚本不用自己造轮子。钢材表面缺陷数据集通常包含夹杂物、斑块、裂纹、划痕、氧化铁皮压入、凹坑等类别标注格式多为 YOLO txt 或 VOC XML图像分辨率从 200×200 到 1000×1000 不等。这份资源适合两类人一类是想拿工业缺陷数据练手目标检测的算法工程师另一类是需要快速验证产线缺陷检测可行性的嵌入式部署开发者。数据集本身不解决所有问题但它能让你跳过最耗时的数据采集和标注环节直接进入模型调参和部署验证阶段。2. 数据集结构与 YOLOv5 训练链路拆解2.1 钢材缺陷数据集的目录组织与标注格式拿到一份钢材表面缺陷数据集第一件事不是急着跑训练脚本而是把目录结构和标注格式摸清楚。常见的数据集组织方式有两种一种是按类别分文件夹每个文件夹下放对应缺陷的图像另一种是图像和标注文件平铺在同一目录通过文件名关联。YOLOv5 要求的是后者图像和同名的 txt 标注文件放在一起txt 里每行格式为class_id x_center y_center width height坐标全部归一化到 0 到 1 之间。我一般会先跑一段脚本统计类别分布和标注框尺寸分布这一步能提前暴露很多问题。比如某些类别的样本数只有个位数训练时直接就被模型忽略了再比如标注框宽高比极端集中说明标注规范可能有问题。import os import glob from collections import Counter # 统计图像数量和标注文件数量是否匹配 img_dir NEU-DET/images label_dir NEU-DET/labels img_files glob.glob(os.path.join(img_dir, *.jpg)) label_files glob.glob(os.path.join(label_dir, *.txt)) print(f图像数量: {len(img_files)}) print(f标注文件数量: {len(label_files)}) # 统计每个类别的标注框数量 class_counter Counter() for lbl in label_files: with open(lbl, r) as f: for line in f: parts line.strip().split() if len(parts) 5: class_counter[int(parts[0])] 1 print(类别分布:, dict(class_counter))这段脚本做了两件事先核对图像和标注文件数量是否一致不一致说明有漏标或多余文件再统计每个类别的标注框总数如果某个类别数量明显偏少训练时就需要考虑过采样或者类别权重调整。参数方面img_dir和label_dir按实际路径改class_id从 0 开始编号和data.yaml里的names列表顺序严格对应。2.2 从零配置 YOLOv5 训练环境与 data.yamlYOLOv5 的代码仓库更新频率不低直接 clone 主分支有时候会遇到依赖冲突。我一般会指定一个稳定版本比如 v7.0然后按官方 requirements.txt 装依赖。PyTorch 版本要和 CUDA 驱动匹配不然训练时会在.to(device)那一步报错。# 克隆指定版本的 YOLOv5 git clone -b v7.0 https://github.com/ultralytics/yolov5.git cd yolov5 # 安装依赖建议用虚拟环境 pip install -r requirements.txt # 验证环境是否可用 python -c import torch; print(torch.__version__, torch.cuda.is_available())环境装好后关键是写对data.yaml。这个文件告诉 YOLOv5 去哪里找训练集、验证集以及类别名称是什么。钢材缺陷数据集如果只有训练集和验证集按下面这样写# data.yaml train: ../NEU-DET/images/train val: ../NEU-DET/images/val nc: 6 # 类别数根据实际数据集调整 names: [crazing, inclusion, patches, pitted_surface, rolled-in_scale, scratches]train和val路径可以是绝对路径也可以是相对路径相对路径是相对于 YOLOv5 根目录。nc必须和names长度一致否则训练启动时会直接报错。如果数据集没有划分验证集可以从训练集里切 10% 到 20% 出来别偷懒全拿去训练不然过拟合了你都不知道。2.3 训练命令与关键超参数设置YOLOv5 的训练入口是train.py参数多但不复杂。钢材缺陷检测这个场景我一般会从 yolov5s 起步输入尺寸设 640batch size 根据显存来8GB 显存跑 16 比较稳。python train.py \ --img 640 \ --batch 16 \ --epochs 100 \ --data data/steel_defect.yaml \ --weights yolov5s.pt \ --cfg models/yolov5s.yaml \ --hyp data/hyps/hyp.scratch-low.yaml \ --name steel_exp1 \ --cache--img 640是输入分辨率钢材缺陷目标通常不大640 够用想提精度可以上 1024 但显存翻倍。--weights yolov5s.pt表示用 COCO 预训练权重做迁移学习工业缺陷数据量通常不大从头训很容易欠拟合。--hyp指定超参数文件hyp.scratch-low.yaml适合小数据集数据增强强度低一些避免把缺陷特征增强没了。--cache把图像缓存到内存加快训练速度但数据集大了会吃内存量力而行。训练过程中重点看三个指标mAP0.5、mAP0.5:0.95和每个类别的precision/recall。钢材缺陷里crazing和scratches容易混如果这两个类别的混淆矩阵对角线不干净说明特征区分度不够可以考虑加大输入尺寸或者换更大的模型。3. 推理验证与边缘部署从 PyTorch 到 RK35683.1 用 detect.py 做推理与结果可视化训练完拿到best.pt之后别急着导出先用detect.py在验证集上跑一遍肉眼看看漏检和误检的情况。YOLOv5 的推理脚本支持图像、视频和摄像头输入钢材缺陷检测一般用图像文件夹批量推理。python detect.py \ --weights runs/train/steel_exp1/weights/best.pt \ --source ../NEU-DET/images/val \ --img 640 \ --conf 0.25 \ --iou 0.45 \ --save-txt \ --project runs/detect \ --name steel_val--conf 0.25是置信度阈值低于这个值的框直接丢弃。钢材缺陷检测里如果漏检代价高可以把conf降到 0.15 左右但误检会增加。--iou 0.45是 NMS 的 IoU 阈值缺陷框重叠多的时候可以适当调高到 0.5 到 0.6。--save-txt会把预测结果保存成 YOLO 格式的 txt方便后续和真值做对比分析。推理完重点看两类图一类是漏检的真值有框但预测没有另一类是误检的预测有框但真值没有。漏检多说明模型召回不够可以试试降低conf或者增加训练轮数误检多说明模型精度不够可以试试提高conf或者补充负样本。3.2 导出 ONNX 与 RK3568 量化部署要点RK3568 这类边缘芯片部署 YOLOv5标准链路是 PyTorch → ONNX → RKNN。导出 ONNX 的时候有几个参数必须注意不然转 RKNN 会失败。python export.py \ --weights runs/train/steel_exp1/weights/best.pt \ --include onnx \ --img 640 \ --batch 1 \ --opset 12 \ --simplify--opset 12是 ONNX 算子集版本RKNN 工具链对 opset 11 和 12 支持最好别用太新的。--simplify会调用 onnx-simplifier 做图优化去掉冗余算子这一步能显著减少转换时的报错。--batch 1是因为边缘设备通常一次只推理一张图batch 设大了 RKNN 可能不支持。转 RKNN 的时候量化方式选asymmetric_quantized-u8数据集准备 100 到 200 张有代表性的钢材缺陷图做校准。量化后精度掉点是正常的如果掉太多检查校准集是不是覆盖了所有缺陷类别别只用一种缺陷的图去校准。提示RKNN 工具链对 YOLOv5 的 Focus 层和 SiLU 激活函数支持有版本差异建议用 RKNN-Toolkit2 的 1.4 以上版本转之前先跑一遍官方提供的 yolov5 转换示例确认环境没问题再换自己的模型。3.3 树莓派 4B 部署 YOLOv5 的可行性边界树莓派 4B 部署 YOLOv5 这件事我的血泪经验是能跑但别指望实时。树莓派 4B 的 CPU 是 ARM Cortex-A72没有 NPU纯 CPU 推理 yolov5s 在 640 输入下大概 1 到 2 FPS换成 yolov5n 能到 3 到 5 FPS。如果产线要求 30 FPS树莓派方案直接放弃老老实实上 RK3568 或者 Jetson Nano。如果只是做离线抽检或者低频监控树莓派 4B 可以用 ONNXRuntime 或者 OpenVINO 的 ARM 版本来跑。安装 ONNXRuntime 的时候注意选 aarch64 的 wheel别装成 x86 的。# 树莓派 4B 上安装 ONNXRuntime pip install onnxruntime # 推理脚本核心部分 import onnxruntime as ort import cv2 import numpy as np session ort.InferenceSession(best.onnx) input_name session.get_inputs()[0].name img cv2.imread(defect.jpg) img cv2.resize(img, (640, 640)) img img[:, :, ::-1].transpose(2, 0, 1) # BGR to RGB, HWC to CHW img np.expand_dims(img, axis0).astype(np.float32) / 255.0 outputs session.run(None, {input_name: img})树莓派上跑的时候把img尺寸降到 320 能明显提速但小缺陷可能就检不出来了。我的建议是树莓派只做粗筛把可疑区域裁出来传给后端服务器做精检别把所有压力都压在一颗 ARM CPU 上。4. 避坑与排查钢材缺陷训练里最容易翻车的五件事4.1 现象训练 loss 正常下降但 mAP 一直是零原因data.yaml里的names顺序和标注文件里的class_id对不上。钢材缺陷数据集不同来源的类别编号可能不一样有的把crazing编 0有的编 5直接拿来用就全乱了。解决写个脚本统计标注文件里出现的所有class_id和names列表逐一核对。如果发现某个class_id超出了nc的范围说明标注文件有问题需要重新映射。4.2 现象验证集 mAP 比训练集低 20 个点以上原因训练集和验证集分布不一致。钢材缺陷数据集如果按随机划分可能出现训练集里全是scratches验证集里全是inclusion的情况。解决划分数据集的时候按类别分层采样保证每个类别在训练集和验证集里的比例接近。YOLOv5 本身不提供分层划分需要自己写脚本或者用 sklearn 的train_test_split加stratify参数。4.3 现象转 ONNX 时报错 Unsupported operator Slice原因YOLOv5 某些版本里的 Slice 算子参数在 opset 11 以下不支持或者 onnx-simplifier 版本太旧。解决导出时指定--opset 12并且升级 onnx-simplifier 到最新版。如果还报错检查 PyTorch 版本1.8 到 1.12 之间对 ONNX 导出支持最好太新的 PyTorch 有时候会引入不兼容的算子。4.4 现象RKNN 量化后小缺陷全部漏检原因校准集里小缺陷样本太少量化时把和小缺陷相关的权重精度压得太低。解决校准集里至少放 30% 的小缺陷图像并且确保每个类别都有代表。如果还是不行试试混合量化对检测头部分保留浮点精度。4.5 现象树莓派上推理结果和 PC 上不一致原因图像预处理不一致。PC 上用的 OpenCV 版本和树莓派上的版本不同resize 的插值算法默认值可能不一样。解决显式指定cv2.resize的interpolation参数统一用cv2.INTER_LINEAR。另外检查 BGR 到 RGB 的转换有没有漏掉YOLOv5 训练时用的是 RGB推理时忘了转就会导致类别全错。5. 把 mAP 再提三个点的实操技巧从数据增强到模型微调钢材缺陷检测的 mAP 卡在某个值上不去是常见情况。我一般会从三个方向入手数据增强策略、锚框聚类、以及模型微调时的学习率调度。先说数据增强。YOLOv5 默认的hyp.scratch-low.yaml里mosaic是 1.0mixup是 0.0。钢材缺陷图像背景相对单一mosaic 增强能显著提升模型对缺陷位置的鲁棒性但mixup要慎用它会把两张图线性叠加缺陷特征容易被稀释。我一般会把mosaic保持 1.0mixup设 0.1 到 0.2copy_paste设 0.1让模型多见一些缺陷在不同背景下的样子。再说锚框。YOLOv5 默认的锚框是基于 COCO 数据集聚类的钢材缺陷的宽高比和 COCO 里的目标差别很大。用kmeans重新聚类一遍锚框能明显提升回归精度。YOLOv5 仓库里自带utils/autoanchor.py训练时加--noautoanchor关掉自动锚框然后手动跑一遍聚类python utils/autoanchor.py \ --data data/steel_defect.yaml \ --weights yolov5s.pt \ --img 640 \ --thr 4.0跑完会输出一组新的锚框尺寸把它替换到模型配置文件里的anchors字段。--thr 4.0是锚框和真值的宽高比阈值钢材缺陷里细长划痕多这个值可以适当放宽到 5.0。最后说学习率调度。YOLOv5 默认用余弦退火lr0设 0.01lrf设 0.01。钢材缺陷数据集通常不大lr0可以降到 0.005 到 0.008避免训练初期震荡。如果发现训练后期 loss 还在降但 mAP 不动了试试把lrf调到 0.1让学习率在后期保持得高一点。还有一个容易被忽略的点验证时的conf阈值和iou阈值对 mAP 影响很大。YOLOv5 默认在验证时用conf0.001和iou0.6来算 mAP这个设置是为了让 PR 曲线更完整。但实际部署时你用的是conf0.25所以验证集上的 mAP 和实际产线表现会有差距。我一般会额外跑一遍conf0.25的验证看看实际阈值下的 precision 和 recall这个数字比默认 mAP 更有参考价值。从那以后我每次拿到新的缺陷数据集都强制走一遍「统计类别分布 → 检查标注格式 → 分层划分 → 锚框聚类 → 小学习率预热」这套流程再也没出现过训练 loss 正常但 mAP 为零的翻车情况。希望帮到你。本文还有配套的精品资源点击获取