☰
电动车摩托车违规检测数据集:YOLO训练与标注质检实战
2026/9/28 11:21:51 网站建设 项目流程

简介:本资源面向计算机视觉与目标检测方向的开发者、学生及算法工程师,提供一套可直接用于YOLO训练的电动车、摩托车违规行为图像数据集,聚焦不戴头盔、骑行中使用手机等常见违规场景,适合开展交通违规检测、安全监控等实战项目。压缩包共1883个文件,包含940张jpg图像、941个txt标注文件、1个可视化py脚本和1个png图片,整体约56.63MB,数据按YOLOv5目录结构组织,划分为约700张训练集与180张验证集,并附类别class文件,可直接接入检测流程。可视化脚本无需修改即可随机读取图片并绘制边界框,便于快速核验标注质量。目前已有531人学习下载,配套YOLOv5改进实战专栏,能帮助读者从数据准备到模型训练完整跑通违规目标检测任务。

1. 电动车摩托车违规检测数据集:从拿到压缩包到跑通第一轮训练

路口监控里电动车闯红灯、摩托车逆行、骑手不戴头盔,这些场景做算法落地时最头疼的往往不是模型结构,而是手里没有一份标注干净、类别明确、拿来就能喂给 YOLO 的数据。这份资源就是冲着这个痛点来的:它提供了一批电动车与摩托车违规目标的图像,已经按训练/验证/测试划分好,附带类别 class 文件和数据可视化脚本。适合正在做交通违规检测、智慧路口项目,或者想拿真实场景数据练手 YOLO 训练流程的从业者。你不需要自己从视频抽帧、标注、划分,解压后改几个路径就能进入训练环节。下面我按实际拆包顺序,把目录结构、类别定义、可视化校验、训练配置和几个容易翻车的地方讲清楚。

2. 拆开压缩包先看什么:目录结构、class 文件与划分逻辑

拿到一份目标检测数据集,我习惯先不急着写训练脚本,而是把目录结构和标注文件翻一遍。这一步花十分钟,能省掉后面几小时的报错排查。这份资源的组织方式比较标准,属于 YOLO 系列常见的 images/labels 平行目录结构,配合 data.yaml 描述类别和路径。

2.1 目录层级与文件对应关系

解压后典型结构大致是这样(不同版本可能略有差异,以实际为准):

dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ ├── classes.txt ├── data.yaml └── visualize.py

images 下每个子目录放 jpg/png 原图,labels 下同名 txt 放标注。YOLO 格式的标注是每行一个目标:class_id x_center y_center width height,后四个都是归一化到 0~1 的相对坐标。这里有个高频坑:图片和标注必须同名,只差扩展名。如果 images/train 里有001.jpg,labels/train 里就必须有001.txt,否则训练时这张图会被当成负样本或者直接报错跳过。

classes.txt 是纯文本,一行一个类别名,行号即 class_id。data.yaml 则是训练入口配置,通常长这样:

path: ./dataset train: images/train val: images/val test: images/test nc: 3 names: ['electric_bike_violation', 'motorcycle_violation', 'helmet_missing']

nc是类别数,names顺序必须和 classes.txt 完全一致。我见过有人改了 names 顺序但没改标注里的 class_id,结果模型把电动车识别成摩托车,mAP 看着还行但业务全错。改类别定义时,classes.txt、data.yaml 的 names、以及标注文件里的 id 三者要同步动。

2.2 划分比例与类别分布检查

资源已经划分好 train/val/test,省去了自己 split 的步骤。但划分好不代表分布合理。常见做法是训练前统计一下每个类别的实例数,看有没有严重长尾。可以用几行脚本快速过一遍:

import os from collections import Counter label_dir = 'dataset/labels/train' counter = Counter() for f in os.listdir(label_dir): if not f.endswith('.txt'): continue with open(os.path.join(label_dir, f)) as fp: for line in fp: cls_id = int(line.split()[0]) counter[cls_id] += 1 print('类别实例分布:', dict(sorted(counter.items())))

这段逻辑很直白:遍历训练集标注目录,读每行第一个字段作为类别 id 计数。跑完如果发现某个类别只有几十个实例,而另一个有几千个,那训练时小类别大概率学不好。解决办法不是硬训,而是先确认这个类别是不是真的这么少,或者考虑过采样、类别权重。参数上没什么可调的,重点看输出分布是否符合业务预期。

提示:统计时把 train/val/test 分别跑一遍,如果 val 里某个类别一个实例都没有,验证指标会失真,这种划分需要重新调整。

2.3 可视化脚本怎么用

资源带的数据可视化脚本是校验标注质量最直接的工具。它一般做两件事:把归一化坐标还原成像素坐标画框,以及在框上标类别名。核心逻辑大概是这样:

