简介YOLO机油泄露目标检测数据集面向工业安全监测与目标检测学习者基于真实场景采集的高质量图片标注框质量可靠适合石油化工、设备巡检等场景的算法研究与课程实践可直接用于YOLO系列模型训练。压缩包共2000个文件其中1986个xml文件为VOC格式标注并配套coco(json)与yolo(txt)标签另有Linux/Windows双版本环境搭建与训练教程html、三个Python划分脚本及训练列表txt整体约616.37MB文件组织清晰便于查阅。目前已有547人学习下载适合目标检测入门、课题设计与竞赛备赛者参考。资源附带三个Python划分脚本可按需求将图片与标签划入训练集、验证集、测试集训练教程结合实际案例讲解如何修改配置并训练自定义数据集可有效缩短环境搭建与数据准备时间适合从零开始跑通YOLO检测流程。1. 为什么说这个机油泄露数据集是目标检测落地最缺的那块拼图做工业视觉的人都有体会算法模型开源满天飞预训练权重随手就能下真正卡住项目进度的永远是标注数据。尤其机油泄露这类场景不像行人、车辆有海量公开数据集可用泄露点往往是小目标、低对比度、背景复杂自己标注一万张图的成本足以劝退绝大多数团队。这套YOLO机油泄露目标检测数据集直接打包了10000张图片同时给出VOC、COCO和YOLO三种格式标签外加划分脚本和训练教程本质上是把“数据采集→标注→格式转换→划分→训练”这条完整链路一次性交付了。对于正在做工业安全巡检、设备漏油监测、液压系统维护的工程师这份数据能让你跳过最枯燥的数据准备阶段直接把精力花在模型调参和漏检率优化上。对于想入门目标检测的新手三种格式标签本身就是最好的教材对比着看就能理解不同标注体系之间的转换逻辑。和那些只有图片没有标签、或者只给单一格式的野路子数据集相比这套数据最大的价值在于“开箱即用”配合训练教程基本能做到当天拿到数据、当天跑通训练流程。这里先明确一点后续所有操作都围绕官方YOLOv5和YOLOv8的常规工作流展开这也是目前社区落地最稳的路线。2. 三种标签格式的底层逻辑VOC、COCO、YOLO各自适合什么2.1 VOC格式的本质是XML文件理解文件夹结构是关键VOC格式源自PASCAL VOC挑战赛它的核心存储单元是XML文件每张图片对应一个同名XML。标注信息以树状结构组织最外层是annotation下面挂着folder、filename、source、size、object等节点。每个object里包含name类别名、pose、truncated、difficult以及bndboxbndbox里是xmin、ymin、xmax、ymax四个坐标值表示目标框的左上角和右下角。annotation folderJPEGImages/folder filenameleak_000123.jpg/filename size width1920/width height1080/height depth3/depth /size object nameoil_leak/name bndbox xmin452/xmin ymin318/ymin xmax678/xmax ymax529/ymax /bndbox /object /annotation这段XML描述的核心信息是图片leak_000123.jpg中在(452,318)到(678,529)这个矩形区域内存在一个oil_leak类别的目标图片尺寸为1920x1080。VOC格式的优势是直观、可读性强任何文本编辑器都能打开检查适合人工校验标注质量。但缺点也很明显每张图一个文件管理起来碎片化严重而且在训练时需要额外写解析器。VOC标准目录结构是Annotations放XML、JPEGImages放原图、ImageSets/Main放train.txt、val.txt这些划分文件。很多从VOC格式起步的玩家会在转换时漏掉ImageSets目录导致训练脚本找不到划分信息这个坑后面会细说。2.2 COCO格式用JSON统一描述标注信息全量集中COCO格式由Microsoft COCO数据集确立整个数据集的标注浓缩进一个JSON文件。顶层结构包含info、licenses、images、annotations、categories五个数组images数组记录每张图的id、file_name、width、heightannotations数组记录每个目标的image_id、category_id、bbox、area、iscrowdcategories数组定义类别id到名称的映射。{ images: [{id: 1, file_name: leak_000123.jpg, width: 1920, height: 1080}], annotations: [{id: 1, image_id: 1, category_id: 1, bbox: [452, 318, 226, 211], area: 47686, iscrowd: 0}], categories: [{id: 1, name: oil_leak, supercategory: none}] }注意COCO的bbox格式是[x, y, width, height]x和y是框左上角坐标width和height是框的宽高这和VOC的[xmin, ymin, xmax, ymax]不同。area字段可以手算宽高乘积也可以用工具自动生成。转换时最常出的错就是把两个坐标系的公式搞混直接把xmax减xmin当成x实际上是宽。COCO格式的最大价值是标准化和互操作性mmdetection、Detectron2这些框架原生支持COCO格式训练、评估一条龙。缺点是一个文件几百MB出了问题排查相对麻烦而且标注的可读性比XML差不适合人眼直接审查。2.3 YOLO格式用txt精简到极致和锚框机制深度绑定YOLO系列使用的标注格式是最精简的纯文本格式每一行代表一个目标包含五个数字class_id, x_center, y_center, width, height。前四个坐标全部做了归一化处理除以图片宽高所以取值范围在0到1之间和图片实际分辨率解耦。这一点是YOLO训练效率高的原因之一读取速度快且不需要像VOC那样边训练边解析XML。0 0.2943 0.3921 0.1177 0.1954这行数据表示类别id为0的目标归一化中心点坐标为(0.2943, 0.3921)归一化宽高为(0.1177, 0.1954)。类别id对应data.yaml文件里的类别顺序在YOLOv5和YOLOv8中通常从0开始编号。YOLO格式训练效率高但有个致命弱点仅凭txt文件无法还原类别名必须搭配一个yaml配置文件才能完整定义数据集。此外归一化坐标对转换脚本的精度要求高保留几位小数会直接影响框的像素级精度一般建议保留6位。如果数据集中包含难例样本、小目标特别多格式转换时就得做严格的质量校验框偏移一两个像素对结果影响不大偏移太多就会拉低召回率。三种格式各有适用场景实际项目中我一般统一转成YOLO格式训练VOC和COCO作为备份用于交叉验证。下面用一张参数表做个对比维度VOCCOCOYOLO存储形式每图一个XML单JSON文件每图一个txt坐标定义xmin,ymin,xmax,ymaxx,y,width,heightx_center,y_center,w,h归一化可读性高低中框架兼容需写解析器Detectron2等原生支持YOLO系列原生支持文件数量碎片化集中碎片化人工校验方便较难较方便3. 划分脚本实战把10000张图拆成训练集、验证集、测试集3.1 脚本核心逻辑随机划分与种子值的边界拿到数据后的第一件事永远不是训练而是先做数据划分。这套数据集自带划分脚本但理解其原理仍然重要——因为不同项目的划分比例、数据集大小、类别分布各不相同能自己改脚本才能应对变化。我一般会先把数据按7:2:1或8:1:1切分训练、验证、测试集比例取决于总样本量和任务复杂度。import os import random import shutil from sklearn.model_selection import train_test_split # 设置随机种子保证划分结果可复现 random.seed(42) image_dir images label_dir labels train_ratio, val_ratio, test_ratio 0.8, 0.1, 0.1 images [f for f in os.listdir(image_dir) if f.endswith(.jpg)] train_files, test_files train_test_split(images, test_sizetest_ratio, random_state42) train_files, val_files train_test_split(train_files, test_sizeval_ratio / (train_ratio val_ratio), random_state42)这段代码先用train_test_split把全部图片按10%拆出测试集再把剩余图片按验证集占比从剩余空间里拆出10%最终得到8:1:1的三份数据随机种子固定为42确保每次运行结果一致。注意这里拆的是文件名真正划分时要把同名标签文件一并移动否则训练时会因为找不到标签直接报错。划分完成后还要做一步关键校验——检查训练集和验证集的类别分布是否均衡。如果原始数据是按顺序排放的前8000张全是白天场景后2000张全是夜间场景直接随机划分没问题但如果图片是按泄露类型分目录存放的就必须在划分前做类别分层采样否则验证集会缺失某些类别训练出来的模型评估指标虚高。3.2 把VOC转成YOLO格式转换脚本与四个边界坑数据集里同时存在VOC和YOLO两种格式但实际用的时候通常要统一到一种。以VOC转YOLO为例核心逻辑是读入XML中bndbox的四个坐标值按照图片宽高换算成归一化坐标。这个转换看起来简单实际坑非常多。import xml.etree.ElementTree as ET def voc_to_yolo(xml_path, img_width, img_height, class_list): tree ET.parse(xml_path) root tree.getroot() yolo_lines [] for obj in root.findall(object): cls_name obj.find(name).text if cls_name not in class_list: continue cls_id class_list.index(cls_name) bndbox obj.find(bndbox) xmin int(float(bndbox.find(xmin).text)) ymin int(float(bndbox.find(ymin).text)) xmax int(float(bndbox.find(xmax).text)) ymax int(float(bndbox.find(ymax).text)) # 换算归一化坐标 x_center ((xmin xmax) / 2) / img_width y_center ((ymin ymax) / 2) / img_height w (xmax - xmin) / img_width h (ymax - ymin) / img_height yolo_lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) return yolo_lines四个容易踩的坑集中说明一下。第一个坑是XML中的坐标可能是浮点型字符串直接int()会截断报错稳妥做法是先float再int。第二个坑是部分标注工具的xmax和ymax不是实际边界值坐标系原点和图片尺寸语义在不同工具间有差异转换时务必抽10张图人工核对。第三个坑是越界框问题数据集中如果存在标注框超出图片边界的脏数据归一化后w或h会大于1训练时YOLO直接报错或产生NaN损失。转换前要做一次全量越界检查把异常标注过滤掉或裁剪到边界内。第四个坑是类别名不一致VOC的XML里写着oil_leakyaml里配置的类别名却叫oil_leakageclass_list.index会直接抛ValueError最终整个文件转换失败。这类问题排查起来非常费时间正确做法是在转换脚本里加一个类别名映射表把同义词统一映射到标准类别名。3.3 划分后的目录结构与数据校验数据划分和格式转换完成后最终的目录结构应该长这样dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ ├── data.yaml └── classes.txt每个子目录里的图片名和标签名必须一一对应这是YOLO训练的最基本前提。校验脚本的核心逻辑就是遍历labels目录下每个txt文件检查同名的jpg是否存在同时检查txt文件是否为空、每行的类别id是否超出类别总数。import os for split in [train, val, test]: label_dir flabels/{split} image_dir fimages/{split} for label_file in os.listdir(label_dir): img_name label_file.replace(.txt, .jpg) img_path os.path.join(image_dir, img_name) if not os.path.exists(img_path): print(f[错误] 标签存在但图片缺失: {img_name}) with open(os.path.join(label_dir, label_file), r) as f: lines f.readlines() for line in lines: parts line.strip().split() if len(parts) ! 5: print(f[错误] 格式异常: {label_file} 第{lines.index(line)1}行)校验脚本最好在每次训练前都跑一遍尤其是刚换过数据集或改过标注的节点上。数据质量是目标检测里最容易被轻视的部分这里翻车一次后面所有时间都在浪费。另外建议统计一下所有框的宽高分布如果标注框大部分集中在图像面积的1%以下后续训练就必须把anchor设置调小否则小目标的召回率会非常难看。4. 用这份数据集跑通YOLO训练从预训练权重到损失曲线4.1 环境准备与依赖版本对应关系在动手训练前先把环境装干净。YOLOv5和YOLOv8对Python、PyTorch的版本都有隐性要求版本不匹配会出现一些非常玄学的报错比如GPU利用率直接跑满但loss不掉。我一般用Python 3.9搭配PyTorch 2.0以上版本CUDA 11.8或12.1这套组合在YOLOv5和YOLOv8上都验证过比较稳定。# 创建虚拟环境避免污染系统Python conda create -n yolo python3.9 -y conda activate yolo # 安装PyTorch根据CUDA版本选择对应命令 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 # 克隆YOLOv5并安装依赖 git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txt如果要改用YOLOv8直接pip install ultralytics即可它的封装更完善训练命令更简洁底层细节也做了不少优化。从实际项目的稳定性角度看YOLOv5依旧是个不会出错的选择尤其在自定义数据和老旧GPU上兼容性更好。YOLOv8的优势是训练速度更快、小目标检测精度有提升但对显存的要求也更高这两个版本之间的选择按自己的显卡来定RTX 3090以下建议YOLOv5以上随意。4.2 数据集配置文件data.yaml的写法与路径坑YOLO训练需要一份data.yaml来告诉框架数据在哪里、类别有几种。这是数据准备和训练之间的衔接点也是最容易因路径出错的地方。train: /home/user/dataset/images/train val: /home/user/dataset/images/val test: /home/user/dataset/images/test nc: 1 names: [oil_leak]train和val写的是图片目录的绝对路径不是标签目录这点很容易搞混。nc是类别数量names是类别名称列表顺序必须和标签txt里的class_id一一对应顺序反了模型就会用错误的学习目标训练训练出来的模型输出类别名和预测框对不上整体全部作废。另一个常见问题是使用相对路径导致训练脚本换目录后找不到数据。我一般会写一个环境变量或者统一用绝对路径配合文档标注说明数据路径不让这些低级的路径问题浪费调优时间。建议在正式训练前用python -c import yaml; print(yaml.safe_load(open(data.yaml)))检查yaml语法避免格式错误导致训练中途崩溃。4.3 训练脚本中的核心参数img、batch、epochs的取舍一切就绪后开始训练YOLOv5和YOLOv8的训练参数含义基本一致直接以YOLOv5为例说明核心参数的意义和设置逻辑。python train.py --data data.yaml --weights yolov5s.pt --img 640 --batch 16 --epochs 100 --device 0--weights指定预训练权重yolov5s.pt是基于MS COCO预训练的模型初始权重模型大小适中精度和速度平衡适合机油泄露这类单类别检测任务。--img指定训练时的输入尺寸为640x640YOLO会把任意尺寸的图片缩放后输入网络这个值的设置逻辑是原图分辨率足够高且小目标多就设大一点显存有限就优先保证batch不要太小。--batch是批大小直接影响梯度更新的稳定性和训练速度--epochs是训练轮数建议先跑100轮观察损失收敛情况如果损失曲线在末尾还在下降说明数据量大或者任务难需要再往上加。显存不足时优先降batch其次降img不建议同时把两者都降得很低会严重影响模型性能。训练过程中如果GPU利用率一直很低大概率是数据加载成了瓶颈检查num_workers参数是否有设置默认0代表主进程处理数据量大时速度会很慢。# 以YOLOv8为例训练命令更简洁 from ultralytics import YOLO model YOLO(yolov8s.pt) results model.train(datadata.yaml, epochs100, imgsz640, batch16, device0)YOLOv8的train接口把大部分参数放到函数参数里适合直接写在Python脚本里做超参数实验。它会自动生成runs/detect/train目录保存每轮的权重文件、损失曲线和验证指标不用手动记录。4.4 训练到一半怎么判断收敛状态训练不是设完参就等着收工要定期看训练日志。前50轮以内损失应该快速下降之后进入平台期缓慢收敛。重点看两个关键指标训练损失持续下降、验证集上的mAP稳步上升两者缺一不可。如果验证集表现上不去训练损失却很低大概率是过拟合了需要加早停或者减少训练轮数。YOLOv5训练日志里每个epoch输出一列指标包括box_loss、cls_loss以及P、R、mAP50、mAP50-95。机油泄露场景要看mAP50也就是IoU0.5时的均精度因为这个任务里我们更关心能不能把泄露点找出来而不是框的精度有多高。mAP50-95是严格指标反映检测框和真实框的重合质量对小目标来说这个值达到0.5以上基本就可以用了。如果遇到损失不减或指标震荡优先检查数据集是否有标注错乱、类别不平衡、锚框设置不合理等问题模型本身出问题的概率远小于数据出问题的概率。训练完成后runs目录下会保留完整的训练过程数据包括混淆矩阵、PR曲线、标签可视化图这些是判断模型是否可用的第一手资料。5. 避坑指南标签、路径、显存三座大山5.1 标签错位导致损失函数直接炸掉现象训练开始后不到几个epoch损失值出现NaN或者骤增几个数量级训练过程直接报废。原因图片和标签文件不匹配常见于训练集图片名是IMG_001.jpg标签文件名却叫img_001.txt大小写不一致或扩展名不同导致标签加载了错误内容。另一个原因是标签中的坐标越界比如归一化后的width写了1.2模型计算损失时出现无效数值。解决写一个统一的文件名规范化脚本将所有图片和标签统一转为小写命名去掉特殊字符再做一一对应检查。标签越界检查同样要跑一遍全量把width或height大于1的过滤掉或者裁剪到[0,1]范围内。这个锅不在模型数据上花十分钟能解决的事硬着头皮训练等于浪费时间。5.2 路径写死导致迁移训练无处下手现象在自己电脑上训练得好好的把代码和数据集拷到服务器上训练报错找不到图片路径data.yaml改了路径但其他地方还有绝对路径在捣乱。原因代码里存在多处硬编码的绝对路径不止data.yaml一处比如加载预训练权重时直接写C:/Users/xxx/Desktop/yolov5/yolov5s.pt换了机器路径失效。解决把所有路径集中到config.py或环境变量里统一管理代码只引用变量不写死字符串。目录结构也尽量保持相对独立把数据集和项目代码放在同一根目录下用os.path.join动态拼接路径保证换机器后只需改一处配置。5.3 显存不足或batch设得太大导致OOM现象启动训练后立刻报错CUDA out of memory或者运行到一半显存爆掉进程被杀。原因batch和img设得过大超出了显存容量尤其是8GB显存的卡硬跑batch32、img640不爆才怪。解决先用nvidia-smi确认显存大小再做预算。8GB显存建议batch16,img640跑yolov5s16GB以上可以试着batch32。如果确实需要大batch开启梯度累积把batch64拆成四个batch16累积更新。另一个技巧是开启--cache参数把图片提前缓存到内存能大幅减少GPU等待时间显存占用反而会降低。5.4 预训练权重下载失败或权重损坏现象train.py启动后卡在Downloading yolov5s.pt网络不好一直失败或者下载到一半中断解压时CRC校验错误。原因GitHub Releases上的权重文件托管在国外服务器国内网络环境下下载不稳定。解决用镜像地址手动下载权重文件放到weights目录再通过--weights参数指定本地权重路径跳过自动下载。下载失败后不要急着重试检查文件完整性用md5sum比对官方给出的哈希值保证权重文件没损坏。这个坑虽然不起眼但确实卡住过不少人提前备好权重文件能避免在最开始就翻车。6. 验证与进阶用混淆矩阵和PR曲线确认模型真的能用训练跑完不代表模型能用还要过验证这一关。YOLO训练目录下的confusion_matrix.png和PR_curve.png是判断模型质量最重要的两张图。混淆矩阵的横坐标是真实类别纵坐标是预测类别对角线上的值越高说明分类越准。对于机油泄露这个单类别任务重点看background类的误检率——如果大量负样本被错误预测成oil_leak说明模型的置信度阈值设低了推断时需要调高conf_thres。PR曲线反映的是不同置信度阈值下精确率和召回率的权衡关系曲线越靠近右上角模型越好。mAP50其实就是PR曲线下的面积在IoU0.5时的值这个数能达到0.85以上基本可以满足工业巡检场景的初步要求。如果mAP50很高但mAP50-95偏低说明模型对框的位置预测不够精细后续可以用更高分辨率的输入图测试或者换yolov8m这类更大的模型再训练。验证时还有一个实用技巧把测试集图片丢进模型做批量推理输出可视化结果图人工过一遍标注框的位置、大小、漏检的样本长什么样。这个步骤没人能替代模型指标再漂亮也不如实实在在看一眼预测效果。重点看小目标的检出率、光线变化下的鲁棒性、以及不同泄露程度的区分能力。我自己跑这类工业检测项目时有个习惯训练结束后挑出top 10的误报样本和漏报样本按特征归类比如全部是反光区域误报还是管道接头处漏检。这些样本的特征是后续优化的重要方向——如果都是反光造成的误报考虑在数据增强里加入更多光照扰动如果都是小目标漏检调整anchors、提高输入分辨率或融合高分辨率特征层是三个最有效的方向。这一轮改进完再训练模型基本能上一个大台阶。希望这份数据集加训练流程能帮你少踩几个坑把时间真正花在模型调优而不是数据折腾上。方向对了剩下的交给迭代。本文还有配套的精品资源点击获取