news 2026/9/30 10:49:04

8511张YOLO格式DMS疲劳驾驶数据集:从拆包到YOLOv8训练全流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
8511张YOLO格式DMS疲劳驾驶数据集:从拆包到YOLOv8训练全流程

简介:本资源为面向疲劳驾驶检测(DMS)场景的YOLO系列目标检测数据集,适用于yolov5、yolov8、yolov9、yolov7、yolov10及yolo11等算法,可直接用于模型训练与验证测试。数据集共8511张图像并配有标签,覆盖未系安全带、唤醒、昏昏欲睡、系安全带、打电话、打哈欠等驾驶员状态类别,适合智能座舱安全监测方向的算法学习与项目实践。压缩包内共2000个文件,以xml标注文件为主,同时提供yolo格式txt与voc格式xml两套标签,分别存放于独立文件夹,并附带data.yaml配置文件,便于快速接入训练流程。目前已有393人学习下载。资源已完成训练集与验证集划分,标签坐标采用归一化格式,读者可直接复现检测流程、验证模型效果,并在此基础上开展类别扩展与调优实验。

1. 8511 张带标签的 DMS 疲劳驾驶数据集:从拿到压缩包到跑通第一轮训练

上周帮一个做车载 DMS 的团队看模型,他们卡在一个很实际的问题上:分类头能识别闭眼,但一遇到「手离开方向盘去拿手机」这种复合动作就崩。翻他们的训练集才发现,全是自己用手机拍的几百张摆拍图,类别只有睁眼闭眼两种。这类需求其实非常典型——疲劳驾驶检测从来不是单标签任务,打哈欠、打电话、没系安全带、昏昏欲睡、唤醒动作,这些状态在真实座舱里是并发出现的。这次拆的这个资源,就是一份 8511 张图像、带 YOLO 格式标签的 DMS 疲劳驾驶员数据集,覆盖没系安全带、唤醒、昏昏欲睡、安全带、电话、打哈欠这几类目标。它解决的不是「有没有数据集」的问题,而是「类别够不够贴近量产 DMS 场景」的问题。适合正在做 YOLOv8 目标识别、想快速验证座舱多状态检测方案的人,也适合拿它当标注格式和类别设计的参考样本。下面按我实际拆包的顺序讲,从目录结构一直讲到训练参数和踩坑。

2. 拆开压缩包先看什么:目录结构、标签格式与类别映射

拿到一个目标检测数据集,我第一件事不是急着写训练脚本,而是先把目录和标签翻一遍。这一步做扎实,后面能省掉大量「训练 loss 不降但不知道哪错了」的时间。这个包的结构是典型的 YOLO 检测数据集布局,图像和标签分离存放,标签是每张图一个 txt。

2.1 目录布局与文件命名规律

解压后大致是这样一个结构,不同人打包习惯略有差异,但核心就两块:images 和 labels。

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

先确认三件事:图像和标签是否同名(只差扩展名)、train/val 是否已经切好、有没有现成的 data.yaml。如果标签和图像不在对应目录,YOLOv8 会直接报「No labels found」,这是最常见的翻车点之一。命名上,图像是 jpg,标签是 txt,一一对应,这个规律必须严格保持,中间任何一张图缺标签,训练时都会被当成背景图处理,反而污染模型。

2.2 YOLO 标签格式逐字段拆解

YOLO 检测标签每行是一个目标,格式固定为五个字段:

class_id x_center y_center width height

举个实际例子,一行标签长这样:

2 0.4531 0.6120 0.0875 0.1930

含义是:类别索引 2,目标中心点横坐标占整图宽度的 45.31%,纵坐标占 61.20%,目标框宽占 8.75%,高占 19.30%。这里有个新手最容易搞错的点——后四个值全是归一化到 0~1 的相对值,不是像素。如果你拿标注工具导出的是像素坐标,直接喂进去,模型会学到一堆越界的框,训练 loss 会异常大甚至出 NaN。

字段含义取值范围常见错误
class_id类别索引,从 0 开始0 ~ N-1与 data.yaml 顺序不一致
x_center框中心 x,归一化0 ~ 1误填像素值
y_center框中心 y,归一化0 ~ 1误填像素值
width框宽,归一化0 ~ 1用绝对宽除以了错误基准
height框高,归一化0 ~ 1同上

2.3 类别映射与 data.yaml 的对应关系

这个数据集的核心价值在类别设计,它把 DMS 场景拆成了六类:没系安全带、唤醒、昏昏欲睡、安全带、电话、打哈欠。类别顺序必须和标签里的 class_id 严格对应,写错一位,模型就会把「打哈欠」学成「打电话」。data.yaml 一般长这样:

path: ./dataset train: images/train val: images/val names: 0: no_seatbelt 1: wake_up 2: drowsy 3: seatbelt 4: phone 5: yawn

注意 names 的键必须从 0 连续编号,中间不能跳号。我见过有人把「安全带」和「没系安全带」顺序写反,结果模型在验证集上指标虚高,一上车全错。改完 yaml 后,建议先跑一遍标签可视化再训练,这一步后面会讲。

3. 用 YOLOv8 跑通训练:环境、配置与关键参数

数据集看明白了,接下来就是让它真正跑起来。这一章按「环境准备 → 配置 → 启动训练 → 看结果」的顺序走,每一步都给可抄的命令和参数解释。YOLOv8 是目前这类 DMS 检测任务里上手最快、生态最全的选择,Ultralytics 的接口把训练流程压得很短,但参数设不对照样白跑。

3.1 环境准备与依赖安装

先建一个干净的虚拟环境,避免和系统里的老版本 torch 打架。CUDA 版本要和显卡驱动匹配,这个不匹配是训练起不来的头号原因。

conda create -n dms_yolo python=3.10 -y conda activate dms_yolo # 安装 pytorch,按自己 CUDA 版本选,这里以 cu118 为例 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 # 安装 ultralytics pip install ultralytics

装完先验证 GPU 是否可用,这一步别省:

import torch print(torch.cuda.is_available()) # 期望 True print(torch.cuda.get_device_name(0)) # 打印显卡型号

如果返回 False,先别怀疑代码,八成是 CUDA 版本和驱动对不上,或者装成了 CPU 版 torch。显存方面,8511 张图用 yolov8n 或 yolov8s 在 8G 显存上跑 batch=16 基本够用,想上 yolov8m 就得把 batch 降到 8 或开 AMP 混合精度。

3.2 训练脚本与参数逐项说明

Ultralytics 的训练入口非常简洁,但每个参数都影响结果。下面这份是我在这个数据集上常用的配置:

from ultralytics import YOLO # 加载预训练权重,从 COCO 迁移能明显加快收敛 model = YOLO("yolov8s.pt") results = model.train( data="dataset/data.yaml", # 指向你的 data.yaml epochs=100, # 轮数,小数据集 100 起步 imgsz=640, # 输入尺寸,DMS 场景 640 够用 batch=16, # 按显存调,爆显存就减半 device=0, # 用第 0 号 GPU workers=8, # 数据加载线程,Windows 下调小 patience=20, # 20 轮无提升就早停 lr0=0.01, # 初始学习率 lrf=0.01, # 最终学习率系数 augment=True, # 开启内置增强 cache=True, # 小数据集缓存到内存加速 project="runs/dms", # 结果保存目录 name="exp1" )

逐项说下为什么这么设。imgsz=640 是 YOLOv8 的默认训练尺寸,DMS 图像里目标(手、手机、安全带)尺度中等,640 能兼顾速度和精度,盲目上 1280 只会拖慢训练。batch=16 是显存和梯度的折中,太小梯度噪声大,太大泛化差。patience=20 是后悔药,防止过拟合后还傻跑。cache=True 对 8511 张这种规模很友好,第一次读盘后常驻内存,后续 epoch 速度能快一截,但内存小于 16G 的机器慎开。

3.3 训练过程监控与结果解读

训练启动后,终端会实时打印每个 epoch 的 box_loss、cls_loss、mAP50 等指标。重点盯两个:cls_loss 是否稳定下降,mAP50 是否在涨。如果 cls_loss 震荡剧烈,多半是学习率偏大或标签有脏数据;如果 mAP50 早早卡住不动,先怀疑类别不平衡。

训练结束后,结果都在 runs/dms/exp1 下,几个关键文件:

文件/目录内容用途
weights/best.pt验证集最优权重部署和推理用这个
weights/last.pt最后一轮权重断点续训用
results.csv每轮指标记录画曲线分析
confusion_matrix.png混淆矩阵看类别间误判
val_batch*.jpg验证集预测可视化肉眼检查漏检误检

混淆矩阵特别值得看。DMS 数据集里「昏昏欲睡」和「打哈欠」容易混,「安全带」和「没系安全带」也容易互相误判,因为两者视觉特征高度相似,只差一条带子。如果这两对在矩阵里交叉严重,说明特征区分度不够,要么加数据,要么在类别定义上再细化。

3.4 推理验证:拿一张图看真实效果

训练完别只看指标,一定要拿真实图跑一遍推理,指标好看但实际漏检的情况太常见了。

