简介面向目标检测学习与施工安全场景这份压缩包提供了YOLO反光衣是否穿戴检测数据集内含10000张真实场景图片穿/未穿两类样本均有覆盖场景丰富且贴近实际工地环境可直接用于训练YOLOv5、YOLOv8等主流目标检测模型。图片经LabelImg逐一标注对应VOC(xml)、COCO(json)、YOLO(txt)三种格式标签按类别分目录存放能无缝接入常见检测训练流程。压缩包共2000个文件体积约892MB文件类型除以xml标注为主体外还有少量txt、py、html分别承担数据划分、训练集/验证集/测试集生成及环境搭建、案例教程说明等任务。附带Python划分脚本可按需拆分数据Windows/Linux双版本训练教程帮助读者替换成自己的数据集并完成训练。目前已有86人查看该资源适合需要真实工地场景数据做算法验证、课程设计或入门YOLO实战的开发者与学生。1. YOLO反光衣穿戴检测数据集为什么它是工地安全检测的入场券YOLO反光衣穿戴检测听起来是个特别细分的场景但真正在工地监控、高速养护、电力巡检这类项目里扎过的人都知道它是付费需求最稳定的目标检测任务之一。这个资源一次打包了 10000 张图片而且把 VOC、COCO、YOLO 三种常用格式的标签全部配齐同时还带了划分脚本和训练教程。它把数据清洗、格式转换、数据集划分这些最花时间的准备工作做成了完成态剩下需要你操心的是把自己的训练环境跑通。这份资源的定位很直接不是带你研究检测算法而是让你在最短时间内拿到一个可用的反光衣穿戴检测模型再去适配自己的业务。它适合刚接触目标检测的工程师也适合要在项目里交付这个能力的团队。2. 三种标签格式的本质VOC、COCO与YOLO的存储逻辑和框架适配很多新手拿到这份资源后的第一反应是直接跑训练脚本结果完全依赖默认的数据加载逻辑。等到想换框架时才发现VOC、COCO、YOLO 虽然描述的是同一批图片、同一批反光衣目标但坐标体系和文件组织方式完全不同。把这一点搞清楚数据才算是真正被用明白了。2.1 从标注文件看三种格式的结构区别VOC 格式的标注载体是 XML一张图片对应一个 XML 文件里面记录图片尺寸、文件名、目标名称和边界框坐标。annotation folderJPEGImages/folder filename000001.jpg/filename size width1920/width height1080/height depth3/depth /size object nameperson_with_vest/name bndbox xmin456/xmin ymin123/ymin xmax789/xmax ymax567/ymax /bndbox /object /annotation坐标是绝对像素值左上角和右下角各一对读起来很直观。它的优点在于便于人工检查和二次筛选缺点也很明显一万张图就有一万个 XML 文件文件数量庞大训练脚本启动时解析这些 XML 的 IO 开销不低。目前它在实际项目里更多是作为中间格式存在比如从旧标注平台导出后再转成其他格式。COCO 格式则把整个数据集的图片信息和标注信息收进一个 JSON 文件里结构上分 images、annotations、categories 三个主要块。{ images: [ {id: 1, file_name: 000001.jpg, width: 1920, height: 1080} ], annotations: [ { id: 1, image_id: 1, category_id: 1, bbox: [456, 123, 333, 444], area: 147852, iscrowd: 0 } ], categories: [ {id: 1, name: person_with_vest}, {id: 2, name: person_without_vest} ] }这里面有三个容易踩的细节。第一bbox 的四个数分别是左上角 x、左上角 y、目标宽度、目标高度不是右下角坐标。第二COCO 的 category_id 从 1 开始和 YOLO 文本格式里类别从 0 开始是两套规则。第三area 字段在后续用 cocoapi 做评估时会被用到如果转换时漏掉评测脚本可能在算 mAP 时直接把面积统计搞乱。YOLO 系列格式是目前 Ultralytics 生态最主流的格式每张图片对应一个 TXT 文件一行一个目标五列内容依次是类别 id、中心点 x、中心点 y、框宽、框高全部归一化到 0 到 1 区间。0 0.32421875 0.31944444 0.17343750 0.20555556 1 0.65104167 0.73148148 0.18281250 0.23888889归一化的意思是实际像素值除以图片总宽度或总高度。TXT 文件本身不记录图片尺寸因此它不能脱离图片单独被理解。图片一旦被 resize旧坐标就全部失效需要重新计算。这份资源已经把三种格式都转换好了本意就是让你在不同框架之间自由切换。但如果你以后遇到只有 VOC 标注的原始数据下面这段转换逻辑是通用参考。常见做法是用 Python 的 xml 库解析 XML再按 YOLO 的归一化公式换算。import xml.etree.ElementTree as ET xml_path Annotations/000001.xml img_width 1920 img_height 1080 tree ET.parse(xml_path) root tree.getroot() for obj in root.findall(object): name obj.find(name).text # 类别字符串要映射成数字 idYOLO 格式从 0 开始编号 class_id 0 if name person_with_vest else 1 box obj.find(bndbox) xmin int(box.find(xmin).text) ymin int(box.find(ymin).text) xmax int(box.find(xmax).text) ymax int(box.find(ymax).text) # 归一化时用 xml 里的原始图宽不要用 resize 后的尺寸 center_x (xmin xmax) / 2.0 / img_width center_y (ymin ymax) / 2.0 / img_height box_w (xmax - xmin) / img_width box_h (ymax - ymin) / img_height print(f{class_id} {center_x:.6f} {center_y:.6f} {box_w:.6f} {box_h:.6f})这段代码的关键不在 XML 解析本身而在于 img_width 和 img_height 必须来自 XML 里的原始图片尺寸。很多翻车都是因为在别处用了统一尺寸去归一化比如强制 640x640最后模型在边缘目标的框偏移明显。三种格式的差异可以用一张表快速对比。格式存储载体坐标表达典型消费框架VOCXML每图一文件左上角与右下角的绝对像素PyTorch 旧流程、自定义 pipelineCOCOJSON全数据集一处bbox 的 [x, y, width, height]Detectron2、MMDetectionYOLOTXT每图一文件归一化的中心点、宽高YOLOv5、YOLOv8、YOLOv11 等2.2 目录结构、文件对应与格式选择同一个数据集同时提供三种格式根本原因是框架生态各不相同。Ultralytics 的 YOLO 系列直接吃 TXTMMDetection 和 Detectron2 更适合 COCO JSON老项目里还有直接解析 VOC XML 的训练代码。保留多种格式背后是真实的工程约束而不是单纯的资料堆砌。这类资源常见的目录组织方式如下├── VOC │ ├── JPEGImages │ ├── Annotations │ └── ImageSets ├── COCO │ ├── images │ └── annotations └── YOLO ├── images │ ├── train │ ├── val │ └── test └── labels ├── train ├── val └── test我拿到这类资源后不会直接开训而是先做一次文件对应性检查。图片和标签只要有一方缺失后续的训练和评估就会埋雷。import os img_dir YOLO/images/train label_dir YOLO/labels/train imgs set(os.listdir(img_dir)) labels set(os.listdir(label_dir)) img_names {os.path.splitext(f)[0] for f in imgs} label_names {os.path.splitext(f)[0] for f in labels} print(缺少标签的图片数:, len(img_names - label_names)) print(缺少图片的标签数:, len(label_names - img_names))这段逻辑不难但价值很高。两个差值如果超过两位数就要回头确认压缩包是否完整或者划分脚本是否漏掉了某个目录。如果图片数量和标签数量对得上再进入下一步。选择哪种格式作为主力取决于你接下来用哪个训练框架。如果打算用 Ultralytics 的 YOLO直接在 YOLO 目录下工作尽量不要跨格式转换如果是为了在 MMDetection 里做对比实验那用 COCO 格式更省事。最常见的反面例子是有人在保持 YOLO 目录结构的情况下硬把标注文本改成 COCO JSON结果路径和框架全对不上最后花半天排查数据加载问题。3. 划分脚本与训练教程把 10000 张图变成可用权重的完整流程这份资源里自带的划分脚本做的事情就是把图片和对应标签按比例切成 train、val、test 三份。包作者的绝对路径和你本机不同所以脚本还是要自己确认之后再用。3.1 划分脚本的逻辑随机种子、比例与文件一致性我拿到的划分脚本核心逻辑大致是下面这样的import os import random from shutil import copy random.seed(42) # 固定随机种子保证每次划分结果一致 train_ratio 0.7 val_ratio 0.2 test_ratio 0.1 files [f for f in os.listdir(images) if f.endswith(.jpg)] random.shuffle(files) train_cnt int(len(files) * train_ratio) val_cnt int(len(files) * val_ratio) train_files files[:train_cnt] val_files files[train_cnt:train_cnt val_cnt] test_files files[train_cnt val_cnt:] # 只移动图片不够还要同步移动同名标签 for f in train_files: copy(os.path.join(images, f), YOLO/images/train/) copy(os.path.join(labels, f.replace(.jpg, .txt)), YOLO/labels/train/)这里三个关键点。第一random.seed(42) 不是可选项固定随机序列才能保证实验结果可复现否则每次划分后的验证集都不同朝阳模型的表现也没法对比。第二切分时同时复制图片和同名标签到目标目录而不只是生成一个列表文件这样训练脚本直接读目录更稳定。第三比例上 8:1:1 或 7:2:1 都常见test 比例低了最多是最终评估数字保守一点不会影响模型本身的可用性。特别提醒一下如果发现脚本只遍历了 images 目录而没有同步处理 labels 目录那这个脚本会把一半标签文件遗漏在原始目录训练时大量图片找不到标注。这个问题我在好几个数据集上都见过属于反复出现的经典坑。3.2 训练配置文件先确认类别再写 yaml到了训练环节第一件事是确定类别映射。很多人按数据集名字猜测类别数其实直接统计标签文件的第一列最准确。for file in YOLO/labels/train/*.txt; do awk {print $1} $file; done | sort | uniq -c这个输出会告诉你标签里实际出现了哪些类别 id以及每个类别的样本频率。比如输出0 4231和1 3811说明有两个类别且 0 和 1 都代表目标如果只有一种 id那就只配一个类别。注意YOLO 的类别 id 从 0 开始所以最大值加 1 就是 nc。统计完再写训练用的数据配置文件YOLOv8 风格如下path: /data/safety_vest train: images/train val: images/val test: images/test nc: 2 names: 0: person_with_vest 1: person_without_vestnames 列表的顺序就是类别 id 顺序yaml 里第一个名字对应标签中的 0不是 1。反光衣检测场景通常有两种标注策略一种直接把人分成穿戴和未穿戴两态另一种把反光衣和人分开检测变成三到四个类别。到底用哪种以你自己统计出来的标签为准不要猛抄网上的模板。3.3 训练命令与参数从 YOLOv5 到 YOLOv8数据集规模 10000 张类别只有两三个用 YOLOv8s 级别的模型足够了模型太大反而容易过拟合。常用训练命令如下yolo detect train \ modelyolov8s.pt \ datasafety_vest.yaml \ epochs50 \ imgsz640 \ batch16 \ device0几个参数逐个说。modelyolov8s.pt 是预训练权重路径YOLO 生态里做的迁移学习通常从这里开始比随机初始化收敛快得多。epochs50 对一万张量级的目标检测是中等迭代量先跑一个基线看到验证集 mAP 不涨再提前停。imgsz640 是标准训练分辨率如果反光衣目标在原图里占比特别小可以调到 768 或 960代价是显存占用明显上涨。batch16 对单卡 12GB 显存比较合适显存有富余就往上加爆显存就降到 8。device0 指定第一块 GPU如果机器上没有 GPU把 device 改成 cpu但训练速度会慢很多。如果你更习惯 YOLOv5命令对应是这样的python train.py --data safety_vest.yaml --weights yolov5s.pt --img 640 --batch 16 --epochs 50听到YOLO 预训练模型下载这个点很多人会担心权重文件哪里来。Ultralytics 的仓库会在第一次运行时自动拉取对应预训练权重本地如果已经有 .pt 文件直接放到项目根目录或者用 model/path/to/yolov8s.pt 显式指定就不会重复去下载。训练过程中重点看损失函数的变化。YOLOv8 输出里包含 box_loss 和 cls_loss反光衣这种目标检测任务cls_loss 能否下降直接反映了模型有没有学到正反例区分。如果 cls_loss 整个训练阶段不动先回数据环节查标签不要埋头调超参数。训练产物会落在 runs/detect/train 目录下里面有 best.pt 和 last.pt 两个权重。推理时优先用 best.pt它是验证集上 mAP 表现最好的节点last.pt 只适合继续断点续训。4. 避坑与常见问题五个训练前必须检查的细节这一章写的是我在类似数据集上真实踩过的坑每条都按现象、原因、解决来讲。这些细节在文档里经常被一笔带过但实际项目里每一条都能让你白耗半天。4.1 空标签文件让 Loss 震荡不降现象训练已经启动loss 值在降但降得很慢验证 mAP 一直起不来有时候 loss 曲线还会在中段出现周期性凸起。原因数据集里存在没有标注的图片对应标签文件是空的。这类图片以背景身份参与训练模型在空标签图上学不到正样本反向传播梯度被干扰。反光衣数据集里尤其容易出现误标漏标的情况因为远距离小目标的人工标注质量参差不齐。解决训练前用 find 命令把空文件全部扫出来。find YOLO/labels -name *.txt -size 0扫出来的空标签对应哪些图片逐一确认。如果是漏标补标注如果是纯背景图单独放到负样本目录不要直接混在训练集里裸奔。4.2 类别 ID 从 0 开始还是从 1 开始现象训练过程完全正常但推理时所有检测结果都被归到同一个类别或者直接抛一个 index out of range 的报错。原因写 VOC 转 YOLO 脚本时习惯性把类别从 1 开始编号。VOC 的 XML 对类别序号没有硬性规定YOLO 却规定类别号必须从 0 开始两者一错位整个标签文件全歪了。解决写完转换脚本后先跑一遍类别统计命令确认。for file in YOLO/labels/train/*.txt; do awk {print $1} $file; done | sort -n | uniq看输出里的最大类别编号如果是 1那就是两类如果是 2那就是三类。第一时间比对 yaml 里的 nc 和 names 是否和这个统计一致。4.3 归一化坐标与原始尺寸不一致现象训练能收敛但验证时边缘目标的框偏移严重反光衣穿在手臂上那种细长目标特别容易被框歪。原因转换标签时图片宽高读成了模型输入尺寸而不是原始尺寸。比如图片实际是 1920x1080脚本里却固定用 640x640 做分母归一化所有坐标都被压扁了。解决图片宽高必须来自 XML 的 size 标签或用 PIL 即时读取转换阶段绝不用固定尺寸。如果已经生成了 TXT随机挑一张图来比对中心点坐标和目标的实际位置肉眼抽查往往比自动化校验更快发现问题。4.4 划分时忽略类别均衡验证集挑食现象训练 loss 正常验证 mAP 却忽高忽低同一条训练记录里不同 epoch 的验证结果波动很大看起来像玄学问题。原因随机 shuffle 划分数据集时某一小类图片大量进入了 test 或 val验证集中该类样本数量太少评估结果被几张图主导。解决划分前先按类别分布做分层抽样。不追求严格的多数标签分层只要保证每个类别在 train、val、test 里的占比和整体接近即可。简单做法是用图片的主类别做分组再在每组内部随机切分工程上比纯 random.shuffle 稳得多。4.5 环境配置与预训练权重不匹配现象运行 train.py 时出现 shape mismatch或者某个 module 导入失败还有可能权重文件加载后完全卡住不动。原因PyTorch 版本与 ultralytics 包版本不兼容权重文件路径不对导致脚本反复尝试下载或者下载下来的文件版本和模型结构对不上。解决开一个干净 conda 环境固定 Python 版本安装稳定版 PyTorch 后再装对应版本的 ultralytics然后显式指定本地权重路径。conda create -n yolo python3.10 conda activate yolo pip install torch torchvision pip install ultralytics权重文件先手动放到固定目录训练时直接用绝对路径引用比如 model/path/weight/yolov8s.pt。这样即使工作目录变了权重路径依然明确也不会被自动下载覆盖。5. 验证与进阶用 mAP、混淆矩阵和真实场景判断模型可用很多人在训练结束后只看最终 mAP 数字但 mAP 回答不了反光衣检测最关键的问题有没有漏检。对安全场景来说漏掉一个穿反光衣不达标的人代价远大于误报一次。先用验证命令跑标准指标yolo detect val modelruns/detect/train/weights/best.pt datasafety_vest.yaml验证结束后产物里会有混淆矩阵。反光衣检测必须盯着混淆矩阵做决策FP 偏高时调高置信度阈值能压误报FN 偏高时要回训练数据里看是不是未穿戴样本太少或者远距离场景没覆盖。如果 FN 长期降不下来可以考虑把 imgsz 提到 768让远处的小目标获得更多有效像素。再拿一段训练中没出现过的现场视频推理比如工地实拍片段yolo detect predict modelruns/detect/train/weights/best.pt \ sourcesite_video.mp4 conf0.3 saveTrueconf0.3 的意思是置信度低于 0.3 的框全部舍弃。这个阈值不是拍脑袋定的它对应的是业务容忍度如果现场要求有事立即报误报可以接受就把 conf 设到 0.15 到 0.2如果要降低告警噪音设到 0.4 甚至 0.5。这个调整本质上是在混淆矩阵的 FN 和 FP 之间找平衡。从那以后我每次拿到这类数据集第一件事永远是跑一遍标签检查脚本确认空标签、类别数、图片与标注一一对应后再写 yaml。训练完成之后还会在完全不同的场景视频上跑一次推理毕竟有些模型在验证集上分数漂亮真实场景里却明显水土不服。这套流程我一直在用希望帮到你。本文还有配套的精品资源点击获取