import cv2 import os def draw_boxes(img_path, label_path, classes, save_path): img = cv2.imread(img_path) h, w = img.shape[:2] 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)

关键点在坐标还原:YOLO 存的是中心点加宽高,画框要先算左上角和右下角。xc*w是中心 x 像素,减去bw*w/2才是左边界。如果画出来的框整体偏移或者大小不对,八成是这里算错了,或者图片在标注后被缩放裁剪过。跑几十张图肉眼扫一遍,重点看有没有框错位、漏标、类别标反的情况。这一步别省,标注脏数据是后面 mAP 上不去的头号元凶。

3. 把数据喂给 YOLO:环境、配置与训练命令

数据检查完,接下来是让它真正跑起来。这一章按环境准备、配置修改、启动训练、看结果四步走,每步都给可抄的命令和参数说明。不管你用的是 YOLOv5、v8 还是更新的版本,数据组织逻辑是通的,差异主要在训练命令和配置文件字段名上。

3.1 环境与依赖准备

先确认 Python 和 PyTorch 版本匹配。GPU 训练的话,CUDA 版本要和 PyTorch 对应,这个不匹配是最常见的「装完跑不起来」。常见做法是用 conda 建独立环境:

conda create -n yolo_ev python=3.10 -y conda activate yolo_ev pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install ultralytics opencv-python pyyaml

cu118对应 CUDA 11.8,如果你机器是别的版本,去 PyTorch 官网查对应命令。ultralytics 这个包覆盖了 YOLOv8 及之后的训练推理接口,装完yolo命令就能直接用。装完跑一句yolo checks看环境自检,它会告诉你 GPU 有没有被识别、版本对不对。如果显示 CPU only 而你有显卡,先查驱动和 CUDA,别急着改代码。

3.2 data.yaml 与训练参数配置

data.yaml 前面看过结构,这里补几个训练时真正影响结果的字段。以 YOLOv8 风格为例:

path: /abs/path/to/dataset train: images/train val: images/val test: images/test nc: 3 names: ['electric_bike_violation', 'motorcycle_violation', 'helmet_missing']

path建议写绝对路径,相对路径在不同工作目录下启动训练时容易找不到文件。nc和names长度必须一致,不一致直接报错。改完 yaml,启动训练:

yolo detect train \ data=dataset/data.yaml \ model=yolov8n.pt \ epochs=100 \ imgsz=640 \ batch=16 \ device=0 \ project=runs/ev_violation \ name=exp1

逐个说参数:model=yolov8n.pt是预训练权重,n 是最小号,显存紧张先用它;epochs=100是训练轮数,小数据集容易过拟合,可以配合早停;imgsz=640是输入尺寸,违规检测里小目标多的话可以提到 960,但显存和速度要权衡;batch=16按显存调,OOM 就减半;device=0指定第一块 GPU,CPU 训练写cpu。project和name决定结果保存路径,方便多次实验对比。

3.3 训练过程看什么指标

训练启动后终端会刷每个 epoch 的损失和指标。重点盯三个:box_loss定位损失、cls_loss分类损失、以及验证集上的mAP50和mAP50-95。前几十个 epoch 损失下降快是正常的,后面趋于平缓。如果cls_loss一直不降,多半是类别定义或标注有问题,回去查 class_id 有没有越界。如果训练集 mAP 很高但验证集很低,那是过拟合,加数据增强或者减模型容量。

训练完在runs/ev_violation/exp1/下会有weights/best.pt和last.pt,还有混淆矩阵、PR 曲线等图。混淆矩阵能直接看出哪个类别容易被混,比如电动车违规和摩托车违规如果互相混得多,说明这两类视觉特征太接近,要么合并类别,要么补充区分度高的样本。

3.4 推理验证与结果导出

拿 best.pt 跑几张测试图,确认模型真的能用:

yolo detect predict \ model=runs/ev_violation/exp1/weights/best.pt \ source=dataset/images/test \ conf=0.25 \ save=True

conf=0.25是置信度阈值,低于它的框不输出。违规检测场景里,漏检和误检的代价不同,如果业务更怕漏检就把阈值调低到 0.15 左右,宁可多报也别放过;如果误报会触发大量人工复核,就提到 0.4 以上。这个阈值没有标准答案,要拿一批真实场景图跑一遍,看误报漏报的平衡点在哪。结果默认存到runs/detect/predict,可以直接翻图核对。

4. 避坑与排查:标注、路径、显存、指标四类高频问题

这一章是我自己踩过和帮别人排查过的真实问题,按「现象 → 原因 → 解决」写。数据集类项目翻车大多不在模型,而在数据和环境这些看起来不起眼的地方。

4.1 训练报「No labels found」或大量图片被跳过