from ultralytics import YOLO model = YOLO("runs/dms/exp1/weights/best.pt") results = model.predict( source="test_images/", # 可以是单图、目录或视频 conf=0.25, # 置信度阈值 iou=0.45, # NMS 的 IoU 阈值 save=True, # 保存带框结果 device=0 )

conf=0.25 是默认值,DMS 场景如果漏检严重可以降到 0.15 试试,但会引入更多误检,需要权衡。iou=0.45 控制重叠框合并,同一目标被重复框出时调小这个值。推理结果图会存到 runs/detect/predict 下,逐张看,重点看小目标和遮挡目标——手部遮挡、夜间低照度是 DMS 的两大难点。

4. 避坑与排查:标签、显存、类别不平衡的五个真实翻车点

这一章是我和几个做 DMS 的同行踩过的坑汇总,每条都按「现象 → 原因 → 解决」写。数据集本身没问题,但用法不对,照样训不出能用的模型。

4.1 训练报 No labels found

现象:启动训练几秒后直接抛错,提示找不到标签文件。

原因:data.yaml 里的 train/val 路径写错,或者图像和标签没放在对应目录。YOLO 默认会在 images 同级找 labels,路径结构不对就找不到。

解决:确认 images/train 和 labels/train 是同级目录,且文件名一一对应。可以写个脚本快速核对:

import os img_dir = "dataset/images/train" lbl_dir = "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)

两边差集都为空才算干净。

4.2 训练中途 CUDA out of memory

现象:跑了几十个 epoch 突然爆显存,或者一开始就 OOM。

原因:batch 太大、imgsz 太高,或者 cache=True 把数据全塞进内存后显存被挤占。

解决:先把 batch 减半,再把 imgsz 从 640 降到 512 试。如果开了 cache,内存吃紧就关掉。另外 workers 设太大也会占资源,Windows 上建议设 0 或 2。

4.3 某几个类别 mAP 一直很低

现象:整体 mAP50 有 0.8,但「没系安全带」这类只有 0.4。

原因:类别样本数严重不平衡,或者该类目标太小、遮挡太多。DMS 里「没系安全带」往往只露出安全带一小段,特征弱。

解决:先统计各类别框数量,对少样本类做过采样或复制增强;也可以在训练时给类别加权,或者干脆把相似类合并再细分。统计脚本:

import os from collections import Counter lbl_dir = "dataset/labels/train" counter = Counter() for f in os.listdir(lbl_dir): with open(os.path.join(lbl_dir, f)) as fp: for line in fp: cls = int(line.split()[0]) counter[cls] += 1 print(sorted(counter.items()))

4.4 验证集指标虚高,实车全错

现象:val mAP 很漂亮,但拿真实座舱视频一测,漏检误检一堆。

原因:训练集和验证集来自同一批拍摄条件,分布太像,模型没学到泛化特征。或者标签里有系统性错误,比如把「打电话」标成了「唤醒」。

解决:手动抽 50 张验证集图,用可视化脚本把框画出来肉眼过一遍。分布上尽量让 train/val 覆盖不同光照、不同驾驶员。标签错误只能靠人工复核,没有捷径。

4.5 标签坐标越界导致 loss 异常

现象:训练 loss 一开始就是几百甚至 NaN。

原因:标签里有像素坐标没归一化,或者归一化时除错了基准(比如用宽除了高)。

解决:写个校验脚本,检查每行后四个值是否都在 0~1:

import os lbl_dir = "dataset/labels/train" bad = [] for f in os.listdir(lbl_dir): with open(os.path.join(lbl_dir, f)) as fp: for i, line in enumerate(fp): parts = line.split() vals = [float(v) for v in parts[1:]] if any(v < 0 or v > 1 for v in vals): bad.append((f, i, line.strip())) print("越界标签数:", len(bad)) for b in bad[:10]: print(b)

发现越界就回到标注工具重新导出,别想着在训练里硬扛。

5. 进阶技巧:标签可视化复核与迁移到自定义 DMS 场景

数据集跑通只是第一步,真正让它产生价值的是两件事:训练前把标签复核一遍,训练后把模型迁移到自己的场景。这一章讲我常用的两个具体技巧,都是能直接抄的。

5.1 训练前必做的标签可视化复核

我现在的习惯是,任何数据集进训练前,先随机抽 20 张把框画出来看。这一步能提前发现 80% 的标签问题。用 OpenCV 写个轻量脚本:

import cv2 import os import random img_dir = "dataset/images/train" lbl_dir = "dataset/labels/train" names = ["no_seatbelt", "wake_up", "drowsy", "seatbelt", "phone", "yawn"] colors = [(255,0,0),(0,255,0),(0,0,255),(255,255,0),(255,0,255),(0,255,255)] samples = random.sample(os.listdir(img_dir), 20) for f in samples: img = cv2.imread(os.path.join(img_dir, f)) h, w = img.shape[:2] lbl_path = os.path.join(lbl_dir, os.path.splitext(f)[0] + ".txt") if not os.path.exists(lbl_path): continue with open(lbl_path) as fp: for line in fp: c, x, y, bw, bh = line.split() c = int(c) x, y, bw, bh = float(x)*w, float(y)*h, float(bw)*w, float(bh)*h x1, y1 = int(x-bw/2), int(y-bh/2) x2, y2 = int(x+bw/2), int(y+bh/2) cv2.rectangle(img, (x1,y1), (x2,y2), colors[c], 2) cv2.putText(img, names[c], (x1, y1-5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, colors[c], 1) cv2.imwrite(f"check_{f}", img)

跑完打开 check_ 开头的图,重点看三样:框有没有偏、类别名对不对、有没有漏标的目标。漏标比错标更隐蔽,因为模型会把漏标目标当背景学,直接拉低召回。这个脚本我每次换数据集都跑,已经成了肌肉记忆。

5.2 迁移到自定义 DMS 场景的微调策略

如果你手上只有少量自己场景的图,别从零训,用这个数据集训出的权重做起点,冻结 backbone 先微调检测头:

from ultralytics import YOLO model = YOLO("runs/dms/exp1/weights/best.pt") model.train( data="my_dms/data.yaml", epochs=50, imgsz=640, batch=8, freeze=10, # 冻结前 10 层,只训检测头 lr0=0.001, # 微调学习率要小 project="runs/my_dms", name="finetune" )

freeze=10 冻结主干浅层,保留通用特征,只让检测头适配新类别。lr0 调到 0.001 是因为预训练权重已经很好,大学习率会把学到的特征冲掉。等检测头稳定后,再解冻全部层做一轮小学习率全量微调,通常能再涨几个点。这套流程我在几个座舱项目里反复用,比直接从头训省一半以上数据。

5.3 一个容易忽略的验证习惯

最后说个习惯。每次训完,我都会把 best.pt 在一段真实视频上跑一遍,而不是只看验证集图片。视频能暴露时序上的抖动——比如同一帧里「安全带」和「没系安全带」来回跳,这种闪烁在静态图上根本看不出来。跑视频的命令很简单:

yolo predict model=runs/dms/exp1/weights/best.pt source=test_video.mp4 conf=0.3 save=True

看完视频再决定要不要调 conf 或加时序后处理。从那以后我每次交付 DMS 模型前,都强制走一遍「标签可视化 + 视频推理」这两步,指标再好看也不跳过。希望帮到你。

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/30 10:47:14

Nginx性能优化全链路诊断与治理手册

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/30 10:45:15

新媒体多平台批量发布流程详解

一、流程概述当下新媒体运营已全面进入矩阵化时代&#xff0c;个人自媒体、小型运营团队及中小品牌企业&#xff0c;均会布局公众号、视频号、抖音、小红书、知乎等多渠道平台。多平台同步运营&#xff0c;能够打破单一流量局限&#xff0c;拓宽内容传播边界&#xff0c;精准触…

作者头像 李华
网站建设 2026/9/30 10:44:31

MiniCPM5 2B 开源 这次 2B 真挤进了 4B 赛道

仓库修复比单题编程麻烦得多。模型要读 issue 和报错日志&#xff0c;在目录里找到相关文件&#xff0c;理解函数之间的调用关系&#xff0c;写完补丁还要跑测试。任何一步偏离目标&#xff0c;后面的操作都会跟着出错。MiniCPM5-2B 在 SWE-bench Verified 上修复了 46.4% 的测…

作者头像 李华
网站建设 2026/9/30 10:43:41

昇腾910B上部署DeepSeek V3-R1:MindIE并行调参与显存优化实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/30 10:42:04

基于 Mosquitto 与 paho-mqtt 的 MQTT 客户端封装

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/30 10:41:26

服装店进入“AI 换挡期”:数字化不是加分项,而是生存题

服装实体零售正在经历一场静默的“换挡”&#xff1a;增长从“水涨船高”变成“贴身肉搏”&#xff0c;经营从“凭经验”变成“看数据”。国家统计局数据显示&#xff0c;2025 年全年服装、鞋帽、针纺织品类零售额 15215 亿元&#xff0c;同比仅增长 3.2%&#xff0c;低于同期社…

作者头像 李华