☰
YOLO电动车违规检测数据集:从标注到训练全流程实战
2026/10/10 1:05:53 网站建设 项目流程

简介:这是一份面向计算机视觉与智能交通方向学习者的YOLO格式目标检测数据集,聚焦电动车、摩托车骑行中的违规行为识别,可用于训练和验证不戴头盔、使用手机等五类违规目标检测模型,适合课程设计、竞赛实战或算法改进实验。资源包共1883个文件,包含940张jpg图像、941个txt标注文件、1个可视化py脚本和1个png说明图,压缩包约56.63MB,按YOLOv5目录结构组织,训练集约700张、验证集约180张,可直接投入检测训练。配套的类别class文件明确了五类违规标签,可视化脚本无需修改即可随机读取图片并绘制边界框,方便快速检查标注质量。目前已有532人学习下载,结合作者提供的YOLOv5改进实战专栏,读者能获得从数据准备、标注核验到模型训练与改进的完整参考路径。

1. 电动车违规检测数据集:从标注到可视化,一份能直接开训的 YOLO 资源

做交通场景目标检测的同行大概率都遇到过这个尴尬:算法代码跑得通,公开数据集却对不上业务——COCO 里没「电动车违规载人」,BDD100K 里摩托车样本稀得可怜,自己从路口摄像头截帧标注,标到两千张就发现类别定义前后打架。这份 YOLO 电动车、摩托车违规目标图像检测数据集,解决的正是这个断层。它把划分好的训练/验证/测试集、类别 class 文件、数据可视化脚本打包在一起,拿到手不用再纠结目录结构怎么摆、类别 id 怎么对,直接进训练流程。适合做智慧交通、非机动车违规抓拍、边缘端部署的从业者,也适合刚入门 YOLO 想找一个真实业务数据集练手的人。下面按「资源是什么 → 怎么接进训练 → 坑在哪 → 怎么验证」的顺序拆开讲。

2. 数据集结构与 class 文件:先搞懂目录约定再动手

2.1 目录布局与划分逻辑

拿到一个目标检测数据集,第一件事不是急着写训练脚本,而是把目录结构摸清楚。这份资源常见做法是采用 YOLO 系列通用的 images/labels 平行目录,再按 train/val/test 三份切分。典型结构长这样:

dataset/ ├── images/ │ ├── train/ # 训练集图像 │ ├── val/ # 验证集图像 │ └── test/ # 测试集图像 ├── labels/ │ ├── train/ # 与 images/train 一一对应的 txt 标注 │ ├── val/ │ └── test/ ├── classes.txt # 类别名,一行一个 └── visualize.py # 数据可视化脚本

这里的关键约定是:images/train/xxx.jpg必须对应labels/train/xxx.txt,文件名(不含扩展名)严格一致。YOLO 训练时是按文件名去配对图像和标签的,一旦对不上,那张图就会被当成无目标背景图处理,训练日志里 loss 看着正常,实际模型学了个寂寞。划分比例上,交通违规这类场景我一般建议 train:val:test 按 7:2:1 或 8:1:1,验证集不能太小,否则 mAP 波动大到没法判断模型到底有没有进步。

2.2 class 文件与类别 id 映射

classes.txt是整份资源的「字典」,它决定了标注 txt 里每行第一个数字代表什么。YOLO 标注格式是每行class_id x_center y_center width height,后四个都是归一化到 0~1 的相对坐标。class_id 从 0 开始,顺序必须和 classes.txt 的行号严格对应。假设类别文件是这样:

electric_bike # id = 0 motorcycle # id = 1 rider_no_helmet # id = 2 overload # id = 3

那么标注文件里出现2 0.51 0.43 0.12 0.20,意思就是「未戴头盔的骑行者」这个类别,框中心在图像 51%、43% 位置,宽高占全图 12%、20%。很多人踩的坑是中途改了 classes.txt 的顺序却没重刷标签,结果模型把电动车学成了摩托车。改类别定义一定要同步检查所有 label 文件,或者干脆重新导出。

2.3 用可视化脚本先验数据

在写训练配置之前,强烈建议先跑一遍可视化脚本,把标注框画回图上肉眼过一遍。这是成本最低的质检手段。脚本核心逻辑无非是读图、读对应 txt、按归一化坐标还原像素框、画矩形和类别名:

import cv2 import os def visualize(img_path, label_path, classes, save_path): img = cv2.imread(img_path) h, w = img.shape[:2] if os.path.exists(label_path): with open(label_path) as f: for line in f: cid, xc, yc, bw, bh = map(float, line.split()) # 归一化坐标还原为像素坐标 x1 = int((xc - bw / 2) * w) y1 = int((yc - bh / 2) * h) x2 = int((xc + bw / 2) * w) y2 = int((yc + bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(img, classes[int(cid)], (x1, y1 - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) cv2.imwrite(save_path, img)

参数说明:xc/yc是框中心归一化坐标,bw/bh是归一化宽高,乘以图像宽高就还原成像素。跑完重点看三类问题——框有没有整体偏移(说明坐标归一化时用错了图尺寸)、有没有漏标(图上目标没框)、类别名有没有张冠李戴。这一步花十分钟,能省掉后面几小时排查「为什么模型不收敛」的时间。

3. 接进 YOLO 训练:data.yaml 配置与首轮跑通

3.1 写对 data.yaml

YOLO 训练入口是一个 yaml 配置文件,它把数据集路径、类别数、类别名串起来。这份资源接进 Ultralytics 系 YOLO(v5/v8/v11 都兼容这套结构)时,配置大概长这样:

path: /abs/path/to/dataset # 数据集根目录,建议写绝对路径 train: images/train val: images/val test: images/test nc: 4 # 类别数,必须和 classes.txt 行数一致 names: # 顺序必须和 classes.txt 完全一致 0: electric_bike 1: motorcycle 2: rider_no_helmet 3: overload

