ARTICLE DETAIL

资讯详情

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

YOLO车辆行人四类别数据集构建与训练实战指南

YOLO车辆行人四类别数据集构建与训练实战指南 简介目标检测是计算机视觉领域的核心任务之一在交通监控、辅助驾驶和安防系统中应用广泛。而数据集的构建与质量把控往往决定了模型性能的上限。本文从数据集设计出发详细讲解行人、轿车、公交车与货车四类目标的定义逻辑以及图片采集、清洗、标注与格式转换的完整流程。在此基础上围绕YOLOv5/YOLOv8等主流检测框架介绍数据增强策略、训练参数调优、评估指标解读与小目标漏检、类别混淆等工程实践问题的解决方案。无论是算法选型还是训练流程优化这套方法都能帮助开发者快速构建可落地的车辆行人检测系统并有效迁移至不同业务场景。 做目标检测这几年有个问题我一直反复强调算法选型重要但决定项目上限的往往是数据集本身。前段时间我整理了一套 YOLO 车辆行人四类别识别数据集从采集、标注、清洗到训练调参完整跑通了一遍踩了不少坑也沉淀了一套可以直接复用的流程。这篇文章就把整个项目的思路、细节和实操过程梳理一遍给正在做交通场景检测、辅助驾驶识别或者安防监控的朋友一个参考。先说清楚这套数据集解决什么问题。它的核心任务是识别交通场景中的四类目标行人和三类常见车辆。拿到这套数据你可以直接用它训练 YOLOv5、YOLOv8 甚至 YOLOv9也可以作为预训练基础迁移到自己的业务场景做微调。整个过程从数据组织、标注格式转换、模型训练、指标评估到问题排查每个环节我都会讲到尽量做到拿来就能用。1. 项目核心思路为什么做四类别车辆行人数据集1.1 四类别如何定义最合理做目标检测数据集第一件事不是急着找图而是想清楚一个核心问题你要检测的类别边界到底怎么划。这套项目的类别划分是“行人 三类车辆”即行人、轿车、公交车和货车。四类目标看起来简单但设计背后其实有很强的业务考量。为什么不直接把所有车归为一类在真实场景里不同车型的车身尺寸、外形轮廓、长宽比差异很大。轿车长宽比接近 2:1公交车接近 4:1货车又带着高高的货箱。如果全部标成一个大类“车辆”模型在特征提取时会被迫在“轿车的流线造型”和“货车的方正货箱”之间找一个折中结果往往适得其反。反之把车型单独拆开每个类别的样本内部一致性更高特征收敛更快检测精度也会更高。为什么不加太多类别从四类变成八类、十类表面上看起来功能更全但数据标注成本会成倍上升。实际统计一下在同样规模的训练集下类别越多每个类别的平均样本数就越少模型越容易过拟合。尤其是摩托车、三轮车这类细分类别样本本身就少硬加进来只会拉低整体精度。先保证四类的识别高准确率再按需扩展才是务实的思路。1.2 为什么选 YOLO 系列做检测框架这套数据集在设计阶段就明确要适配 YOLO 系列原因很简单实时性要求高。车辆行人识别大多用在视频流场景中比如路口监控、路段车流统计需要每秒处理几十帧。YOLO 单阶段检测天然适合这种场景。工程生态成熟。YOLO 系列从 v5 到 v8训练、导出、部署链路非常完善有官方预训练权重社区资料也很多遇到问题容易找到解决方案。泛化能力经过大规模验证。YOLO 在 COCO、VOC 等通用数据集上表现稳定对中小目标有专门优化。交通场景里行人、远处车辆都属于中小目标YOLO 的多尺度检测头能较好覆盖。当然也不是说 YOLO 就完美。在两阶段检测器如 Faster R-CNN面前YOLO 对极小目标和小目标重叠场景的精度会稍逊一筹。但考虑到数据集的定位是工程落地而非刷榜实时性和易用性优先YOLO 是最合适的选项。提示如果你的场景有大量密集小目标需求建议在这套数据集基础上结合 SAHI 切片推理或添加 P2 检测层能明显改善漏检问题。后文会讲到具体的做法。2. 数据集准备从原始图片到训练集的打磨2.1 数据采集的来源与筛选标准数据采集是这套项目里最耗时间的环节。我的原则是宁缺毋滥一张模糊图可能比一张清晰图带来的负面影响更大。采集来源主要有三个公开数据集筛选。从市面公开的数据集中筛选交通场景图片注意筛选时要去掉低分辨率、严重遮挡、目标占比过小的图片。自采路口视频帧。在合法合规前提下用固定机位录制城区路口、快速路和国道路段的视频按固定间隔抽帧。抽帧间隔建议 3 到 5 秒一帧避免相邻帧目标位置几乎一样导致数据冗余。模拟场景补充。针对夜间和雨天样本不足的情况用游戏引擎渲染或合成数据补充一部分场景图虽然风格与真实图片有差异但对提升模型的鲁棒性有实际帮助。筛选时建议用一个简单的脚本批量统计图片尺寸和目标个数剔除不合格样本。数据清洗阶段可以遵循几个硬性标准筛选维度建议标准原因分辨率不低于 640x480低于这个分辨率小目标基本无法标注目标最小尺寸目标短边不小于 20 像素太小目标标注噪声大训练时容易学偏遮挡程度目标遮挡面积不超过 60%过度遮挡的目标标注边界不确定干扰训练模糊程度肉眼可清晰辨认目标轮廓运动模糊会让特征严重失真2.2 标注细节与格式转换标注环节我用的工具是 LabelImg 和 X-AnyLabeling。LabelImg 适合快速上手X-AnyLabeling 支持自动标注辅助能节省不少人工工作量。这里提一个很多人忽略的细节标注框的贴合程度。标注框不是框住就完事而是要尽量贴合目标外轮廓尤其是行人和非机动车这类轮廓不规则的目标。框太紧会把身体的一部分切出去框太松会把背景背景带进来这两种都会给模型训练带来干扰。我的做法是行人目标保留 1 到 2 像素的边距车辆目标保留 2 到 3 像素边距。关于标注格式分类讨论一下LabelImg 默认输出 PASCAL VOC 格式XML 文件包含目标类别和坐标信息。YOLO 系列训练时用的是 TXT 格式每行一个目标格式为class_id x_center y_center width height其中 x_center、y_center、width、height 都是归一化到 0 到 1 的相对坐标。所以拿到 XML 标注后需要写脚本转换格式。转换时有个关键点YOLO 格式的坐标是归一化后的相对值必须除以图片的实际宽高。很多新手在这里出错导致坐标全部超出边界前面几轮训练 loss 直接变成 NaN。import os import xml.etree.ElementTree as ET from PIL import Image def convert_voc_to_yolo(xml_path, output_dir, classes): tree ET.parse(xml_path) root tree.getroot() img_name root.find(filename).text img_path os.path.join(os.path.dirname(xml_path), img_name) img_w, img_h Image.open(img_path).size yolo_lines [] for obj in root.iter(object): cls_name obj.find(name).text if cls_name not in classes: continue cls_id classes.index(cls_name) box obj.find(bndbox) x1 float(box.find(xmin).text) y1 float(box.find(ymin).text) x2 float(box.find(xmax).text) y2 float(box.find(ymax).text) x_center (x1 x2) / 2 / img_w y_center (y1 y2) / 2 / img_h w (x2 - x1) / img_w h (y2 - y1) / img_h yolo_lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) out_path os.path.join(output_dir, os.path.splitext(img_name)[0] .txt) with open(out_path, w) as f: f.write(\n.join(yolo_lines))转换完成后最好用可视化脚本把 YOLO 格式的标注框重新画到图片上人工抽检一遍。这一步很土但非常有效能发现坐标偏移、类别错标、框尺寸异常等问题。2.3 数据增强与样本平衡交通场景的样本分布天然不均衡。以我的项目为例行人样本约占总目标的 45%轿车约 35%公交车和货车各 10% 左右。如果直接拿去训练模型对公交车和货车的召回率会明显偏低。解决类别不平衡有两类手段一是调整 loss 里的类别权重二是做数据增强来扩充少数类样本。我两者都用了。数据增强我是在 YOLO 训练配置里开了 Mosaic 和 MixUp。Mosaic 会把 4 张图拼成一张增加单张图片中的目标数量也让小目标样本更丰富。MixUp 则把两张图按比例混合增强模型对背景干扰的鲁棒性。需要提醒的是Mosaic 和 MixUp 在训练后期建议关闭否则模型可能难以收敛到最优状态。YOLOv8 训练时可以通过配置项动态调整增强策略的启用和关闭。针对公交车和货车样本不足我还额外收集了这两个类别的专项数据并对其做了水平翻转、亮度调整、尺度缩放三类简单增强将少数类样本量提升到总样本的 20% 左右。增强不是越多越好过度增强会导致模型学到增强痕迹反而降低真实场景的泛化能力。3. YOLO 训练实操配置、训练与评估3.1 训练环境与目录结构训练环境的搭建比想象中简单。我用的是一张 24GB 显存的 GPU软件环境是 Python 3.10 PyTorch 2.1 CUDA 11.8训练框架直接基于 YOLOv8 官方仓库。如果你的显存只有 8GB也能跑只要把 batch-size 调小图像分辨率降到 640训练时长适当延长即可。数据集的目录结构建议直接对齐 YOLO 训练框架的默认约定省去后续改配置的麻烦dataset/ ├── images/ │ ├── train/ # 训练图片 │ └── val/ # 验证图片 ├── labels/ │ ├── train/ # 训练标注TXT格式 │ └── val/ # 验证标注TXT格式 └── data.yaml # 数据集配置文件train 和 val 的数量比例我按 8:2 来划分并且确保同一条道路的连续帧不会被同时分到训练集和验证集。这个细节容易被忽视如果连续帧被拆开模型在验证集上会“见”过几乎一样的画面评估指标虚高部署到真实场景就直接露馅。3.2 data.yaml 配置详解data.yaml 是 YOLO 训练的数据集入口内容非常简单但三个关键字段必须写对# data.yaml path: /path/to/dataset # 数据集根目录 train: images/train # 训练图片目录 val: images/val # 验证图片目录 nc: 4 names: 0: pedestrian 1: car 2: bus 3: truck关于类别名字这里有个细节建议全部用小写英文不要用中文也不要用大写。虽然 YOLO 框架本身支持中文命名但在导出 ONNX、部署到嵌入式设备时中文类别名偶尔会出现编码问题。别在这个地方给自己挖坑。3.3 训练参数选择与调优实战训练参数直接影响模型收敛速度和最终精度不同参数组合差异很大。下面是我在这个数据集上实验过的关键参数配置参数初始值调优后说明img640640输入分辨率过高内存压力大且收益递减batch1632显存充足可调大加速收敛epochs100150四类别任务 100 epoch 可到收敛拐点optimizerAdamWAdamWYOLOv8 默认收敛稳定lr00.010.001迁移学习微调时降低初始学习率momentum0.9370.937SGD/AdamW 通用合理值weight_decay0.00050.0005默认值防止过拟合如果你是第一次用 YOLOv8 训练可以直接跑官方命令# 使用预训练权重做迁移学习 yolo detect train \ datadataset/data.yaml \ modelyolov8m.pt \ epochs150 \ imgsz640 \ batch32 \ device0 \ projectresults \ namevehicle_person_exp跑起来之后每隔一段时间看一下 loss 曲线。正常情况是训练 loss 稳步下降验证 loss 呈现类似的下降趋势两者之间差距不大。如果验证 loss 在某个 epoch 后开始上升而训练 loss 还在降就是过拟合了可以把 epochs 缩短或者增加数据增强或者调大 weight_decay。3.4 评估指标怎么读怎么调YOLO 训练结束后会自动输出一套评估指标包括 mAP50、mAP50-95、precision、recall。很多新手只看 mAP50不够全面。我的做法是同时关注以下三组数据mAP50IoU 阈值 0.5 时的平均精度反映模型总体检测能力。这个值一般能达到 0.9 以上但别被它骗了它比较宽容。mAP50-95从 0.5 到 0.95 多个 IoU 阈值的平均精度。这个指标更严格更能反映定位精度。四类别任务做到 0.7 到 0.8 之间说明模型定位能力不错。每类别的 recall单独看每一类的召回率。如果某个类别的 recall 明显低于其他类别说明该类别的特征没学好或样本不足。实测中我遇到的情况是 mAP50 很高但 mAP50-95 偏低说明检测框的位置不够精准。解决办法是加大输入分辨率从 640 提升到 960同时将 anchor 匹配的 IoU 阈值适当放宽。注意分辨率提升带来的是显存和推理耗时的增加需要根据实际场景做取舍。4. 实测问题与避坑经验4.1 小目标漏检严重三步解法交通场景中远处的行人和车辆在画面里可能只有 30x30 像素左右模型很容易漏掉。我实测中小目标的召回率比中大型目标低 10 到 15 个百分点。解决思路有三步第一步提高输入分辨率。把 imgsz 从 640 提到 960小目标的特征图面积扩大 2 倍以上漏检率明显下降。但这会让推理时间增加约 40%。第二步启用 TTA测试时增强虽然推理变慢但作为离线检测场景可以显著提升召回率。第三步在 YOLOv8 的模型配置中增加 P2 检测层利用浅层高分辨率特征来检测小目标。具体做法是修改模型 yaml 文件在 head 部分加入从第 2 层引出的检测分支。4.2 光照和遮挡场景下的误检漏检夜间、逆光、雨雾天气是这套数据集场景里面最考验模型的情况。夜间行人穿着深色衣物与背景对比度极低模型容易漏检。雨天玻璃反光、地面积水倒影会产生大量误检框。处理这类问题数据层面我做了两件事一是在数据增强环节增加了随机亮度、对比度和色彩抖动让模型适应光照变化二是专门收集了一些夜间和雨天的图片做微调让模型见过“难”的样子。算法层面可以结合图像增强预处理步骤比如限制对比度自适应直方图均衡化CLAHE在推理前对图像做增强提升暗部细节的可见度。注意夜间数据不要过度依赖红外或热成像图。这类图和普通可见光图像的分布差异很大直接混在一起训练会让模型在可见光场景下的精度下降。如果业务场景确实需要红外建议单独训练一个红外模型或做域适应。4.3 训练不收敛loss 炸掉的排查思路训练过程中最让人头疼的问题就是 loss 不降或者直接变成 NaN。从我的经验来看常见原因有以下几种数据标注坐标越界。标签文件中出现大于 1 或小于 0 的坐标值训练时模型无法有效计算 loss。排查方法是写脚本遍历所有标签文件检查是否存在越界坐标。学习率设置过大。使用预训练权重微调时初始学习率设置为 0.01 可能偏大。建议从 0.001 开始观察前 10 个 epoch 的 loss 变化再调整。类别 id 超出 nc 范围。标签中的 class_id 大于 data.yaml 中配置的 nc 值会导致数组索引越界训练直接崩溃。batch 内目标数量过少。如果 batch 设置太小且图片本身目标很少可能出现梯度不稳。适当增大 batch 或混合使用 Mosaic 增强可以缓解。我踩得最深的一个坑是用 LabelImg 标注时有一批图片的标注框超出了图像边界转换脚本里也没有做裁剪和归一化处理结果训练到第 12 个 epoch 时 loss 直接跳到 NaN回退重跑浪费了大半天。从那以后我在训练前一定会跑一遍数据校验脚本。4.4 类别混淆怎么处理四类别任务中最容易混淆的是公交车和货车车身尺寸相近轮廓上有重叠尤其是侧面视角。还有一个容易混淆的场景小轿车和 SUV。虽然我把轿车统一归为一类但 SUV 的高车身轮廓与部分轻型货车存在相似性。处理类别混淆我的方案有两条线一是增加区分度高的标注数据比如公交车和货车的正面车头图、货车侧面带货箱图等让模型学到更细的特征二是调整 loss 中的类别权重对易混淆的类别赋予更高权重迫使模型重点学习它们的差异。在迁移到自己的场景时如果发现混淆问题还在可以考虑引入细粒度分类模型做第二级分类器先检测出车辆位置再用分类模型区分具体车型。5. 数据集落地与后续扩展方向5.1 从检测模型到自动标注的迭代这套数据集训练出的模型我实际上用于一个更大项目的筑基流程。模型在真实场景中推理后会输出新的检测框我再人工校验这些检测结果的高置信度样本将其作为新的标注数据补充进训练集。这个过程叫主动学习回注能持续优化模型对场景的适配。具体操作上我写了一个简单的自动标注脚本用已训练好的模型对未标注图片做预测保留置信度大于 0.85 的检测框自动生成 YOLO 格式标注文件再由人工抽检。这样新场景的数据标注效率能提升 3 到 5 倍。自动标注省时省力但置信度阈值要控制好否则错标样本会污染数据集。5.2 迁移到车载与安防场景的适配经验这套数据集本身的泛化能力还不错但如果直接迁移到差异化很大的场景比如高空无人机视角、鱼眼摄像头视角效果会打折扣。原因很简单视角变了目标比例和外观都变了。迁移到这类场景时不要直接拿原有模型硬跑而是应该在原有模型权重的初始化基础上用少量新场景数据做微调。我已经验证过500 张新场景图片微调比 2000 张新场景图片从头训练效果更好收敛更快。5.3 模型部署时的精简与加速训练完成后部署环节也有讲究。如果要做实时推理比如边缘设备或嵌入式设备我会把模型从 PyTorch 格式导出为 ONNX再用 TensorRT 做加速。导出的几个关键细节是# 导出 ONNX yolo export modelbest.pt formatonnx imgsz640 halfTrue导出后建议用 onnxruntime 或 TensorRT 验证一下输入输出尺寸和精度是否符合预期。特别注意 dynamic batch 的设置如果部署时只需要固定 batch1导出时就不要开 dynamic batch可以缩减模型体积加快推理速度。在实际项目中我把 YOLOv8m 导出并转换为 TensorRT FP16 后在嵌入式设备上的推理耗时从原始的 45ms 降到了 18msmAP 精度几乎没有下降。需要说明的是部署设备差异很大这个数据仅供参考。5.4 数据集后续扩充路线数据集后续扩展我计划沿着四个方向走一是扩充恶劣天气样本加入更多雨天、雪天、雾天的图片提升模型在复杂气象条件下的鲁棒性二是增加夜间多光源场景样本覆盖车灯眩光、路灯色温变化等情况三是加入更多俯视视角数据为无人机场景做准备四是引入视频时序信息把检测能力扩展到跟踪任务。另外如果你准备使用这套数据集做迁移学习建议固定随机种子保证实验的可复现性。根据我个人的实操经验数据集从来不是一次做完就结束的。一个好的数据集要跟着算法迭代一起成长持续补充难例、修正标注、平衡分布模型精度才会稳步提升。做完这套四类别车辆行人数据集我最大的体会是标注质量和数据分布的控制远比模型选型更有杠杆效应。如果你正准备做类似的目标检测项目建议把 70% 的精力放在数据准备和清洗上剩下 30% 放在训练和调参上最终效果会远超你的预期。本文还有配套的精品资源点击获取
返回列表