现象:启动训练后提示找不到标注,或者日志里 warning 说某些图片没有对应 label 被忽略。

原因:images 和 labels 目录层级不对应,或者图片和标注文件名不一致。YOLO 找标注是按路径替换images为labels再换扩展名,任何一环对不上就找不到。

解决:写个脚本核对两边文件名集合是否一致,把差集打出来。常见的是图片是.jpeg而标注按.jpg命名,或者有的图根本没标。差集里的图要么补标,要么从训练集移除。

4.2 画出来的框整体偏移或大小不对

现象:可视化脚本跑出来框的位置和实际目标对不上,整体偏一个方向或者框明显偏大偏小。

原因:坐标还原公式用错,或者图片在标注后被 resize 过但标注没同步更新。YOLO 归一化坐标是相对原图的,如果原图被裁过,坐标就失效了。

解决:先拿一张图手动算一遍中心点和宽高,和标注文件对比。确认公式是x1=(xc-bw/2)*w。如果公式没错,检查图片尺寸是否和标注时一致,不一致的图要重新标注或从数据集剔除。

4.3 训练中途 CUDA out of memory

现象:训练跑着跑着报显存不足,进程被杀。

原因:batch 太大、imgsz 太高,或者验证阶段同时占显存。小显存卡跑 640 加 batch16 很容易爆。

解决:先把 batch 减到 8 或 4,再把 imgsz 降到 512 试。还可以开混合精度amp=True(多数版本默认开),能省不少显存。如果还不行,换更小的模型,比如从 s 换到 n。别硬扛大 batch,训练稳定性比吞吐重要。

4.4 mAP 虚高但实际检测一塌糊涂

现象:验证集 mAP 看着不错,但拿真实场景图一跑,漏检误检严重。

原因:验证集和训练集分布太接近,甚至来自同一段视频的相邻帧,模型记住了背景而不是目标。或者类别定义太粗,把不同违规行为混成一类。

解决:验证集要尽量独立,最好来自不同路段、不同时段。类别定义按业务需求拆细,比如「不戴头盔」和「闯红灯」分开,别都塞进「违规」一类。另外看看混淆矩阵,如果某类 recall 很低,针对性补样本。

5. 进阶技巧:用可视化脚本反查标注质量与类别平衡

数据可视化脚本很多人只拿来画几张图看看,其实它能当标注质检工具用,而且比肉眼翻图高效得多。我的习惯是把它改造成批量统计加异常检测,一次跑完整个数据集,把可疑样本挑出来。

具体做法是在画框逻辑外面套一层统计:记录每张图的框数量、每个类别的实例数、框的宽高分布。框数量异常多(比如一张图几十个框)或者异常少(零框)的图单独列出来。宽高比特别极端的框也值得怀疑,比如宽高比超过 10:1 的,很可能是标注时拉歪了。下面这段在原来画框基础上加了统计和异常标记:

import os import cv2 import numpy as np def audit_dataset(img_dir, label_dir, classes, area_thresh=0.001): stats = {'total_imgs': 0, 'empty_labels': [], 'tiny_boxes': [], 'cls_count': {}} for f in os.listdir(label_dir): if not f.endswith('.txt'): continue stats['total_imgs'] += 1 label_path = os.path.join(label_dir, f) img_path = os.path.join(img_dir, f.replace('.txt', '.jpg')) with open(label_path) as fp: lines = [l for l in fp if l.strip()] if not lines: stats['empty_labels'].append(f) continue for line in lines: cid, xc, yc, bw, bh = map(float, line.split()) stats['cls_count'][int(cid)] = stats['cls_count'].get(int(cid), 0) + 1 if bw * bh < area_thresh: stats['tiny_boxes'].append((f, bw * bh)) return stats result = audit_dataset('dataset/images/train', 'dataset/labels/train', ['electric_bike_violation', 'motorcycle_violation', 'helmet_missing']) print('空标注文件:', result['empty_labels'][:10]) print('过小框数量:', len(result['tiny_boxes'])) print('类别分布:', result['cls_count'])

area_thresh=0.001是相对面积阈值,小于千分之一的框基本是误标或者目标太小不值得学。跑完看三个输出:空标注文件列表、过小框数量、类别分布。空标注要么补标要么删图;过小框考虑过滤;类别分布如果某类占比低于 5%,训练时要么过采样要么调类别权重。

这套质检流程我一般放在训练之前强制走一遍。有次偷懒没跑,训完发现验证集里混进了一批标注错位的图,mAP 卡在 0.4 上不去,回头查标注又花了大半天。从那以后我每次拿到新数据集,都先跑一遍统计加可视化,确认干净了再进训练。数据这关过了,模型调参才有意义。希望这份资源和这套流程能帮你少走点弯路。

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

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

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

立即咨询