ARTICLE DETAIL

资讯详情

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

工业视觉实战:从零构建YOLOv5齿轮检测数据集与训练调优指南

工业视觉实战:从零构建YOLOv5齿轮检测数据集与训练调优指南 简介本资源是一套专为工业视觉检测场景设计的齿轮型号识别目标检测数据集面向YOLOv5算法初学者与制造业AI质检开发者解决小样本工业零件多类别精准定位难题。数据严格遵循YOLOv5目录规范组织含3个实际产线常见齿轮型号B65、B6H、BPN的标注样本覆盖训练集3861图/txt、验证集351图/txt与测试集174图/txt共2000个文件其中1999个为YOLO格式标签txt含归一化中心坐标与宽高1个为开箱即用的可视化脚本show.py——无需修改参数运行后自动加载任意图片并绘制带类别标签的边界框便于快速验证标注质量与模型输出效果。压缩包大小332.01MB结构清晰、即取即用已获135人学习下载显著降低工业检测类项目的数据准备门槛与调试成本。1. 项目背景与核心价值最近在做一个工业视觉相关的项目需要识别传送带上不同型号的齿轮以便进行后续的分拣和装配。一开始想用传统的图像处理模板匹配但现场光照变化、齿轮表面油污、以及不同角度的摆放让传统方法的鲁棒性直线下降调试成本高得吓人。于是转向基于深度学习的目标检测就成了必然选择。YOLOv5以其在速度和精度上的优秀平衡以及极其友好的工程化生态成为了我的首选。这个项目最核心、也最耗时的一步就是构建一个高质量的数据集。网上公开的工业零件数据集很少更别说特定型号的齿轮了。所以从零开始采集、标注、整理一个符合YOLOv5格式的齿轮型号识别数据集是项目成败的关键。我最终整理了一个包含3个类别齿轮的数据集并严格按照YOLOv5的目录格式划分了训练集和验证集。这个过程踩了不少坑也积累了一些非常实用的经验今天就把这个数据集的构建思路、目录结构设计、标注过程中的注意事项以及如何利用这个数据集进行有效训练的心得完整地分享出来。无论你是刚接触工业视觉的工程师还是正在寻找一个结构清晰、可直接复用的目标检测数据集范例这篇文章都能给你提供一条从数据到模型的清晰路径。我们不止谈理论更聚焦于实操一张图片该怎么拍标注框怎么画才算合格YOLOv5的data.yaml文件里每个参数到底什么意思训练时如果loss不降该怎么办这些实战中才会遇到的问题我都会结合这个齿轮数据集一一拆解。2. 齿轮识别任务分析与数据采集规划在动手采集图片之前必须先把任务定义清楚。盲目拍照只会得到一堆无用的数据后期标注和训练都会事倍功半。2.1 明确检测目标与类别定义我的任务是识别三种不同型号的齿轮姑且命名为Gear_AGear_BGear_C。它们的主要区别在于齿数、外径和中心孔尺寸。在定义类别时有几点需要特别注意类别粒度是只区分“齿轮A”和“齿轮B”还是需要进一步区分“齿轮A-正面”、“齿轮A-侧面”对于装配场景通常只需要识别型号因此我选择了前者。如果你的场景需要判断齿轮的朝向例如抓取点识别那么就需要定义更细的类别。遮挡与重叠产线上齿轮可能堆叠或部分被遮挡。我们需要决定是否标注被严重遮挡、可见部分不足50%的物体。我的原则是只要关键特征如齿形还能被肉眼大致分辨就进行标注这有助于模型学习在复杂情况下的识别能力。背景干扰物画面中可能出现的扳手、螺丝、包装盒等不属于检测目标坚决不标注。但可以在采集时有意让一些干扰物入镜增加数据的复杂性提升模型泛化性。2.2 数据采集策略与设备选型采集是数据质量的源头。为了模拟真实产线环境我设计了以下采集方案设备使用了一台普通的USB工业相机分辨率1280x720。没必要一开始就追求高端相机关键在于光照和拍摄角度。光照这是工业视觉的命门。我使用了环形LED光源从顶部均匀打光目的是消除金属表面的反光和高光让齿轮的边缘和纹理清晰可见。尝试了不同色温白色、暖白色最终发现白色光在金属零件上表现更稳定。切记要固定光照条件如果现场光照会变化那么采集时就要涵盖这些变化如白天、晚上、不同灯光模式。拍摄角度与距离相机固定在传送带正上方约50cm处。同时我手动改变了齿轮的摆放姿态进行拍摄平面旋转将齿轮在水平面内旋转0度、30度、60度、90度等。轻微倾斜模拟齿轮未放平的状态。距离变化让齿轮在视野中呈现近、中、远三种大小对应不同的像素面积。这对于训练模型适应不同尺度的目标至关重要。背景传送带是深绿色。我额外采集了部分齿轮放在灰色桌面、黑色橡胶垫上的图片以丰富背景多样性。数量每个类别的齿轮我最终采集了约300-400张原始图片。初始目标可以定在每类150-200张通过后续的数据增强来弥补数量的不足。注意采集时务必为每张图片做好记录最简单的办法就是用类别和序号命名文件夹例如raw_data/Gear_A/,raw_data/Gear_B/。原始图片建议保存为.jpg格式在质量和文件大小间取得平衡。3. YOLOv5数据集目录格式详解与构建数据采集完后一堆图片散落在文件夹里是没用的。YOLOv5有一套约定俗成的目录格式严格遵守这个格式能避免很多后期麻烦。下面是我为齿轮数据集构建的目录结构gear_detection_dataset/ ├── images/ │ ├── train/ │ │ ├── 000001.jpg │ │ ├── 000002.jpg │ │ └── ... │ └── val/ │ ├── 000050.jpg │ ├── 000051.jpg │ └── ... └── labels/ ├── train/ │ ├── 000001.txt │ ├── 000002.txt │ └── ... └── val/ ├── 000050.txt ├── 000051.txt └── ...3.1 核心目录与文件说明images/与labels/这是两个必须的顶级目录分别存放图像文件和对应的标注文件。train/与val/在images和labels下都必须创建同名的train训练集和val验证集子目录。YOLOv5在训练时会根据这个结构自动寻找对应的图片和标签。文件对应关系这是关键images/train/000001.jpg对应的标注文件必须是labels/train/000001.txt。文件名不含扩展名必须严格一致。通常使用数字序号或具有唯一性的ID来命名避免使用中文或特殊字符。3.2 数据划分训练集与验证集如何将总数据划分为训练集和验证集常见的比例是 8:2 或 9:1。我采用了 8:2 的比例。划分原则绝不能简单地把前80%的图片作为训练集后20%作为验证集。必须随机打乱后划分确保两个集合中的数据分布如类别比例、光照条件、拍摄角度是相似的。实操方法写一个简单的Python脚本。读取所有图片路径使用random.shuffle打乱顺序然后按比例切片。更稳妥的做法是确保每个类别的图片在训练集和验证集中都有出现。import os import random import shutil # 假设所有原始图片都在 raw_images 文件夹 raw_image_paths [os.path.join(raw_images, f) for f in os.listdir(raw_images) if f.endswith(.jpg)] random.shuffle(raw_image_paths) split_idx int(len(raw_image_paths) * 0.8) train_paths raw_image_paths[:split_idx] val_paths raw_image_paths[split_idx:] # 复制到目标目录 def copy_files(file_paths, image_dest, label_dest): for img_path in file_paths: # 复制图片 shutil.copy(img_path, image_dest) # 假设标注文件同名但扩展名为.txt在另一个raw_labels文件夹 label_name os.path.splitext(os.path.basename(img_path))[0] .txt label_src os.path.join(raw_labels, label_name) if os.path.exists(label_src): shutil.copy(label_src, label_dest) copy_files(train_paths, gear_detection_dataset/images/train/, gear_detection_dataset/labels/train/) copy_files(val_paths, gear_detection_dataset/images/val/, gear_detection_dataset/labels/val/)3.3 数据标注从工具到YOLO格式标注是数据集中最耗时但最决定性的环节。我使用的是LabelImg这款开源工具它支持直接导出YOLO格式。标注过程打开LabelImg设置标注格式为YOLO。用矩形框Bounding Box紧密地框住整个齿轮。框的边界应尽可能贴近齿轮外缘但不必像素级精确适当留一点空隙是可以接受的。选择对应的类别Gear_A, Gear_B, Gear_C。关键技巧对于部分遮挡的齿轮仍然框出整个齿轮的估计位置包括被遮挡的部分。这能教会模型根据可见部分推断整体。YOLO标签格式解析 LabelImg会为每张图片生成一个同名的.txt文件。每一行代表一个目标物体格式为class_id x_center y_center width heightclass_id类别的索引从0开始。例如0代表Gear_A1代表Gear_B2代表Gear_C。x_center,y_center,width,height目标框中心点的x坐标、y坐标、宽度和高度。这些值都是归一化后的即相对于图片宽度和高度的比例范围在0到1之间。计算公式如下x_center (框左上角x坐标 框宽度/2) / 图片宽度 y_center (框左上角y坐标 框高度/2) / 图片高度 width 框宽度 / 图片宽度 height 框高度 / 图片高度例如一张800x600的图片上一个齿轮的框左上角在(200, 100)框大小为200x150。那么x_center (200 200/2) / 800 0.375 y_center (100 150/2) / 600 0.2917 width 200 / 800 0.25 height 150 / 600 0.25如果这个齿轮是Gear_Bclass_id1那么标签行就是1 0.375 0.2917 0.25 0.25重要心得标注完成后一定要进行可视化检查。可以写个脚本读取几张图片和对应的标签文件将框画回图片上检查框的位置和类别是否正确。这是发现标注错误如类别标错、框太大或太小最有效的方法能避免把错误带入训练导致模型学习到错误知识。4. 核心配置文件data.yaml的编写与调优数据集目录准备好后需要告诉YOLOv5关于这个数据集的所有信息。这就是data.yaml文件的作用。它通常放在数据集目录的同级或项目根目录下。下面是我为齿轮数据集编写的gear_data.yaml# 齿轮型号识别数据集配置文件 # 数据集根目录路径 (相对于本yaml文件) path: ../gear_detection_dataset # 训练集和验证集的图片目录 (相对于path) train: images/train val: images/val # 类别数量 nc: 3 # 类别名称列表顺序必须与标注时的class_id对应 names: [Gear_A, Gear_B, Gear_C] # 可选参数高级配置 # 是否自动计算锚框(anchor)对于自定义数据集建议设为True让YOLOv5在训练开始时重新聚类 autoanchor: True # 图片缩放时的填充策略保持长宽比 rect: False # 对于齿轮这种目标大小不一的情况通常设为False使用方形填充4.1 参数深度解析path: 这是所有相对路径的基准。通常建议使用绝对路径或者在训练时通过命令行参数--data指定避免路径错误。我这里的../表示yaml文件在数据集目录的上一级。train/val: 路径是相对于path的。YOLOv5会根据这个路径去path指定的目录下寻找images/train和labels/train。nc与names: 必须完全对应。names列表的第一个元素对应class_id0第二个对应class_id1以此类推。这个顺序在训练、验证和推理时都必须一致否则类别预测会完全混乱。autoanchor: 锚框Anchor是YOLO系列算法用于预测边界框的预设框。YOLOv5预训练模型是在COCO等通用数据集上聚类得到的锚框。我们的齿轮尺寸分布可能与COCO差异很大。设置为True后YOLOv5会在训练的第一个epoch前在你的训练集上重新运行K-means聚类计算出一组更适合你数据集的锚框尺寸。对于自定义数据集强烈建议开启此选项这通常能带来小幅度的精度提升。rect: 设置为True时训练会进行矩形训练Rectangular Training即在一个batch内将图片统一缩放到一个最小公倍数的尺寸减少信息冗余加快训练速度。但我们的齿轮目标可能出现在图片任何位置且需要保持原始长宽比以维持特征所以我选择了False采用传统的方形缩放如缩放到640x640。4.2 路径问题的常见坑路径错误是新手最常遇到的问题会导致Dataset not found或Labels not found的错误。绝对路径 vs 相对路径在yaml文件中使用相对路径更灵活但需要清楚当前工作目录。最保险的方法是在训练命令中直接指定yaml文件路径例如python train.py --data ./gear_data.yaml。YOLOv5会以该yaml文件所在目录为基准解析其中的相对路径。检查图片和标签是否配对运行以下命令可以快速检查是否有图片缺少标签或者标签缺少图片# 在数据集根目录下 ls images/train/*.jpg | wc -l ls labels/train/*.txt | wc -l两个数字应该相等。如果不相等就要用脚本排查具体是哪些文件缺失。5. 数据增强策略让小数据集发挥大作用我们每类只有几百张图片对于深度学习模型来说远远不够。数据增强Data Augmentation是“凭空”创造更多训练样本、提升模型泛化能力的核心技术。YOLOv5内置了非常强大的数据增强管道我们需要根据齿轮图像的特点进行合理配置。5.1 YOLOv5内置增强与参数调整YOLOv5的训练脚本train.py通过hyp.scratch.yaml或hyp.finetune.yaml等超参数文件来控制增强强度。我们不需要修改代码只需调整这些超参数。以下是一些对工业检测特别有效的增强及其原理色彩空间扰动(hsv_h,hsv_s,hsv_v)作用模拟光照变化、相机白平衡漂移、零件表面氧化或油污造成的颜色变化。调整建议对于齿轮这种颜色特征不关键主要是形状和纹理但受光照影响大的目标可以适当增强hsv_v明度和hsv_s饱和度的扰动范围比如从默认的0.015/0.7/0.4调到0.02/0.8/0.5。hsv_h色调扰动不宜过大以免改变金属本色。平移、缩放、旋转(translate,scale,rotate)作用模拟目标在视野中的位置变化、距离变化以及摆放角度变化。调整建议因为我们采集时已经包含了多角度和距离所以这些增强可以保持中等强度。rotate参数对于圆形对称的齿轮尤其友好可以设置较大的角度范围如-10, 10度让模型学会旋转不变性。透视变换(perspective)作用模拟相机视角并非完全正对目标时产生的轻微形变。调整建议对于固定角度的顶视相机这个增强强度应设得很低如0.0001因为现实中视角变化很小。如果是手持设备或多角度拍摄可以适当增加。马赛克增强Mosaic与混合MixUpMosaic将四张训练图片随机拼接成一张。这能极大地丰富背景让模型在一个批次内看到更多样化的上下文信息并且自然地增加了小目标的出现频率因为大图被缩小了。对于我们的齿轮数据集Mosaic非常有用它能模拟齿轮散乱堆放、背景复杂的场景。MixUp将两张图片以一定比例混合。这能增加决策边界的平滑性提升模型鲁棒性。但对于边界需要清晰区分的检测任务强度不宜过高。5.2 针对齿轮数据的自定义增强思路除了调整超参数有时我们需要引入一些YOLOv5默认没有的、针对特定场景的增强模拟油污与划痕使用OpenCV或Albumentations库在图片上随机添加一些深色斑点、条纹或模糊区域模拟齿轮表面的污染或磨损。高斯噪声与模糊增加图片的高斯噪声或施加轻微的运动模糊、高斯模糊模拟相机抖动或对焦不准的情况。亮度与对比度随机变化模拟产线灯光老化或电压不稳造成的照明波动。实施方法可以修改YOLOv5的datasets.py文件中的load_mosaic或augment函数在加载图片后、送入网络前加入自定义的增强操作。不过这需要一定的编程能力。更简单的方法是先使用这些增强算法离线处理一批图片扩充原始数据集然后再进行标注和训练。核心原则增强必须合理。增强的目标是模拟真实世界中可能发生的变化。如果产线上齿轮永远是干净、正放、光照恒定的那么过度的、不合理的增强如极端色彩扭曲、大幅度的非刚性形变反而会误导模型降低其在实际场景中的性能。建议的策略是先使用YOLOv5默认的中等强度增强进行训练然后在验证集上测试。如果模型在某个特定变化如侧光下表现不佳再有针对性地增加相关增强的强度。6. 模型训练、验证与问题排查实战数据集和配置文件都准备好后就可以开始训练了。这里以YOLOv5s小型模型为例展示完整的训练流程和问题排查方法。6.1 训练命令与关键参数解读在YOLOv5项目根目录下运行类似下面的命令python train.py \ --img 640 \ # 训练图片尺寸保持默认640即可 --batch 16 \ # 批次大小根据你的GPU显存调整。8G显存可设16更小显存可设8或4。 --epochs 100 \ # 训练轮数。对于小数据集100-150轮通常足够。 --data ./gear_data.yaml \ # 指向我们的数据集配置文件 --cfg models/yolov5s.yaml \ # 选择模型结构配置文件 --weights yolov5s.pt \ # 加载预训练权重这是迁移学习的关键能加速收敛。 --name gear_exp1 \ # 本次实验的名称用于保存结果 --cache \ # 使用RAM或磁盘缓存图片加速训练如果内存足够 --device 0 \ # 使用第0块GPU。如果是CPU则设为 --device cpu --workers 4 # 数据加载的线程数根据CPU核心数调整通常设为4或8。--weights yolov5s.pt强烈建议使用预训练权重。这相当于让模型从一个“见过世面”的状态开始学习它已经具备了提取通用图像特征边缘、纹理、形状的能力。我们只需要让它微调Fine-tune专注于学习“齿轮”这个特定领域的特征这比从零训练快得多效果也更好。--batch批次大小影响训练稳定性和速度。越大越稳定但需要更多显存。如果出现“CUDA out of memory”错误就减小batch值。--epochs不是越多越好。需要通过观察验证集指标来判断何时停止早停Early Stopping。6.2 训练过程监控与指标解读训练开始后控制台会输出日志更重要的是YOLOv5会在runs/train/gear_exp1目录下生成一系列可视化结果results.png这是最重要的监控图表包含多个子图损失曲线Box, Obj, Clstrain/box_loss,val/box_loss边界框回归损失。理想情况是训练和验证损失都平稳下降。如果验证损失在中间开始上升而训练损失继续下降说明过拟合了。train/obj_loss,val/obj_loss目标置信度损失。反映模型判断网格内是否有目标的能力。train/cls_loss,val/cls_loss分类损失。对于我们的3类齿轮看这个损失是否平稳下降。性能指标曲线metrics/precision,metrics/recall精确率和召回率。我们希望两者都高。如果精确率高但召回率低说明模型太保守很多齿轮没检测出来如果召回率高但精确率低说明模型乱报误检多。metrics/mAP0.5最核心的指标表示在交并比IoU阈值为0.5时的平均精度mean Average Precision。这个值会随着训练逐步上升最终趋于平稳。训练的目标就是让这个值在验证集上达到最高。验证结果可视化在val_batch*_labels.jpg和val_batch*_pred.jpg中可以看到验证集图片的真实标签Ground Truth和模型预测结果的对比。这是定性评估模型好坏最直观的方式。检查模型是否漏检该画的框没画、误检在背景上乱画框、或者类别分错Gear_A的框标成了Gear_B。6.3 常见问题与排查指南问题一训练Loss损失居高不下或剧烈震荡。可能原因1学习率Learning Rate太大。排查YOLOv5默认使用了带热身的自适应学习率调度器。但如果一开始损失就爆炸变成NaN可能是初始学习率过高。可以尝试在命令中添加--lr 0.01默认是0.01来调小例如设为--lr 0.001。可能原因2数据标注有严重错误。排查立即暂停训练用之前提到的可视化脚本检查训练集和验证集的标注。重点检查是否有类别标错、框的位置严重偏离物体、或者同一个物体被重复标注。可能原因3锚框Anchor不匹配。排查确保data.yaml中autoanchor: True。训练开始时控制台会输出“AutoAnchor: Running kmeans for 9 anchors on X bounding boxes...”。如果给出的新锚框尺寸与你数据集中目标框的尺寸分布差异巨大说明数据标注的宽高比可能有问题。问题二验证集mAP很低但训练集Loss已经很低过拟合。现象train/box_loss持续下降但val/box_loss在某个epoch后开始上升。val/mAP0.5达到一个峰值后开始下降。解决方案增加数据增强提高hyp文件中增强参数的强度特别是hsv、translate、scale让模型看到更多样的数据。使用更轻量级的正则化YOLOv5默认已经包含了DropOut等正则化。可以尝试微调--dropout参数如果模型支持但效果通常不如数据增强明显。减少模型复杂度如果你用的是yolov5m或yolov5l可以换回更小的yolov5s。小模型更不容易过拟合小数据集。早停Early Stopping手动监控val/mAP0.5当其在连续10-20个epoch内不再提升时就停止训练。YOLOv5本身没有内置早停需要自己写回调或手动判断。问题三某一类齿轮的识别精度特别差。排查查看runs/train/gear_exp1/confusion_matrix.png混淆矩阵。这个矩阵显示了类别间的误判情况。如果Gear_A很多被误判为Gear_B说明这两个类别的特征可能比较相似。解决方案检查数据平衡确保训练集中每个类别的图片数量大致相等。如果Gear_A只有50张而Gear_B有300张模型自然会偏向Gear_B。需要对少的类别进行过采样复制或数据增强。分析特征差异人工观察Gear_A和Gear_B的图片找出它们最明显的区别如齿数、中心孔形状、是否有标记。如果视觉区别很小可能需要考虑增加额外的检测维度如结合尺寸测量或者重新审视分类的必要性。调整分类损失权重这是一个进阶操作。可以为样本数量少的类别在损失函数中赋予更高的权重迫使模型更多关注它们。这需要在代码层面修改损失函数。7. 模型导出与部署前验证训练出一个满意的模型后比如验证集mAP0.5达到了0.95以上工作还没结束。我们需要将模型导出为可部署的格式并进行最终测试。7.1 模型导出为ONNX或TorchScriptYOLOv5提供了方便的导出脚本python export.py \ --weights runs/train/gear_exp1/weights/best.pt \ # 训练得到的最佳权重 --img 640 \ # 输入图片尺寸 --batch 1 \ # 批次大小部署时通常为1 --include onnx \ # 导出为ONNX格式也可选择 torchscript --dynamic \ # 允许动态输入尺寸可选 --simplify # 简化ONNX模型推荐ONNX格式开放神经网络交换格式被大多数推理引擎如OpenVINO, TensorRT, ONNX Runtime支持是工业部署的首选。TorchScriptPyTorch原生的序列化格式如果你打算在PyTorch环境下部署可以选择这个。导出后验证务必运行python detect.py --weights ./path/to/exported_model.onnx对几张测试图片进行推理确保导出过程没有错误精度没有显著下降。7.2 构建最终测试集与性能评估训练集和验证集是模型“见过”的数据。为了最终评估模型的真实泛化能力我们需要一个全新的、在训练和验证中完全没出现过的测试集。测试集构建从原始数据中再预留一部分例如10%在划分训练/验证集时就直接拿出来全程不参与训练和超参数调整。全面测试在测试集上运行模型不仅要看mAP更要进行压力测试极端光照测试模拟过曝、欠曝、侧光等。遮挡测试用其他物体部分遮挡齿轮。模糊与噪声测试对测试图片施加运动模糊、高斯噪声。新背景测试将齿轮抠图粘贴到完全没见过的背景上。分析失败案例对测试集中所有识别错误漏检、误检、错检的案例进行逐一分析找出模型的薄弱环节。这能为后续的数据集补充和模型迭代提供最直接的指导。7.3 项目复盘与迭代建议完成第一版模型后一个好的实践是进行项目复盘数据质量评估回顾标注质量是否有可以统一的标注规范模糊、有争议的标注案例如何处理模型选择反思YOLOv5s是否够用如果对速度要求极高可以尝试更小的模型如YOLOv5n如果精度不满足且硬件允许可以尝试更大的模型YOLOv5m/l/x或新一代的YOLOv8。部署考量模型最终要运行在什么设备上是工控机、嵌入式设备如Jetson Nano、RK3568还是云端不同的平台对模型格式ONNX, TensorRT, TFLite、算力和功耗有不同要求这可能会反过来影响你训练模型时的选择如是否进行量化感知训练。构建一个高质量的齿轮目标检测数据集远不止是标注图片那么简单。它贯穿了从业务理解、数据采集、规范制定、工具使用、到训练调优和部署验证的完整链路。每一个环节的细微疏忽都可能在最终的模型效果上被放大。这个过程中积累的关于数据平衡、增强策略、过拟合处理、问题排查的经验其价值甚至超过了模型本身。当你下次面对另一个工业零件比如轴承、螺丝、PCB板时这套方法论依然适用。记住在AI落地的战场上高质量的数据是比任何 fancy 的算法都更坚固的基石。本文还有配套的精品资源点击获取
返回列表