尧图精选

YOLO安全带检测数据集:8400张标注数据与训练实战指南

🕒 发布时间:2026/9/28 6:47:02 📁 来源:尧图网络
1. 为什么安全带检测值得单独做一个数据集1.1 从一张卡口图说起前阵子帮一个做智慧交通的朋友看他们新上线的高空瞭望抓拍系统后台一天能回传几十万张卡口图。他们最初的想法很朴素既然已经有人脸识别、车牌识别那顺手把驾驶员有没有系安全带也判了不就完了。结果真跑起来才发现这件事比想象中麻烦得多。车牌识别是结构化文本匹配人脸是特征比对而安全带检测本质上是小目标 遮挡 类内差异极大的视觉问题——安全带就是一条几厘米宽的深色带子压在深色衣服上还经常被方向盘、手臂、安全气囊盖板挡住一半。用通用检测模型直接跑漏检率高得离谱。这就是安全带检测数据集存在的意义。它不是随便凑几千张车拍图就完事而是要针对安全带这个特定目标把正负样本比例、遮挡形态、光照条件、车型分布这些维度都覆盖到。我手上这份数据集是 8400 张的规模全部按 YOLO 格式标注直接可以喂给 YOLOv5 / v8 / v11 甚至更新的版本训练。说白了它解决的就是我想做一个安全带识别功能但懒得从零标数据这个最现实的痛点。适合谁来用三类人最合适一是做智慧交通、卡口稽查类项目的算法工程师二是拿它当课程设计或毕设的学生三是想练手目标检测、找一个真实业务场景数据集的入门者。8400 张不算大但足够跑出一个能上线的 baseline也足够让你把 YOLO 的整套流程走一遍。1.2 8400 张这个量级意味着什么很多人一上来就问多少张才够。这个问题没有标准答案但可以给个经验区间。对于单类别、目标形态相对固定的检测任务YOLO 系列一般 3000 到 5000 张就能出一个可用的模型8000 张以上基本能覆盖大部分常见场景。安全带检测恰好属于单类别或双类别系了/没系的任务8400 张是一个相当舒服的规模——既不会小到欠拟合也不会大到让你在单卡上训练到怀疑人生。我实测过用 8400 张、640 分辨率、YOLOv8n 这种轻量模型单张 V100 大概 40 分钟能跑完 100 个 epoch收敛得很稳。如果换成 YOLOv8m 或者 v11m时间翻两三倍但 mAP 通常能再涨 2 到 4 个点。这个量级的好处就在于你有充足的余量去做消融实验、调超参、试不同的数据增强策略而不是每改一次都要等一整天。提示数据集规模不是越大越好关键是分布是否贴合你的实际业务场景。如果你只做白天高速卡口那 8400 张里如果混了大量夜间城区图反而会拉低你在目标场景上的表现。用之前先抽样看看分布。2. 数据集的结构与标注规范拆解2.1 YOLO 格式到底长什么样既然标题里明确写了 YOLO 格式这里必须把标注规范讲透因为80% 的训练翻车都出在标注格式上。YOLO 的标注是一图一 txt每张图对应一个同名 txt 文件txt 里每一行代表一个目标框格式是class_id x_center y_center width height注意后面四个值全部是归一化到 0 到 1 之间的浮点数不是像素坐标。这一点新手特别容易搞错直接把像素坐标写进去训练时 loss 直接爆炸或者模型完全不收敛。举个例子一张 1920×1080 的图某个安全带框的像素范围是 x 从 800 到 1000y 从 400 到 460那么x_center (8001000)/2 / 1920 900/1920 ≈ 0.4688y_center (400460)/2 / 1080 430/1080 ≈ 0.3981width (1000-800)/1920 200/1920 ≈ 0.1042height (460-400)/1080 60/1080 ≈ 0.0556所以这一行就是0 0.4688 0.3981 0.1042 0.0556。看着简单但实际标注时框的松紧程度直接影响模型学到的特征。安全带这种细长目标框如果画得太松把衣服、方向盘都框进去模型就会把无关纹理也当成判别依据。2.2 类别设计单类还是双类这是用这份数据集前必须想清楚的问题。常见有两种设计方案类别定义优点缺点单类方案只标安全带一个类标注简单正样本充足无法直接判断没系需要靠检测不到来推断误报高双类方案已系安全带 未系安全带可直接输出违规判断负样本标注难度大容易漏标我个人更推荐双类方案因为业务上你要的是这个人违规了这个结论而不是我检测到一条带子。如果只标安全带那驾驶员穿深色衣服、安全带被挡住时模型检测不到你根本分不清是没系还是系了但没看见。双类方案下未系安全带这个类会显式地学习胸前没有斜向带子这个特征鲁棒性高得多。不过双类方案对标注质量要求更高。我见过不少数据集未系类只标了驾驶员躯干区域框得特别随意导致模型学到的其实是方向盘区域而不是没系安全带。正确的做法是未系类的框应该覆盖驾驶员上半身胸前区域也就是安全带本该出现的位置这样两类框的空间分布才有可比性。2.3 目录结构建议拿到 8400 张图后别急着开训先把目录理清楚。我习惯用这套结构safety_belt_dataset/ ├── images/ │ ├── train/ # 约 5880 张 │ ├── val/ # 约 1680 张 │ └── test/ # 约 840 张 ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── data.yaml按 7:2:1 划分是常规操作。这里有个细节划分时要保证场景不泄漏。什么意思如果同一个卡口、同一辆车、甚至同一段连续视频抽帧出来的图被分到了 train 和 val 两边那 val 的指标会虚高因为模型见过几乎一样的图。正确做法是按卡口 ID 或视频片段整体划分而不是随机打散。这一点在智慧交通数据集上尤其重要因为很多数据是从视频抽帧来的相邻帧相似度极高。data.yaml 的内容大概是这样path: ./safety_belt_dataset train: images/train val: images/val test: images/test nc: 2 names: 0: belted 1: unbeltednc是类别数names的顺序必须和标注里的 class_id 严格对应。我踩过的坑就是改类别名时忘了同步改标注结果模型把已系和未系学反了上线后疯狂误报排查了半天才发现是 names 顺序写错了。3. 从零跑通训练环境、配置与实操3.1 环境搭建的取舍训练环境这块我给的建议是别一上来就折腾源码编译。如果你只是想快速验证数据集质量直接用 ultralytics 官方库最省事pip install ultralytics这一行装完YOLOv8、v11 都能直接调。想用更新的版本去官方仓库拉最新代码即可。显卡方面8400 张图用 8G 显存的卡比如 3060Ti、4060就能跑batch size 设 8 到 16分辨率 640。如果显存够V100 32G 这种batch 可以拉到 64训练速度提升明显。有个细节很多人忽略PyTorch 版本和 CUDA 版本的匹配。我见过太多训练中 BN 崩溃的案例最后查出来是 torch 和 cuda 版本不匹配导致的数值不稳定。稳妥起见用官方推荐的组合别自己乱配。装完后跑一句python -c import torch; print(torch.cuda.is_available())返回 True 才算环境通了。3.2 训练命令与关键参数一条最基础的训练命令长这样yolo detect train \ data./safety_belt_dataset/data.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ device0 \ projectruns/belt \ nameexp1这里每个参数都有讲究。modelyolov8n.pt是加载预训练权重强烈建议加载不要从零训。预训练模型在 COCO 上学到的边缘、纹理特征对安全带这种小目标帮助巨大收敛速度快一倍不止。imgsz640是输入分辨率安全带本身很小如果你显存允许可以试 960 甚至 1280小目标召回率会明显提升但速度会掉。epochs100不是死规定。判断该训多久看的是验证集 mAP 是否还在涨。我一般设 200 个 epoch 配 early stoppingpatience30让模型自己决定什么时候停。batch16是显存和稳定性的折中太小比如 2会导致 BN 统计不准太大又容易 OOM。3.3 数据增强策略怎么调YOLO 默认开了一堆增强但对安全带检测有些增强要慎用。默认的mosaic四图拼接对小目标有帮助但mixup可能把两张车的图叠在一起产生现实中不存在的幽灵安全带反而有害。我的经验配置是yolo detect train \ ... \ mosaic1.0 \ mixup0.0 \ hsv_h0.015 \ hsv_s0.7 \ hsv_v0.4 \ degrees0.0 \ translate0.1 \ scale0.5 \ fliplr0.5 \ flipud0.0解释几个关键项。hsv_h/s/v是色调、饱和度、明度扰动用来模拟不同光照和天气这个对卡口图特别有用白天黑夜、阴天晴天都得覆盖。degrees0.0是旋转角度我设成 0因为卡口相机基本是水平安装的旋转会引入不真实的姿态。fliplr0.5是水平翻转这个可以开因为左右舵车都存在翻转不会破坏语义。flipud0.0是垂直翻转绝对不要开倒过来的车在现实中不存在。注意数据增强不是越多越好。每加一种增强你都在假设这种变换后的图在现实中可能出现。如果假设错了模型就会学到错误的先验。安全带检测里旋转和垂直翻转基本是负收益。3.4 训练过程监控看什么训练跑起来后别只盯着 loss 看。真正该关注的是这几个指标box_loss定位损失下降说明框越来越准cls_loss分类损失下降说明系/没系分得越来越清mAP50IoU 阈值 0.5 下的平均精度这是最直观的指标mAP50-95更严格的指标反映框的精细程度precision / recall查准率和查全率业务上更关心哪个取决于你的场景我一般会在训练到 30、60、100 epoch 时各抽一次验证集结果看图。如果 mAP50 卡在某个值不动了先别急着加 epoch去看看是不是数据本身有问题——比如某类样本太少或者标注有系统性错误。混淆矩阵是个好东西能一眼看出模型把哪两类搞混了。不过要注意混淆矩阵的总和有时候对不上那是因为有些预测框 IoU 不够被算作背景了这是正常现象不用慌。4. 常见问题排查与避坑实录4.1 训练不收敛或 loss 变 NaN这是最高频的问题。按我的排查顺序先看三件事第一标注格式对不对。随便打开一个 txt确认坐标都在 0 到 1 之间且没有负数。如果发现坐标是几百上千的整数那就是没归一化赶紧写脚本批量转换。第二类别 id 有没有越界。data.yaml 里 nc2那标注里的 class_id 只能是 0 或 1。如果出现 2、3训练时就会报错或者静默出错。第三学习率是不是太大。默认 lr00.01 对大多数情况没问题但如果你改了 batch size 或者用了奇怪的优化器可能需要调小。我遇到过一次 loss 直接 NaN最后发现是某张图的标注框宽高为 0除零导致的。写个脚本扫一遍所有标注把宽高为 0 的行删掉就行。4.2 漏检严重尤其是夜间和遮挡场景漏检是安全带检测的头号敌人。如果验证集上 recall 很低先分类讨论夜间漏检多半是训练集夜间样本太少。解决办法是补充夜间数据或者在增强里加大hsv_v的扰动范围模拟低光照。遮挡漏检安全带被手臂挡住时模型确实很难。这时候可以尝试提高输入分辨率让被遮挡的部分保留更多细节或者用更强的 backbone比如从 n 换到 m/l。小目标漏检如果安全带在图中占比极小考虑用切片推理SAHI或者提高 imgsz。640 提到 1280小目标召回率通常能涨 5 到 10 个点。我实测过一个技巧在推理时降低置信度阈值。默认 conf0.25如果漏检多可以降到 0.1让模型多输出一些框再用 NMS 过滤。代价是误报会变多需要根据业务容忍度权衡。4.3 误报太多把没系的判成系了误报和漏检是一对矛盾。误报多的典型原因是负样本未系标注不规范。如果未系类的框画得太小或者位置飘忽模型就学不到稳定的特征。我的建议是重新审视负样本标注确保每个未系框都覆盖驾驶员胸前安全带本该出现的区域。另一个原因是正负样本比例失衡。如果 8400 张里 90% 都是已系模型会倾向于全判已系。解决办法是用copy_paste增强或者手动过采样未系样本。YOLO 本身没有内置的类别平衡机制得在数据层面解决。4.4 常见问题速查表现象可能原因排查方向解决手段loss 变 NaN标注坐标异常检查 txt 是否有 0 宽高、越界值清洗标注完全不收敛未加载预训练 / lr 过大确认 model 参数、看初始 loss加载预训练调小 lr夜间漏检夜间样本不足统计训练集光照分布补数据或加 HSV 增强误报高负样本标注差可视化负样本框重标负样本训练中 BN 崩溃torch/cuda 版本不匹配打印版本号重装匹配版本mAP 卡住不涨数据分布单一看混淆矩阵补充难例样本4.5 几个我踩过的坑第一个坑是用视频抽帧数据时没去重。相邻帧几乎一样导致 train 和 val 高度相似val mAP 虚高到 0.95一上真实场景就掉到 0.6。后来我按视频片段划分指标才真实。第二个坑是忽略了图像 EXIF 方向。有些手机拍的图带旋转信息用 OpenCV 读进来是正的但标注工具读进来是转过的导致框全错位。解决办法是统一用 PIL 读图并应用 EXIF 旋转或者干脆在预处理阶段把所有图转正。第三个坑是测试集当验证集用。调参时反复看 test 集指标等于把 test 集训进了模型选择过程最后报出来的数字没有意义。正确做法是 val 集调参test 集只在最后跑一次。5. 从数据集到落地部署与效果评估5.1 模型导出与推理加速训练完的 .pt 模型不能直接上生产得先导出。常见格式有 ONNX、TensorRT、OpenVINO选哪个取决于你的部署硬件。如果是 NVIDIA 显卡TensorRT 最快导出命令yolo export modelruns/belt/exp1/weights/best.pt formatengine halfTruehalfTrue是 FP16 量化速度能快将近一倍精度损失通常不到 1 个点。如果是边缘设备比如 RK3588 这类导出 ONNX 再用对应工具链转换。导出后一定要做精度对齐验证拿同一批图分别跑 .pt 和导出模型对比输出框的差异确认没有明显偏移。5.2 业务指标怎么定学术上看 mAP业务上看的是违规检出率和误报率。这两个指标要分开算违规检出率 正确检出的未系数 / 实际未系总数误报率 错误判为未系的数 / 判为未系的总数在卡口稽查场景误报率比检出率更敏感因为每一次误报都意味着一次无效的人工复核。我一般会把置信度阈值调高宁可漏一点也别误报太多。具体阈值多少得拿一批真实业务图跑一遍画个 PR 曲线找业务能接受的平衡点。5.3 持续迭代的思路8400 张训出来的模型上线后一定会遇到 bad case。正确的做法是建一个难例回流机制把线上误报、漏检的图自动存下来人工复核后加入训练集定期重训。这样模型会随着业务数据不断进化。我见过一个团队靠这套机制三个月把违规检出率从 78% 提到了 93%靠的就是持续喂真实难例。另外如果业务场景扩展了比如新增了副驾驶安全带检测别急着从零标数据可以先用现有模型跑一遍新场景图把高置信度的预测当伪标签人工只修正错的标注效率能提升好几倍。这就是所谓的半自动标注在智慧交通这种数据量大的场景里特别实用。最后分享一个我个人的小习惯每次重训前都把上一版的 bad case 单独存一个文件夹训完新模型后专门在这个文件夹上跑一遍看有没有改善。这比看整体 mAP 更能反映模型是不是真的进步了。毕竟整体指标涨 1 个点可能只是简单样本变好了而难例才是决定业务体验的关键。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →