☰
驾驶员行为检测数据集:22600张YOLO格式标注与训练全流程
2026/9/30 19:51:22 网站建设 项目流程

1. 驾驶员行为检测数据集到底解决什么问题

1.1 从一个真实需求说起

去年帮一个做商用车队管理的朋友看项目,他们想在驾驶舱里装一个摄像头,实时判断司机有没有分心——打电话、抽烟、喝水、扭头跟副驾聊天,甚至打哈欠犯困。听起来简单,但真正落地的时候卡在了第一步:模型训练需要大量标注好的驾驶员行为图片,而他们手里只有几段行车记录仪视频,连一张标注图都没有。

这就是驾驶员行为检测数据集存在的意义。我这次拿到的这份数据集,规模是22600张,采用YOLO格式标注,覆盖了智能驾驶场景下最常见的驾驶员行为类别。说白了,它就是一个"开箱即用"的训练素材库,你拿到手之后不需要从零开始标注,直接就能喂给YOLO系列模型跑训练。

很多人一听到"数据集"三个字就觉得没什么可讲的,无非是下载、解压、训练。但实际做过目标检测项目的人都知道,数据集的质量、标注规范、类别平衡度,直接决定了你后面模型能不能用。22600张这个量级,在驾驶员行为检测这个细分领域里算是相当扎实的规模了,既不会小到欠拟合,也不会大到普通显卡跑不动。

1.2 谁适合用这份数据集

我把适用人群分成三类,你可以对号入座。

第一类是做智能驾驶相关产品的算法工程师。你们公司可能在做DMS(Driver Monitoring System,驾驶员监控系统),需要快速验证一个行为检测的baseline,这份数据集能帮你省掉至少两周的标注时间。

第二类是高校做课题的研究生。驾驶员行为检测是个很好的论文选题,既有实际应用价值,又有足够的技术深度可以挖掘。22600张的规模足够你做出有说服力的实验结果。

第三类是想入门目标检测的开发者。如果你已经看完了YOLO的理论,但一直没找到合适的项目练手,驾驶员行为检测是个不错的切入点——类别清晰、场景固定、评价指标明确。

提示:这份数据集是YOLO格式,意味着标注文件是txt格式,每行是"类别id 中心x 中心y 宽 高"的归一化坐标。如果你用的是COCO格式的框架,需要先做格式转换。

1.3 数据集的核心规格拆解

在正式动手之前,我习惯先把数据集的规格摸清楚。下面这张表是我整理的关键信息,你可以对照自己的需求判断是否匹配。

规格项说明实际影响
图片总量22600张训练集/验证集按8:2划分后,训练集约18000张
标注格式YOLO txt格式可直接用于YOLOv5/v8/v11等系列
场景类型驾驶舱内视角光照变化、遮挡情况需要重点关注
行为类别分心驾驶相关行为类别数直接影响检测头设计
分辨率需实际检查影响训练时的imgsz参数设置

这里我要特别强调一点:拿到数据集的第一件事不是急着训练,而是做数据探查。我见过太多人直接开跑,结果训练到一半发现某几个类别样本极少,或者标注框严重越界,白白浪费了GPU时间。

2. 数据集结构与标注格式深度解析

2.1 目录结构应该长什么样

一份规范的YOLO数据集,目录结构通常是这样的:

driver_behavior_dataset/ ├── images/ │ ├── train/ │ │ ├── 000001.jpg │ │ └── ... │ └── val/ │ ├── 000001.jpg │ └── ... ├── labels/ │ ├── train/ │ │ ├── 000001.txt │ │ └── ... │ └── val/ │ ├── 000001.txt │ └── ... └── data.yaml

images和labels是两个平行目录,图片和标注文件通过文件名一一对应。这一点很关键,YOLO训练时是靠文件名去匹配的,如果000001.jpg对应的标注文件叫000001_1.txt,那这张图就会被当成无标注的负样本,白白浪费。

我实际拿到数据集后做的第一件事,是写个脚本检查图片和标注的配对情况:

import os img_dir = "driver_behavior_dataset/images/train" lbl_dir = "driver_behavior_dataset/labels/train" imgs = {os.path.splitext(f)[0] for f in os.listdir(img_dir)} lbls = {os.path.splitext(f)[0] for f in os.listdir(lbl_dir)} print("图片无标注:", imgs - lbls) print("标注无图片:", lbls - imgs) print("配对正常数量:", len(imgs & lbls))

跑完这个脚本,如果两个差集都是空的,说明数据组织没问题。如果有大量不匹配,那就要考虑是不是下载不完整或者解压出错了。