nc和names是最容易出错的两行。nc写错会导致训练时索引越界或静默丢类别;names顺序错了,推理结果里的类别名就全乱套。我一般会写个小脚本自动从 classes.txt 生成 names 段,避免手抄出错:

with open("classes.txt") as f: names = [l.strip() for l in f if l.strip()] print(f"nc: {len(names)}") print("names:") for i, n in enumerate(names): print(f" {i}: {n}")

3.2 首轮训练命令与关键参数

配置写好后,首轮训练不要一上来就堆 epoch,先用小轮次验证整条链路通不通:

yolo detect train \ data=data.yaml \ model=yolov8n.pt \ epochs=50 \ imgsz=640 \ batch=16 \ workers=4 \ project=runs/traffic \ name=baseline

参数逐个说:model选 nano 版是为了快速验证,链路通了再换 s/m/l;imgsz=640是交通场景的常用起点,小目标多可以提到 960 甚至 1280,但显存和速度要权衡;batch按显存调,爆显存就减半;workers是数据加载进程数,Windows 下设太高反而卡,Linux 上可以给到 8。首轮重点不是精度,而是看 loss 有没有正常下降、验证集有没有出 mAP、可视化预测框位置对不对。如果 loss 一直平着不动,八成是标签路径没对上或类别 id 越界。

3.3 训练日志里该盯什么

跑起来之后,日志里几个信号要盯紧。box_loss和cls_loss应该在前几个 epoch 明显下降,如果 cls_loss 居高不下,通常是类别不平衡或标注噪声大;验证集 mAP50 在 20 个 epoch 内应该有可见爬升,一直为 0 说明验证集标签没被读到。另外注意labels统计行,它会告诉你每张图平均多少个框、有没有大量背景图混进来。交通违规数据里「违规」样本天然少于「正常」样本,如果某类样本占比低于 5%,后面得考虑过采样或 focal loss 之类的补偿手段。

4. 避坑与排查:标注、坐标、类别那些翻车现场

4.1 现象:训练 loss 正常但 mAP 始终为 0

原因:验证集标签路径没配对,或者 data.yaml 里 val 指向了空目录。YOLO 对缺失标签是静默容忍的,不会报错,只会把图当背景。解决:跑一行脚本统计 val 目录下图像数和标签数是否一致,不一致就查文件名后缀(有的图是 .jpeg 标签是 .jpg 对应的 .txt,扩展名不匹配也会断链)。

4.2 现象:预测框整体偏移或大小不对

原因:标注时归一化用错了图像尺寸,比如用缩放后的图算坐标却按原图归一化。解决:用第 2 章的可视化脚本把框画回原图,偏移会立刻暴露。修复只能回到标注环节重刷,没有后悔药。

4.3 现象:类别名显示错乱,电动车被识别成摩托车

原因:classes.txt 顺序和训练时 names 顺序不一致,或者中途改过类别定义没重训。解决:固定一份 classes.txt 作为唯一真源,data.yaml 的 names 由脚本生成,禁止手改。

4.4 现象:显存溢出(CUDA out of memory)

原因:imgsz 或 batch 设太大,交通场景高分辨率图尤其吃显存。解决:先把 batch 降到 8 或 4,再考虑降 imgsz;也可以用梯度累积模拟大 batch。别硬扛,显存爆了训练直接中断。

4.5 现象:小目标(远处电动车)几乎检不出

原因:下采样后小目标特征丢失,640 分辨率对远处目标不够。解决:提高 imgsz 到 960/1280,或在模型里加 P2 小目标检测层。这是交通场景的常见硬骨头,不是调调学习率能解决的。

5. 进阶:用可视化脚本做预测结果复盘与数据迭代

训练完不是终点,真正拉开差距的是拿预测结果反哺数据。我习惯把可视化脚本改造成「预测框 + 真值框」叠加模式,一张图同时画两种颜色的框,一眼就能看出漏检和误检集中在哪。核心改动是在推理输出上再叠一层真值:

from ultralytics import YOLO import cv2 model = YOLO("runs/traffic/baseline/weights/best.pt") results = model.predict("dataset/images/val", conf=0.25, save=True) # 叠加真值框做对比:绿=预测,红=真值 for r in results: img = r.orig_img.copy() for box in r.boxes: x1, y1, x2, y2 = map(int, box.xyxy[0]) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) # 此处再读对应 label 文件画红框,逻辑同第 2 章 cv2.imwrite(f"compare/{r.path.split('/')[-1]}", img)

conf=0.25是复盘用的低阈值,目的是把「模型犹豫的框」也暴露出来,正式部署再调回 0.4~0.5。复盘时重点看三类:真值有框但预测没有(漏检,补样本)、预测有框但真值没有(误检,查标注或加负样本)、框位置偏差大(标注质量或 anchor 问题)。把漏检和误检的图挑出来,针对性补标几百张,往往比盲目加几千张随机图涨点更快。

验证环节我一般会固定一个 hold-out 测试集,每次迭代都跑同一份,记录 mAP50、mAP50-95 和各类别 AP。类别 AP 比总体 mAP 更有指导意义——如果「overload」这类 AP 一直垫底,说明这类样本要么太少要么太难,得单独处理。还有个血泪经验:数据集版本一定要打 tag,每次改类别或增删样本都记一笔,否则两周后你根本想不起来哪版对应哪个权重。从那以后我每次动数据集都强制走一遍「改类别 → 重生成 yaml → 跑可视化抽检 → 打版本号」的流程,再没出现过权重和数据对不上的玄学问题。希望这份资源和这套流程能帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询