简介:目标检测是计算机视觉在工业质检中落地最广的技术方向之一,其核心在于让模型自动定位并识别图像中的异常区域。YOLO系列以高效的单阶段检测结构著称,其中YOLOV5凭借清晰的目录组织、灵活的配置和成熟的训练管道,成为工程实践中的常用选择。在工业场景中,齿轮表面缺陷如划伤、崩角、锈蚀往往形态多样、背景复杂,需要规范的数据标注和合理的训练验证划分才能训练出可靠模型。通过理解YOLO格式的归一化坐标表示、data.yaml配置及超参数调整逻辑,可以快速搭建一套可复用的缺陷检测流程。本文围绕齿轮缺陷检测数据集,梳理从目录结构、标注规范到训练调参的完整链路,为工业视觉落地提供参考。 一台手机、一个显微镜,或者生产线上的定焦相机架在那里,拍到的都是同一类东西:圆形的、带齿的、金属质感的零件,表面有划痕、有崩角,或者边缘锈了一块。咱们的目标是让模型自己把这些缺陷找出来,框住,告诉质检员“这里有问题”。这就是你正在做的事,也是这套数据集存在的意义。
我在计算机视觉方向做了不少年,接触过不少工业检测项目,有一套顺手的齿轮缺陷检测数据(YOLOV5目录格式,3个类别,自带训练集/验证集划分)。这篇文章就从这个数据集讲起,把YOLOV5的训练流程、目录结构、标注规范、超参数设置、常见踩坑点全部串起来。不管你是刚接触目标检测的初学者,还是已经被工业现场脏数据折磨过一阵的工程师,这篇文章应该都能给你一些可复用的参考。
我需要先交代一下这批数据的基本情况:数据是按YOLOV5的标准目录格式组织的,图片放在images目录下,对应的标注txt放在labels目录下。一共三类缺陷,命名很直白:
- scratch:齿面划伤。这是最常见的缺陷类型,一条或多条细线状痕迹,长短、深浅不一。
- chip:齿尖/齿面崩角,边缘缺损,有比较明显的断裂缺口,表现为小区域缺失。
- rust:锈蚀。金属表面出现斑块状的颜色变化,常伴有纹理粗糙。
每张图片都有对应的标注文件,标注内容就是“类别+归一化坐标+框宽高”,完全符合YOLO系列的输入格式,省去了自己转换的麻烦。训练集和验证集已经按一定比例分好,拿到手就能开训,不需要再自己写脚本乱切。
这个数据集本身不算大,但作为工业场景的示例来说,类别划分清晰、缺陷形态典型、差异化足够,拿来练手和做算法验证都是合适的。尤其是对于刚接触YOLOV5目录结构、或者想快速跑通工业缺陷检测流程的人来说,可以直接在这个基础上做迁移学习,然后把自己的缺陷样本加进去,变成私有数据集。下面我从数据集的格式设计讲起,顺着训练流程走到实际调参,最后把现场验证中的常见问题一并理清。
1. 内容整体设计与思路拆解
1.1 为什么采用YOLOV5目录格式
之前很多做缺陷检测的工程师习惯用VOC或者COCO格式标注。VOC是一张图片配一个XML文件,标注框信息写在XML里面的一个<object>标签下面;COCO则是一张大JSON,所有图片的标注信息全塞在一个文件里。
这两种格式各有优势,但到了实际训练阶段,都得额外写一段转换脚本,把自己麻烦一遍。VOC要解析XML然后生成txt,COCO要把JSON里的annotation信息遍历一遍再重写。而YOLOV5目录格式是“一张图对应一个txt”,txt文件的每一行对应一个目标框,格式是:
class x_center y_center width height好,就是这四个坐标值,外加一个类别序号。看起来简单,但实际用起来非常方便。因为工业场景下,经常需要一边采集数据一边看效果,新增一批图、标注一批图,直接丢到images目录和labels目录下就行,不需要动任何索引文件。
另外还有一个实际原因:labelImg、labelme这类标注工具都支持直接导出YOLO格式,或者一键转换。数据生产端和训练端是同一种格式,中间的转换成本直接消失了。这个数据集在选型的时候,明显是考虑了工业场景下“快速迭代、持续扩充”的实际需求。
1.2 三类缺陷的标注思路与设计逻辑
把缺陷分成划伤、崩角、锈蚀这三类,不是随随便便分的。工业质检最核心的问题是:你希望模型把什么东西和什么东西区分开。
- 划伤和锈蚀可能同时出现在同一个齿面上,如果不分开标,模型就会把这两个特征混在一起,给出的置信度会偏低,或者一会报A类缺陷、一会报B类缺陷,质检逻辑就乱了。
- 崩角的形状和阴影经常和背景非常接近,如果不单独作为一个类别,模型很容易直接漏检。
所以这三类的定义逻辑,就是:按缺陷成因和形态区分,类别之间尽量不重叠。拿到手之后,我在标注数据里看了一眼,确认了标注文件里的坐标和缺陷边界是比较严格的,没有出现“一个大框把三处划伤全圈进去”这种偷懒情况。这是保证训练效果的基础。
1.3 数据集的“学习路径”意义
这套数据集拿来训练YOLOV5s这类轻量级模型,效果是很理想的。它足够小,单卡几小时能训练完;它又足够典型,包含了细长条形目标(划伤)、小面积突变目标(崩角)、区域性纹理变化目标(锈蚀),这三种类型基本上覆盖了工业视觉中常见的缺陷形态。
如果你从来没跑过YOLOV5的完整训练流程,这套数据就是一条比较顺的“学习路径”:先读懂目录结构,再搞清楚标注格式,然后调起训练脚本,最后用val或者detect验证效果。整条链路走通之后,再去做其他工业检测项目,你就有底子了。
2. 数据集目录结构与格式全解析
2.1 标准目录树参考
下面是我实际用它训练时使用的目录结构,建议大家保持一致:
gear_defect_data/ ├── data.yaml ├── images/ │ ├── train/ │ │ ├── gear_001.jpg │ │ ├── gear_002.jpg │ │ └── ... │ └── val/ │ ├── gear_101.jpg │ └── ... └── labels/ ├── train/ │ ├── gear_001.txt │ └── ... └── val/ ├── gear_101.txt └── ...有一个细节要记住:images/train里的图片文件名,和labels/train里的txt文件名,必须是一一对应的。比如图片叫gear_001.jpg,那标注文件就必须叫gear_001.txt。YOLOV5在训练时是按文件名去匹配图片和标签的,如果有一张图没有对应的txt文件,会报一句警示信息,然后直接跳过这张图——这在工业场景下容易造成“你以为自己在训练所有数据,实际上训练集凭空少了一截”的情况。
2.2 YOLO标注格式详解
打开一个标注txt,内容是这样:
2 0.581771 0.443490 0.104536 0.059357 0 0.433160 0.584848 0.099316 0.046754解释一下:
- 第一个数:类别序号,0对应
scratch,1对应chip,2对应rust。 - 第二个数:目标中心点的x坐标,已经归一化到0-1之间,等于
框中心x / 图片宽度。 - 第三个数:目标中心点的y坐标,等于
框中心y / 图片高度。 - 第四个数:目标框的宽度,等于
框宽 / 图片宽度。 - 第五个数:目标框的高度,等于
框高 / 图片高度。
这里有一个容易踩坑的点:YOLO格式的四个坐标值全是归一化之后的相对值,不是像素值。所以不管你的原始图片是640x640还是1920x1080,只要归一化做了,YOLOV5都能直接处理。不要以为标注文件里写的是像素坐标,直接用原图尺寸去推理,会对不上。
另外一个容易忽略的坑:图片尺寸变了,标注坐标不用跟着改。因为标注是归一化的相对坐标。但是,如果你做了“裁切”操作,比如把一张大图裁成四张子图,那标注坐标就必须重新计算;不做数据增强之前先搞清楚这一点,可以避免后续大量返工。
2.3 data.yaml配置说明
训练前需要编辑data.yaml,告诉YOLOV5在哪里找图片和标签,以及类别信息。基本内容如下:
train: gear_defect_data/images/train val: gear_defect_data/images/val nc: 3 names: ['scratch', 'chip', 'rust']注意train和val后面写的路径,是找到images目录,YOLOV5会自动根据images的路径推导出labels的路径——它默认把路径中的images替换为labels。所以一个常见的报错是:把labels目录放错了位置,或者图片路径写错了,然后训练时出现“image ... missing labels”或者“found no labels”的红色警告。
提示:不要用绝对路径写在
data.yaml里。除非你永远不换机器。目录路径建议用相对当前工作目录的路径,或者放入一个比较稳定的绝对位置,不然换个环境跑就要改一堆东西。
3. 训练集与验证集的合理划分策略
3.1 划分比例与逻辑
这批数据已经帮你分好了训练集和验证集,比例大概在8:2到7:3之间。这个比例是合理的。
模型训练是需要在大量的“典型情况”上去学习特征,验证集则是用来模拟“真正上场之后的抽检”。如果训练集太小,模型泛化能力不足,验证集上表现会一塌糊涂;如果训练集太大、验证集太小,又可能出现过拟合而你自己发现不了。7:3是工业缺陷检测里一个比较稳妥的窗口。少样本场景甚至可以到6:4,但再往下训练集就不够吃了。
3.2 划分数据时的“同源数据泄漏”问题
关于训练集/验证集的划分,有一件事很多人一开始不重视,直到模型上线才意识到,那就是:不要按照图片序列盲目划分,要按目标/工件个体来划分。
比如齿轮A的图片拍了10张,齿轮B的图片拍了10张,如果随机划分训练/验证集,那么齿轮A的图片可能一部分在训练集,一部分在验证集。这样看起来指标很好看,但实际是因为验证集里出现了与训练集过于相似的图像,模型的“泛化能力”被高估了。到了新工件上,你可能就翻车。
正确的做法是:尽量按照工件个体来划分,一个齿轮的所有图片要么全在训练集,要么全在验证集。这套示例数据的划分是合理的,这也就意味着你后续如果自己扩充数据,别偷懒随机切,要先按“组”划分。
3.3 划分之后的三步检查
拿到划分好的数据集之后,按下面三个步骤做一次检查:
检查类别分布是否均衡:统计训练集和验证集中
scratch、chip、rust三类各自的标注框数量。如果验证集中某个类别的数量是0,那训练过程会非常迷惑,因为loss中该类别的贡献一直是0,最后这个类别很可能没有学习效果。工业场景下,小样本类别干脆训练后单独验证。检查图片是否损坏:工业现场有时候采集的图是花屏或者全黑的,模型训练时越到后面越会被这些坏数据带偏。可以写一段简单的Python脚本扫描所有图片,
opencv读不出来的直接删掉。检查空标注:如果图片是正常的,但没有标注文件,也就是这张图里没有任何缺陷,这个时候要分情况看。如果只是少数几张没有缺陷,通常直接剔除;如果你想专门做“负样本”,那就要单独处理。不要默认“没标就等于无缺陷”,要确认过图片内容再说。
4. YOLOV5训练实操全流程
4.1 环境准备
我用的是比较常规的一套环境,你可以参照着来:
- Python 3.8+
- PyTorch 1.10+
- CUDA 11.x(显卡不行的纯CPU跑也可以,就是慢)
- YOLOV5仓库(
git clone https://github.com/ultralytics/yolov5.git)
克隆下来之后,安装依赖:
pip install -r requirements.txt这一步往往会碰到一个错误:torch版本跟CUDA版本对不上。建议先单独装好PyTorch(去官网挑跟你显卡驱动匹配的命令),再执行requirements.txt的安装。
注意:如果你只想快速验证,不要求太高的mAP,用CPU也完全可以跑这套小数据集,就是epochs耗时会拉长。建议还是整一块NVIDIA显卡,体验完全不同。
4.2 修改模型配置文件
训练前需要改两个配置文件:
models/yolov5s.yaml:把里面的nc参数改为3。data.yaml:确认上面的路径与类别列表正确。
yolov5s.yaml的开头大概是:
nc: 3 # number of classes depth_multiple: 0.33 width_multiple: 0.50depth_multiple和width_multiple决定了网络的宽度和深度。yolov5s是“small”版本,是速度和精度的折中。工业缺陷检测中,轻量级、速度快、部署方便,比超高精度更常被优先考虑。
4.3 训练命令与参数解读
基本的训练命令如下:
python train.py --img 640 --batch 16 --epochs 200 --data data.yaml --cfg models/yolov5s.yaml --weights yolov5s.pt --name gear_defect这里每个参数我解释一遍,因为很多人就是在这一层开始糊涂的:
--img 640:输入图片尺寸。图片在训练时会缩放到640x640。工业缺陷检测中,如果缺陷非常小,可以适当加大到1280,但训练时间会成倍上涨。先跑640,有天花板了再往上加。--batch 16:一次迭代喂给模型的图片数量。越大显存占用越高,梯度更新时间越稳定。显存不够就调小到8或4。工业小数据集batch不用太小,否则loss会震荡得很厉害。--epochs 200:整个数据集被模型完整学习200轮次。对于小数据集,200轮够看趋势了。不需要一上来就设很大。--weights yolov5s.pt:预训练权重。这里的yolov5s.pt是在COCO数据集上预训练过的,继承了它学到的基础视觉特征。迁移学习在工业场景下非常管用,尤其是数据量不大的时候。--name gear_defect:保存本次训练结果的文件夹名,会生成在runs/train/gear_defect/目录下。
训练过程中,终端会打印每一轮的平均loss值,runs/train/gear_defect/下面还会生成一些图表,包括results.png,这是判断训练好坏最直观的一张图。
4.4 超参数调整的经验
训练完后如果发现mAP不够高,不要急着加数据,先看看你现在这条曲线是怎么走的:
- 训练集loss降不下来,但验证集loss也很高:可能是模型容量不够,尝试用
yolov5m或者yolov5l,增加网络宽度和深度,或者加大预训练模型的复杂度。 - 训练集loss一直降,验证集loss稳定在某个值不降反升:过拟合了。增加数据增强、加dropout、加数据量,或者提前停止。工业检测小数据集很容易过拟合。
- loss能降,但mAP很低:大概率是正负样本不均衡,或者标注框不准确。先检查labels里的坐标和图片中的真实目标是否匹配。
YOLOV5还支持调超参数的遗传算法:
python train.py --epochs 50 --evolve它会自己生成一批超参数组合,然后训练、评估、选优。在小数据集上跑这个很耗时,但如果你愿意等一晚上,第二天往往能收获一组比默认配置更好的参数。
5. 常见问题与排查技巧实录
说到YOLOV5训练工业检测数据,常见的坑我已经替你们踩过不少,下面整理一份问题速查表。
| 问题现象 | 可能原因 | 排查方法 |
|---|---|---|
| 训练报错“found no labels” | 标注路径不对,或labels目录结构错误 | 检查data.yaml中的路径;确认图片对应txt存在 |
| 训练时提示“skipping ... train image” | 图片损坏或标注文件为空 | 用opencv逐一读图;统计空txt文件 |
| loss下降特别慢 | 学习率太低,或数据集太小 | 查看results.png;适当加大--lr0或增加epochs |
| 验证集mAP高但实际检测差 | 同源数据泄漏,或过拟合训练集 | 检查划分逻辑;用新采集图片测试;降低epochs |
| 检测结果漏掉小目标缺陷 | 输入尺寸太小,或标注框太小 | 调大--img;用小目标增强策略;保证标注框不丢 |
几条细节经验,展开说说。
第一条:标注文件内容为空的情况。YOLOV5对于“这张图没有目标”的处理方式是:不写txt文件,或者txt里面没有任何内容。但很多标注工具默认会生成一个空txt。训练时,YOLOV5看到空txt会认为这张图没有目标,会把它参与负样本训练,这是合法的。但如果你本意是想“标注缺陷图”,结果有几十张图都是空的,那这些负样本对模型学会检测缺陷基本没有正面帮助,还占显存。我习惯先跑一个脚本统计一下空txt的数量,确认不是标注遗漏。
第二条:验证集mAP高,不代表现场表现好。工业缺陷检测的特殊之处在于:现场背景复杂,同一类型的缺陷在光照、角度变化下差异很大。训练集里如果都是单一背景,模型学到的“划痕”可能是“在某个特定光线下出现的深色细线”,换一个角度就不认了。所以,一个严谨的做法是:训练完模型之后,抽一部分新拍的图片,跑一遍detect.py,用肉眼看看输出。mAP只给你一个数字,肉眼才能给你“哦,它真的找到了”的信心。
第三条:错误标注是最隐蔽的坑。有些标注框稍微偏一点,模型一开始可能还能扛住,但随着训练轮次增加,这些错误标注会像坏老师一样,一遍一遍教模型“框的位置可以有偏差”,导致最终输出框不稳定。你会发现loss正常、mAP还行,但实际输出框就是“差那么一点”。遇到这种情况,除了重新检查标注,一个笨但有效的办法是:把训练集里损失最高的几十张图打印出来,人工看一遍是哪里的问题。通常一轮下来,就能抓出十来个标注错误。
第四条:关于数据增强。YOLOV5默认开启Mosaic增强,就是把4张图拼成一张再训练,对小目标检测很有效。但工业小数据集上Mosaic有一个副作用:很多数据本身是1920x1080的大图,缩放到640x640的时候缺陷已经被缩小了很多,再把4张图拼一起,每个缺陷就更小了。如果模型老是漏掉小缺陷,试试在训练时关闭Mosaic增强,或者把--img调成1280,让模型先用高分辨率“看清楚”缺陷长什么样,再逐步降低输入尺寸去推理。
第五条:训练集和验证集的比例不是越大越好。有些同学手里总共就几百张图,一上来就按9:1切,结果训练集几百张,验证集几十张,出来的验证mAP波动极大。工业小数据集的合理做法是:先把数据扩增到位,再按8:2划分。扩增不是简单翻转和旋转,还包括亮度变化、对比度变化、噪声叠加,这样模型才不会在换一个亮度之后就失效。
6. 后续可扩展的方向:从数据集到私有模型落地
跑通这套齿轮缺陷检测数据之后,你手上已经有了一条完整的从数据到训练的流水线。接下来要往工业场景落地的话,可以按这个顺序去扩展:
先迁移到自己的数据上。用自己的齿轮样本替换images和labels中的内容,类别名称和数量改成自己的,就可以直接训练私有模型。如果自己的样本不够,先别急着上复杂网络,用YOLOV5s+预训练权重迁移学习,能用最小的成本探出数据质量的天花板在哪。
再做一次全量标注重检。用训练好的模型跑一遍训练集,输出预测框和置信度,然后人工把所有置信度低于某个阈值的预测框找出来,看是不是标注漏了或者标错了。这种“模型辅助标注”的方法,在工业视觉领域真的很常用,能节省大量人工标注时间。
最后考虑推理端的部署。YOLOV5在这类数据上训练出来的模型权重,可以导出为ONNX、TensorRT或者OpenVINO格式,部署到边缘设备上。齿轮缺陷检测这种场景,通常不需要特别复杂的后处理,直接在检测框内判断“有缺陷/无缺陷”,就可以输出给PLC或者质检系统了。部署的时候可以根据实际硬件情况,把--img调到480甚至320,推理速度会有非常明显的提升,有些小缺陷也能保留。
说到底,这套齿轮缺陷检测数据集,不是让你只用来跑一个demo就完事。它的价值在于给你提供了一个完全符合YOLOV5训练规范的样本结构——目录该怎么建、标注该怎么标、训练验证该怎么切、模型该怎么调。把这条流水线理解透,后面换任何工业场景,你都能快速搭出一套可用的检测方案来。
我自己在拿到这类数据集时,通常会在训练前多花半小时做上面那些检查:跑一下标注情况统计、看一眼验证集图片分布、确认没有空标注。这半小时看起来是“耽误时间”,实际上能帮你省下后面几天调试的精力。尤其是工业数据,脏和乱才是常态,清洗数据永远比调网络结构更优先。
如果你正准备跑这套数据,建议第一次训练时先用默认参数把全流程走通,然后看results.png,再决定往哪个方向调。不要一上来就把超参数改得面目全非,那样你根本没法判断问题出在数据还是出在参数上。先跑通,再优化,这是所有目标检测项目的通用打法。
本文还有配套的精品资源,点击获取