2.2 YOLO标注格式的细节

YOLO的标注文件每一行代表一个目标框,格式是:

<class_id> <x_center> <y_center> <width> <height>

其中后四个值都是相对于图片宽高的归一化值,范围在0到1之间。举个例子,如果一张1920x1080的图里有个框在左上角,坐标是(100, 50)到(400, 300),那么:

  • 中心点x = (100+400)/2 = 250,归一化后 250/1920 ≈ 0.1302
  • 中心点y = (50+300)/2 = 175,归一化后 175/1080 ≈ 0.1620
  • 宽 = 400-100 = 300,归一化后 300/1920 ≈ 0.1563
  • 高 = 300-50 = 250,归一化后 250/1080 ≈ 0.2315

所以这一行就是:0 0.1302 0.1620 0.1563 0.2315

我为什么要花篇幅讲这个?因为很多标注质量问题就藏在这些数字里。比如归一化值超过1,说明标注框超出了图片边界;比如宽高接近0,说明是个无效的极小框。这些脏数据如果不清理,训练时会出现loss异常甚至崩溃。

2.3 类别定义与data.yaml配置

data.yaml是YOLO训练的核心配置文件,它告诉模型去哪里找数据、有哪些类别。一份典型的配置如下:

path: ./driver_behavior_dataset train: images/train val: images/val nc: 6 names: 0: normal_driving 1: phone_call 2: smoking 3: drinking 4: distracted 5: drowsy

这里的nc是类别数量,names是类别名称映射。类别顺序必须和标注文件里的class_id严格对应,否则模型学出来的就是错的。我踩过一次坑:标注文件里0是打电话,但我配置里写成了0是正常驾驶,结果训练出来的模型把打电话识别成正常,整个项目返工。

注意:类别名称建议用英文,避免中文路径和编码问题。如果你需要中文显示,在推理后处理阶段做映射即可,不要写进yaml。

2.4 标注质量自查清单

在正式训练前,我强烈建议做一轮标注质量检查。下面是我常用的检查项:

检查项判断标准处理方式
坐标越界归一化值>1或<0裁剪到[0,1]或删除该框
极小框宽或高<0.01删除,通常是误标
类别越界class_id >= nc修正或删除
空标注文件txt内容为空作为负样本保留或删除
重复标注同一位置多个相同框去重

写个脚本批量扫一遍,比训练到一半发现问题要划算得多。我一般会把检查结果输出成CSV,方便逐条核对。

3. 从零跑通YOLO训练全流程

3.1 环境准备与依赖安装

训练环境我推荐用Python 3.8到3.10这个区间,太新的版本有时候会和某些库冲突。显卡方面,22600张图用8GB显存以上的卡比较稳妥,6GB也能跑但要调小batch size。

安装依赖的命令很直接:

pip install ultralytics pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118

ultralytics这个库把YOLOv8/v11的训练、验证、推理都封装好了,用起来比自己搭训练脚本省心得多。装完之后用下面这行验证一下:

import torch print(torch.cuda.is_available()) print(torch.cuda.get_device_name(0))

如果输出True和你的显卡型号,说明环境没问题。如果输出False,检查一下CUDA版本和torch版本是否匹配。

3.2 训练参数怎么定

训练参数不是拍脑袋定的,每个参数背后都有逻辑。我把关键参数列出来,逐个说明。

from ultralytics import YOLO model = YOLO("yolov8n.pt") results = model.train( data="data.yaml", epochs=100, imgsz=640, batch=16, lr0=0.01, lrf=0.01, patience=20, device=0, workers=8, project="driver_behavior", name="exp1" )

imgsz=640:这是输入图片的缩放尺寸。驾驶员行为检测的目标(手、脸、烟、手机)通常占画面比例不大,640是个平衡点。如果你的显存够,可以试到768或896,小目标检测效果会更好,但速度会下降。

batch=16:批大小。这个值受显存限制,8GB卡跑640尺寸大概能到16,如果爆显存就降到8。batch太小会导致BN层统计不稳定,loss震荡。

lr0=0.01:初始学习率。YOLOv8默认用SGD优化器,0.01是经过验证的稳妥值。如果你用Adam,要降到0.001量级。

patience=20:早停耐心值。连续20个epoch验证指标没提升就停止训练,防止过拟合。这个值设太小会提前终止,设太大浪费时间,20是个经验值。

epochs=100:训练轮数。22600张图,100轮通常能收敛。但这不是绝对的,要看loss曲线。如果100轮后验证mAP还在涨,可以继续加。

3.3 训练过程监控与关键指标解读

训练启动后,控制台会输出每个epoch的指标。你需要重点关注这几个:

  • box_loss:边界框回归损失,应该持续下降
  • cls_loss:分类损失,也应该下降
  • mAP50:IoU阈值为0.5时的平均精度,这是最直观的指标
  • mAP50-95:更严格的指标,综合了多个IoU阈值

我一般会盯着mAP50看,如果它在30轮之后还在稳步上升,说明模型还在学习;如果连续10轮不动甚至下降,就要考虑是不是过拟合或者学习率太大了。

训练完成后,runs/detect/driver_behavior/exp1/目录下会生成一堆文件,其中最重要的是:

  • weights/best.pt:验证集上表现最好的权重
  • weights/last.pt:最后一轮的权重
  • results.csv:所有epoch的指标记录
  • confusion_matrix.png:混淆矩阵,能看出哪些类别容易混淆

3.4 混淆矩阵暴露的问题

混淆矩阵是我最喜欢看的图。它能直观告诉你模型把哪些类别搞混了。比如在驾驶员行为检测里,"喝水"和"打电话"经常混淆,因为两个动作都涉及手举到脸部附近。如果混淆矩阵显示这两个类别互相误判严重,说明特征区分度不够,可以考虑:

  1. 增加这两个类别的样本量
  2. 在数据增强时针对性地做遮挡、旋转
  3. 换更大的模型(从yolov8n换到yolov8s或m)

我实测下来,yolov8n在22600张图上训练,mAP50大概能到0.85左右;换成yolov8s能提升到0.89,但推理速度会慢一些。具体选哪个,看你的部署场景对速度的要求。

4. 数据增强与类别不平衡处理

4.1 为什么数据增强在驾驶场景特别重要

驾驶舱内的光照条件变化极大——白天强光、夜间暗光、隧道明暗交替、逆光。如果训练集里大部分是白天正常光照的图,模型到了夜间就抓瞎。数据增强就是用来"伪造"这些变化的。

YOLO内置了多种增强策略,在训练配置里可以调:

model.train( ..., hsv_h=0.015, hsv_s=0.7, hsv_v=0.4, degrees=10, translate=0.1, scale=0.5, fliplr=0.5, mosaic=1.0, mixup=0.1 )

hsv_h/s/v:色调、饱和度、明度扰动。这三个参数模拟不同光照条件,v调到0.4能明显提升暗光鲁棒性。

degrees=10:随机旋转角度。驾驶员头部倾斜是常见情况,适度旋转有帮助。但不要调太大,否则会出现不合理的姿态。

mosaic=1.0:马赛克增强,把4张图拼成1张。这是YOLO的招牌增强,能显著提升小目标检测能力,建议保持开启。

mixup=0.1:图像混合。适度使用能提升泛化,但太高会让训练变慢。

提示:数据增强不是越多越好。我试过把所有增强拉满,结果模型在验证集上表现反而下降,因为增强后的图像分布偏离了真实场景。建议先用默认值跑一版,再针对性调整。

4.2 类别不平衡的识别与应对

驾驶员行为检测数据集有个天然问题:正常驾驶的样本远多于异常行为。因为现实中司机大部分时间都在正常开车,分心行为是少数。这会导致模型偏向预测"正常",对异常行为的召回率低。

先统计一下各类别样本数:

import os from collections import Counter lbl_dir = "driver_behavior_dataset/labels/train" counter = Counter() for f in os.listdir(lbl_dir): with open(os.path.join(lbl_dir, f)) as file: for line in file: cls_id = int(line.split()[0]) counter[cls_id] += 1 for cls_id, count in sorted(counter.items()): print(f"类别 {cls_id}: {count} 个框")

如果发现某个类别只有几百个框,而最多的类别有几万个,那就是典型的不平衡。应对手段有几个:

过采样:把稀有类别的图片复制多份参与训练。简单粗暴但有效,缺点是容易过拟合。

类别权重:在损失函数里给稀有类别更高权重。YOLO本身不直接支持,需要改源码。

focal loss:降低易分类样本的权重,让模型聚焦难样本。这是处理不平衡的经典方法。

数据合成:把稀有行为的标注框抠出来,贴到其他背景上。这个工作量大,但效果最好。

我一般先用过采样快速验证,如果效果不够再考虑更复杂的方法。

4.3 针对驾驶场景的定制增强

通用的数据增强之外,我还加了几个针对驾驶场景的定制增强:

随机遮挡:模拟方向盘、手部对脸部的遮挡。可以用Cutout或者Random Erasing实现。

亮度突变:模拟进出隧道的瞬间。在HSV空间做非线性亮度变换。

运动模糊:车辆颠簸导致的画面模糊。用cv2的滤波函数模拟。

这些增强能让模型更适应真实车载环境的复杂性。我做过对比实验,加了定制增强后,模型在夜间和颠簸场景下的检测率提升了约8个百分点。

5. 模型评估、部署与常见问题排查

5.1 评估指标不能只看mAP

mAP是综合指标,但实际部署时你更关心的是具体类别的召回率和精确率。比如"打电话"这个行为,漏检(召回率低)比误检(精确率低)更危险,因为漏检意味着系统没发现司机在分心。

用YOLO的val模式可以输出每个类别的详细指标:

model = YOLO("runs/detect/driver_behavior/exp1/weights/best.pt") metrics = model.val(data="data.yaml") print(metrics.box.map) print(metrics.box.map50) print(metrics.box.maps) # 每个类别的mAP

metrics.box.maps会返回一个列表,对应每个类别的mAP。如果某个类别明显偏低,就要针对性优化。

5.2 推理部署的几种方式

训练好的模型要落地,有几种常见方式:

Python脚本推理:最简单,适合验证和测试。

results = model("test.jpg") results[0].show()

ONNX导出:跨平台部署的标准格式,能在多种推理引擎上跑。

model.export(format="onnx", imgsz=640, dynamic=True)

TensorRT加速:如果部署在NVIDIA设备上,用TensorRT能获得数倍加速。

model.export(format="engine", imgsz=640, half=True)

half=True表示用FP16精度,速度更快,精度损失很小。我实测在同等硬件上,TensorRT比原生PyTorch推理快3到5倍。

5.3 常见问题速查表

下面这张表是我在实际项目中踩过的坑和解决方案,你可以直接对照排查。

问题现象可能原因解决方案
loss变成nan学习率太大或标注有越界值降lr,检查标注归一化值
mAP一直不涨学习率太小或数据增强过强调大lr,减弱增强
显存溢出batch或imgsz太大降batch到8,imgsz到512
某类别检测极差样本太少或标注质量差过采样,人工复核标注
推理速度慢模型太大或没用加速换小模型,导出TensorRT
夜间检测失效训练集缺暗光样本加亮度增强,补暗光数据
混淆矩阵对角线不清晰类别特征区分度低换大模型,增加区分性特征

5.4 几个容易被忽略的实操心得

第一,验证集要能代表真实场景。如果你的验证集全是白天图,那评估出来的指标是虚高的。我建议验证集里白天、夜间、逆光各占一定比例,这样指标才有参考价值。

第二,训练日志要保存。results.csv里记录了每个epoch的所有指标,训练完拿它画曲线图,能看出很多问题。比如loss曲线震荡说明batch太小,验证loss上升说明过拟合。

第三,不要迷信大模型。yolov8n在22600张图上已经能跑出不错的效果,如果你的部署设备算力有限,小模型反而是更务实的选择。我见过有人非要用yolov8x,结果推理一帧要200ms,根本没法实时。

第四,定期保存中间权重。训练过程中如果发现某个epoch的指标特别好,但后面又下降了,你可以回退到那个权重。YOLO默认只保存best和last,我建议加个save_period=10,每10轮存一次。

第五,测试时用真实视频。单张图片的指标再好,也不代表视频流上表现好。因为视频有帧间连续性,可以用跟踪算法平滑检测结果,减少闪烁。我一般会用几段真实行车视频做端到端测试,看实际体验。

5.5 从数据集到产品的最后一公里

数据集和训练只是第一步,真正落地还要考虑很多工程问题。比如模型量化——把FP32转成INT8,模型体积缩小4倍,速度提升2到3倍,精度损失通常在1%以内。再比如多线程推理——视频流是连续的,要用队列做缓冲,避免丢帧。

还有一个容易被忽略的点:误报的处理。驾驶员行为检测系统如果频繁误报,司机很快就会关掉它。所以实际部署时,我一般会加一个时间窗口平滑——连续N帧都检测到同一行为才触发告警,单帧的偶发误检直接过滤掉。这个N值需要根据帧率和实际体验调,通常取5到10帧比较合适。

我在实际项目里的体会是,数据集质量决定了模型的上限,而工程细节决定了产品的下限。22600张的驾驶员行为检测数据集给了你一个不错的起点,但能不能做出真正好用的系统,还得看你在数据清洗、增强策略、部署优化这些环节上花了多少心思。踩过的坑多了,自然就知道哪里该留个心眼。

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

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

立即咨询