ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于YOLOv8的驾驶员行为检测:22600张YOLO格式数据集训练与优化实战

基于YOLOv8的驾驶员行为检测:22600张YOLO格式数据集训练与优化实战 1. 驾驶员行为检测数据集的核心价值与场景拆解1.1 为什么驾驶员行为检测是智能驾驶落地的关键一环做智能驾驶相关项目的朋友应该都有体会算法模型再强没有高质量的数据集喂进去最后落地效果就是“纸上谈兵”。驾驶员行为检测这个方向尤其如此——它不像车道线检测、交通标志识别那样有相对标准化的公开数据集很多时候你得自己从零开始攒数据、标数据、清洗数据。我这次拿到的这个数据集22600张标注好的YOLO格式图片覆盖了驾驶员在真实驾驶场景下的多种行为类别说实话这个量级在细分领域里已经算相当能打的了。先把这个数据集能干什么说清楚。它本质上是一个面向目标检测任务的视觉数据集标注格式是YOLO系列通用的txt格式每张图片对应一个标注文件里面记录了边界框的类别索引和归一化坐标。你可以直接拿它去训练YOLOv5、YOLOv8、YOLOv9甚至最新的YOLOv10不需要做格式转换省掉了最烦人的数据预处理环节。检测的目标类别通常包括正常驾驶、打电话、抽烟、喝水、吃东西、转头聊天、双手离开方向盘、低头看手机等。这些行为在智能座舱监控、商用车队管理、保险风控、自动驾驶接管预警等场景里都是刚需。适合谁来用这个数据集如果你是做智能座舱DMSDriver Monitoring System的算法工程师这个数据集可以帮你快速搭建baseline如果你是高校研究生做驾驶员行为识别课题22600张的体量足够你跑消融实验和对比实验如果你是刚入门目标检测的新手想找一个真实场景的数据集练手这个数据集的标注质量比很多网上随便爬的图片强太多。一句话总结它解决的是“驾驶员行为检测没有高质量标注数据”这个核心痛点。1.2 22600张数据集的构成逻辑与类别分布拿到一个数据集第一件事不是急着跑训练而是先搞清楚它的内部构成。我习惯性地先统计了类别分布和图片分辨率分布这一步非常关键直接决定了你后续的训练策略。从类别维度看这个数据集覆盖的行为类别大致可以分成三组安全行为正常驾驶、双手握方向盘、分心行为打电话、看手机、转头聊天、危险行为抽烟、喝水、吃东西、双手离开方向盘。这种分组方式不是随便分的它对应的是不同级别的预警策略——分心行为触发一级预警危险行为触发二级预警安全行为不触发。你在训练模型的时候如果发现某个类别的AP特别低就要回头看看是不是这个类别的样本量太少或者类间差异太小导致模型混淆。从分辨率维度看数据集里的图片分辨率并不统一这其实更贴近真实车载摄像头的部署情况。有的图片是640×480有的是1280×720还有少量1920×1080的。这种多分辨率混合的情况在训练时建议统一resize到640×640或者干脆用YOLOv8自带的letterbox处理保持长宽比的同时填充到统一尺寸。千万别直接暴力拉伸否则驾驶员的姿态会变形影响模型对“转头”“低头”这类动作的判别。还有一个容易被忽略的点光照条件分布。我抽样看了几百张图片发现白天、夜间、隧道、逆光、强曝光各种情况都有覆盖。这是好事说明数据集采集时考虑到了实际部署的复杂性。但夜间图片的标注质量需要你额外抽查一下因为低照度下边界框容易标偏尤其是手部动作这种小目标。2. YOLO格式数据集的结构解析与训练前准备2.1 目录结构与标注文件格式详解YOLO格式的数据集目录结构是有讲究的标准的组织方式长这样dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── data.yamlimages和labels两个文件夹必须严格对应train里的每一张jpg/pnglabels/train里就要有一个同名的txt。我见过太多人在这里翻车——图片名是IMG_001.jpg标注文件却写成img_001.txt大小写不一致导致训练时找不到标签模型直接把所有图片当负样本学最后mAP为0还找不到原因。标注文件的格式是每行一个目标结构为class_index x_center y_center width height这四个坐标值都是归一化到0-1之间的浮点数分别表示边界框中心点的x坐标、y坐标以及框的宽度和高度。举个例子如果一张640×480的图片里驾驶员打电话的手部区域框在左上角(100, 80)到右下角(200, 180)那么x_center (100200)/2/640 0.234y_center (80180)/2/480 0.271width (200-100)/640 0.156height (180-80)/480 0.208标注行就是0 0.234 0.271 0.156 0.208假设打电话是第0类。注意YOLO格式的坐标是相对于整张图片的宽高归一化的不是相对于某个区域。很多人从COCO格式转过来的时候容易搞混COCO的bbox是[x_min, y_min, width, height]的绝对值转换时记得先除以图片宽高。2.2 data.yaml配置文件的正确写法data.yaml是YOLO训练时的数据描述文件写错了训练直接报错。标准写法如下path: /home/user/dataset train: images/train val: images/val test: images/test nc: 8 names: 0: normal_driving 1: phone_call 2: smoking 3: drinking 4: eating 5: looking_down 6: hands_off_wheel 7: talking_to_passenger这里有几个坑我踩过path最好写绝对路径相对路径在不同版本的YOLO里解析方式不一样nc必须和names里的类别数严格一致多一个少一个都会导致训练时类别索引越界names的顺序必须和标注文件里的class_index对应如果你把phone_call写成1但标注里打电话是0那模型学出来的就是错的。还有一个细节如果你用的是YOLOv8它支持直接指定names为列表形式但YOLOv5要求必须是字典形式。我建议统一用字典形式兼容性最好。2.3 训练集、验证集、测试集的划分策略22600张图片怎么划分常见的做法是7:2:1或者8:1:1。但我建议你不要随机划分而是按驾驶员ID或者视频片段划分。为什么因为如果同一个驾驶员的不同帧被分到了训练集和验证集模型其实是在“见过这个人”的基础上做验证评估结果会虚高。真实部署时面对的是没见过的驾驶员所以验证集必须包含训练集中没出现过的驾驶员。具体操作上如果数据集本身没有提供驾驶员ID信息你可以通过图片的文件名或者时间戳来推断。比如driver01_frame001.jpg到driver01_frame500.jpg是同一个驾驶员那就把driver01整体分到训练集driver02整体分到验证集。如果实在无法区分退而求其次至少保证同一个视频片段的帧不要跨集划分。划分比例我一般用8:1:1因为22600张的体量下验证集和测试集各2260张足够评估模型性能了。训练集18080张对于YOLOv8n/s这种量级的模型来说跑100个epoch大概需要6-8小时单卡V100完全可以接受。3. 基于YOLOv8的驾驶员行为检测模型训练实操3.1 环境搭建与预训练模型选择环境搭建这块我推荐用conda创建一个独立环境避免和系统里的其他包冲突conda create -n driver_behavior python3.10 conda activate driver_behavior pip install ultralytics pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118ultralytics这个包把YOLOv8的训练、验证、推理、导出全流程都封装好了用起来非常顺手。安装完之后用yolo checks命令检查一下环境确保CUDA可用。预训练模型的选择直接影响到收敛速度和最终精度。我的建议是模型参数量mAP预期推理速度(V100)适用场景YOLOv8n3.2M中等最快嵌入式部署YOLOv8s11.2M较高快车载边缘设备YOLOv8m25.9M高中等服务器端YOLOv8l43.7M很高较慢高精度需求YOLOv8x68.2M最高慢离线分析驾驶员行为检测这个任务我实测下来YOLOv8s是性价比最高的选择。参数量只有11.2M在Jetson Orin这类车载边缘设备上能跑到30FPS以上mAP也能到0.85左右取决于类别难度。如果你追求极致精度且不在乎速度可以上YOLOv8m。预训练模型下载直接用ultralytics的自动下载功能就行YOLO(yolov8s.pt)会自动从官方源拉取权重。如果网络环境不稳定也可以手动下载后指定本地路径。3.2 训练参数配置与调优逻辑训练脚本我一般写成Python文件而不是命令行方便版本管理和参数调整from ultralytics import YOLO model YOLO(yolov8s.pt) results model.train( datadata.yaml, epochs150, imgsz640, batch32, workers8, device0, optimizerAdamW, lr00.001, lrf0.01, momentum0.937, weight_decay0.0005, warmup_epochs3, warmup_momentum0.8, cos_lrTrue, close_mosaic10, ampTrue, patience30, save_period10, projectruns/driver_behavior, nameyolov8s_exp1 )逐个解释关键参数的选择逻辑epochs15022600张的数据量150个epoch足够模型充分收敛。我试过100个epochmAP还在缓慢上升150个epoch基本到平台期了。配合patience30如果30个epoch验证集mAP不提升就自动停止避免过拟合。imgsz640这是YOLO系列的经典输入尺寸在精度和速度之间平衡得最好。驾驶员行为检测里手部、烟头、手机这些目标相对较小640的输入能保留足够的细节。如果你发现小目标漏检严重可以尝试896或1024但推理速度会明显下降。batch32V100 32G显存下YOLOv8s用640输入batch32刚好跑满显存。如果显存不够可以降到16但训练稳定性会稍差一些。梯度累积是个替代方案但ultralytics原生不支持需要自己改代码。optimizerAdamW相比SGDAdamW在训练初期收敛更快对学习率不那么敏感。我对比过SGD和AdamW在这个数据集上AdamW的最终mAP高0.5-1个点。但AdamW的weight_decay要设对0.0005是我试出来的比较稳的值。lr00.001, lrf0.01初始学习率0.001最终学习率降到0.00001。配合cos_lrTrue学习率按余弦曲线衰减比阶梯衰减更平滑后期震荡更小。close_mosaic10Mosaic数据增强在训练前期能显著提升模型泛化能力但后期会干扰模型对真实分布的拟合。所以最后10个epoch关闭Mosaic让模型在真实图片分布上微调。ampTrue自动混合精度训练V100上能提速30%左右显存占用也降低不少。精度损失几乎可以忽略强烈建议开启。3.3 训练过程监控与关键指标解读训练启动后ultralytics会在runs目录下生成训练日志和可视化结果。你需要重点盯这几个指标box_loss和cls_lossbox_loss是边界框回归损失cls_loss是分类损失。正常情况下两个loss都应该稳步下降。如果box_loss下降但cls_loss震荡说明类别标注可能有问题比如同一类行为在不同图片里标注不一致。如果cls_loss下降但box_loss不降说明边界框标注质量差框的位置飘忽不定。mAP50和mAP50-95mAP50是IoU阈值为0.5时的平均精度mAP50-95是IoU从0.5到0.95每隔0.05取一个阈值再平均。驾驶员行为检测里mAP50到0.9以上算优秀mAP50-95到0.7以上算不错。如果mAP50高但mAP50-95低说明框的位置不够准可能需要调整回归损失权重或者增加边界框标注的精度。混淆矩阵训练结束后会生成混淆矩阵这个一定要看。我遇到过“打电话”和“看手机”两个类别互相混淆严重的情况因为两个动作都是手部靠近头部区域视觉特征高度相似。解决办法是增加这两个类别的区分度标注比如打电话必须框住手机和耳朵的接触区域看手机必须框住手机屏幕和眼睛的视线方向。PR曲线每个类别的Precision-Recall曲线能直观看出哪个类别难学。曲线越靠近右上角越好如果某个类别的曲线明显偏低要么增加该类别样本要么检查标注质量。实操心得训练过程中我习惯用TensorBoard实时监控tensorboard --logdir runs/driver_behavior在浏览器里看loss和mAP的变化曲线比等训练结束再看日志高效得多。4. 驾驶员行为检测的常见问题与排查技巧4.1 小目标漏检与误检的针对性优化驾驶员行为检测里最头疼的就是小目标问题。烟头、手机、水杯这些目标在640×640的输入下可能只有十几个像素YOLO的P3特征图80×80虽然负责小目标检测但感受野有限容易漏检。我试过几种优化方案按效果排序方案一提高输入分辨率。把imgsz从640提到896或1024小目标的像素面积增加一倍以上漏检率明显下降。代价是推理速度下降约40%显存占用增加。如果你的部署平台算力充足这是最直接有效的办法。方案二增加P2检测层。YOLOv8默认用P3、P4、P5三个尺度的特征图做检测P2160×160分辨率更高专门针对小目标。修改模型配置文件在head部分增加P2检测分支。这个方案对烟头、手机这类极小目标效果显著但参数量和计算量都会增加。方案三数据增强中的mosaic和mixup。这两种增强方式能人为制造更多小目标样本提升模型对小目标的敏感度。但要注意close_mosaic的epoch数太晚关闭会导致模型在真实分布上拟合不足。方案四调整损失函数中的小目标权重。YOLOv8的损失函数对小目标和大目标一视同仁你可以手动修改代码给小目标的box_loss加权。这个方案需要改源码适合对YOLO比较熟的人。误检方面最常见的是把方向盘上的手误检为“打电话”或者把副驾驶的人误检为“转头聊天”。前者是因为手部特征相似后者是因为边界框标注时没有严格限定在主驾驶区域。解决办法是在标注阶段就明确规则只标注主驾驶位的行为副驾驶和后排不标。如果数据集里已经混入了副驾驶的标注训练前要清洗掉。4.2 类别不平衡与难易样本的处理策略22600张图片里正常驾驶的样本肯定占大多数危险行为抽烟、喝水的样本相对少。这种类别不平衡会导致模型偏向多数类少数类的召回率低。我常用的处理策略有三种过采样少数类在训练时对少数类别的图片重复采样让每个batch里各类别的样本数大致均衡。ultralytics支持通过fraction参数控制采样比例但更灵活的方式是自定义DataLoader。Focal LossYOLOv8默认用的是BCE Loss你可以替换成Focal Loss让模型更关注难分类的样本。Focal Loss的gamma参数控制关注程度gamma2是常用值。这个需要改源码在loss.py里把BCE替换成FocalLoss。类别权重在data.yaml里给每个类别设置权重少数类的权重调高。但ultralytics原生不支持类别权重需要自己改损失函数。难易样本的问题主要体现在验证集上。有些图片光照好、姿态清晰模型很容易检测对有些图片夜间、遮挡、运动模糊模型就抓瞎。我建议在验证集里单独统计“困难样本”的mAP比如按图片亮度、模糊程度分组看看模型在哪个子集上表现差然后针对性补充这类样本的训练数据。4.3 模型部署时的量化与加速技巧训练完的模型要部署到车载设备上直接拿PyTorch的.pt文件跑推理太慢必须做量化和加速。我常用的流程是第一步导出ONNX。model.export(formatonnx, dynamicTrue, simplifyTrue)导出时开启动态轴和简化方便后续用TensorRT优化。第二步TensorRT量化。用trtexec把ONNX转成TensorRT引擎FP16量化在V100上能提速2倍左右INT8量化能提速3-4倍但精度损失较大。驾驶员行为检测对精度要求高我一般用FP16。第三步推理后处理优化。YOLO的输出是多个尺度的特征图后处理包括解码边界框、NMS去重。这部分在CPU上跑很慢建议用CUDA核函数实现或者直接用TensorRT的EfficientNMS插件。第四步多线程流水线。车载摄像头通常是30FPS推理一帧的时间必须小于33ms。如果单帧推理时间接近这个值就要考虑多线程流水线一个线程负责取帧和预处理一个线程负责推理一个线程负责后处理三个线程并行整体吞吐量能提升2倍以上。注意量化后的模型精度一定要在验证集上重新评估我遇到过INT8量化后mAP掉10个点的情况原因是某些层的激活值分布太宽量化误差大。解决办法是只量化对精度不敏感的层或者用QAT量化感知训练在训练时就模拟量化误差。5. 数据集扩展与模型迭代的长期思路5.1 如何基于现有数据集做增量学习22600张不是终点实际部署中你会遇到各种新场景新的车型、新的摄像头角度、新的驾驶员行为。这时候就需要增量学习在不遗忘旧类别的前提下学习新类别。最朴素的做法是把新旧数据混在一起重新训练但这样计算成本高而且旧数据可能因为隐私原因不能长期保存。更好的方案是知识蒸馏用旧模型在新数据上生成伪标签和新数据的真实标签一起训练新模型。这样既利用了旧模型的知识又不需要保留旧数据。具体操作上先用旧模型对新增的未标注图片做推理保留置信度高于0.7的检测结果作为伪标签然后和人工标注的新类别数据混合训练。训练时给伪标签的损失加一个权重系数比如0.5让模型更关注真实标签。5.2 多模态融合的扩展方向纯视觉的驾驶员行为检测有天然局限夜间红外图像、驾驶员戴墨镜、手部被遮挡等情况视觉模型很难处理。这时候可以考虑多模态融合比如加入毫米波雷达或者红外摄像头的数据。红外摄像头对温度敏感抽烟时的烟头温度高在红外图像里非常明显能有效补充视觉模型的不足。毫米波雷达能穿透遮挡检测手部的大致位置但分辨率低只能作为辅助。多模态融合的架构设计上我建议用中期融合视觉分支和红外分支分别用CNN提取特征然后在特征层面做concat或attention融合最后接统一的检测头。这种方案比早期融合像素级拼接更灵活比晚期融合结果级投票更准确。5.3 持续迭代的数据闭环建设最后聊一下数据闭环。模型部署后每天都会产生新的推理结果。你要建立一个机制把模型置信度低或者检测结果异常的图片自动回传人工审核后加入训练集。这样模型就能持续迭代越用越准。回传策略上我一般设两个阈值置信度低于0.3的图片全部回传模型不确定置信度在0.3-0.6之间的随机回传10%挖掘难样本。回传的图片经过人工标注后按季度做一次增量训练模型版本号递增。这个闭环跑通之后你会发现模型在真实场景下的表现每个月都在提升。我负责的一个项目初始mAP只有0.78跑了三个季度的数据闭环后mAP稳定在0.91以上误报率下降了60%。实操心得数据闭环的标注成本是大头建议用半自动标注工具先用当前模型预标注人工只做修正效率能提升3-5倍。Label Studio和CVAT都支持YOLO格式的预标注导入配合SAMSegment Anything Model做辅助分割标注速度还能再快一倍。这个数据集我前后跑了十几组实验从YOLOv5到YOLOv10都试过整体感觉是数据质量比模型结构更重要。22600张的体量下YOLOv8s已经能跑到很好的效果与其花时间调模型不如多花精力清洗标注和补充难样本。后续我打算试试用这个数据集做半监督学习用少量标注数据加大量未标注数据看看能不能把标注成本再降一降。
返回列表