自动驾驶多类别交通目标检测数据集:YOLO格式与YOLOv8训练实战
简介这份自动驾驶多类别交通目标检测数据集面向自动驾驶感知算法开发者、智能交通研究人员及计算机视觉方向的学生用于构建车辆、行人、交通标志等多目标实时检测系统可支撑L2至L4级自动驾驶算法开发与ADAS功能验证。资源包共2000个文件以txt标注文件、jpg图像、yaml配置文件及docx说明文档为主压缩包约65.55MB其中txt与jpg一一对应便于直接接入YOLO等主流检测框架训练。数据集划分训练集802张、验证集229张、测试集114张覆盖汽车、公交车、卡车、警车、救护车、行人、自行车、摩托车、交通标志、路灯、建筑物、树木、山脉、绿化带等30类交通要素并包含日间夜间、城市山区、静态动态等多样场景还特别纳入东南亚特色交通工具以提升模型跨环境适应性。目前已有75人学习下载适合用于交通要素分布热力图、特殊车辆优先级识别及道路场景语义理解等扩展任务。1. 自动驾驶多类别交通目标检测数据集802 张训练图能跑出什么名堂如果你正在找一份能直接丢进 YOLO 训练管线、不用自己从视频里抽帧标注的交通场景数据集这份 802 张训练图 229 张验证图 114 张测试图的多类别交通目标检测数据集值得先拆开看看。它覆盖 car、bus、truck、police car、ambulance、person、bike、cycle、traffic-sign、street light、buildings、trees、mountain、garden 等 30 个类别标注是标准 YOLO 格式每张图对应一个同名 txt边界框坐标和类别标签都在里面。适合做自动驾驶感知模块的快速原型验证、ADAS 功能训练、智能交通场景的异常事件识别也适合计算机视觉方向做小目标检测和复杂场景鲁棒性研究。它不是那种几十万张的工业级数据集但胜在类别细、场景杂、标注干净拿来跑通流程、验证模型结构、做迁移学习预训练都够用。2. 拆开压缩包先看什么目录结构、类别分布与标注格式2.1 文件组织方式与命名规律拿到压缩包解压后你大概率会看到 images 和 labels 两个平行目录或者 train/val/test 三个子目录下各自再分 images 和 labels。从项目正文给出的文件名来看图片命名是哈希串加_jpg.rf.再加一串哈希后缀统一是.jpg。这种命名方式是标注平台导出时自动生成的好处是全局唯一不会冲突坏处是你没法从文件名直接读出场景信息。对应的标注文件就是同名.txt放在 labels 目录下路径结构和 images 完全镜像。我一般会先跑一遍文件配对检查确认每张图都有对应的标注文件没有孤儿文件。常见做法是用 Python 脚本扫一遍import os from pathlib import Path img_dir Path(dataset/images/train) lbl_dir Path(dataset/labels/train) img_stems {p.stem for p in img_dir.glob(*.jpg)} lbl_stems {p.stem for p in lbl_dir.glob(*.txt)} missing_lbl img_stems - lbl_stems missing_img lbl_stems - img_stems print(f图片总数: {len(img_stems)}) print(f标注总数: {len(lbl_stems)}) print(f缺标注的图片: {len(missing_lbl)}) print(f缺图片的标注: {len(missing_img)}) # 输出前10个缺标注的文件名方便排查 for name in list(missing_lbl)[:10]: print(f 缺标注: {name})这段脚本的逻辑很直接分别收集 images 和 labels 目录下所有文件的 stem去掉扩展名的文件名做集合差运算。missing_lbl是有图没标注missing_img是有标注没图。正常情况两个都应该是 0如果不是 0说明导出时出了问题需要重新检查原始数据。参数上唯一要注意的是路径要改成你实际解压后的目录结构有些导出包会多一层obj_train_data之类的中间目录。2.2 YOLO 标注格式的字段含义与校验YOLO 格式的标注文件每行代表一个目标格式是class_id x_center y_center width height五个字段全部归一化到 0~1 之间x_center和y_center是边界框中心点相对整图宽高的比例width和height是边界框宽高相对整图宽高的比例。class_id是从 0 开始的整数对应一个classes.txt或data.yaml里的类别名列表。校验的时候重点看三件事坐标是否越界小于 0 或大于 1、宽高是否为零或负数、class_id 是否超出类别总数。我一般会写一个快速校验脚本import yaml from pathlib import Path # 先读 data.yaml 拿到类别数和类别名 with open(dataset/data.yaml, r) as f: data_cfg yaml.safe_load(f) num_classes data_cfg[nc] class_names data_cfg[names] print(f类别数: {num_classes}) print(f类别名: {class_names}) lbl_dir Path(dataset/labels/train) bad_lines [] for txt_file in lbl_dir.glob(*.txt): with open(txt_file, r) as f: for line_no, line in enumerate(f, 1): parts line.strip().split() if len(parts) ! 5: bad_lines.append((txt_file.name, line_no, 字段数不对)) continue cls_id int(parts[0]) coords [float(x) for x in parts[1:]] if cls_id 0 or cls_id num_classes: bad_lines.append((txt_file.name, line_no, fclass_id越界: {cls_id})) if any(c 0 or c 1 for c in coords): bad_lines.append((txt_file.name, line_no, f坐标越界: {coords})) if coords[2] 0 or coords[3] 0: bad_lines.append((txt_file.name, line_no, f宽高非正: {coords[2]}, {coords[3]})) print(f异常行数: {len(bad_lines)}) for item in bad_lines[:20]: print(f {item[0]} 第{item[1]}行: {item[2]})这里的关键参数是data.yaml里的nc和names必须和标注文件里的 class_id 范围一致。如果nc写的是 30 但标注里出现了 30 或更大的 id训练时就会报索引越界。坐标越界的情况在自动标注导出时偶尔会出现通常是标注框超出了图像边界需要裁剪或丢弃。2.3 类别分布统计与长尾问题预判30 个类别的数据集最怕的就是类别极度不均衡。car、person、traffic-sign 这类常见目标可能有几千个实例而 ambulance、police car 这种特殊车辆可能只有几十个。训练前先统计一遍每个类别的实例数心里有数from collections import Counter from pathlib import Path lbl_dir Path(dataset/labels/train) counter Counter() for txt_file in lbl_dir.glob(*.txt): with open(txt_file, r) as f: for line in f: parts line.strip().split() if parts: counter[int(parts[0])] 1 # 按类别名输出 for cls_id in sorted(counter.keys()): name class_names[cls_id] if cls_id len(class_names) else f未知_{cls_id} print(f{cls_id:3d} {name:20s} {counter[cls_id]:6d})如果发现某些类别实例数低于 100训练时就要考虑用类别权重、过采样或者 focal loss 来缓解。这份数据集里 ambulance 和 police car 大概率属于长尾类别但它们在自动驾驶场景里又特别重要——救护车识别直接关系到紧急车辆避让功能。常见做法是在data.yaml里给这些类别更高的损失权重或者在数据加载时对包含这些类别的图片做重复采样。3. 从零跑通 YOLOv8 训练配置文件、命令与参数调优3.1 构建 data.yaml 与目录规范YOLOv8 训练的第一步是把数据目录整理成它认识的格式。标准结构是dataset/ ├── data.yaml ├── images/ │ ├── train/ │ ├── val/ │ └── test/ └── labels/ ├── train/ ├── val/ └── test/data.yaml的内容path: /absolute/path/to/dataset train: images/train val: images/val test: images/test nc: 30 names: 0: car 1: bus 2: truck 3: police car 4: ambulance 5: person 6: bike 7: cycle 8: traffic-sign 9: street light 10: buildings 11: trees 12: mountain 13: garden # ... 其余类别按实际顺序补全注意path要写绝对路径train、val、test写相对路径。names的顺序必须和标注文件里的 class_id 严格对应错一个位置整个训练就废了。我见过有人把names写成列表形式[car, bus, ...]YOLOv8 也认但字典形式更直观不容易数错。3.2 训练命令与关键超参设置YOLOv8 的训练入口很简洁一行命令就能跑yolo detect train \ datadataset/data.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ lr00.01 \ lrf0.01 \ patience20 \ device0 \ projectruns/traffic \ nameexp01逐个说参数modelyolov8n.pt是从 COCO 预训练权重开始微调小数据集不建议从 scratch 训收敛慢还容易过拟合。imgsz640是输入分辨率如果显存不够可以降到 416 或 320但小目标比如远处的 traffic-sign检测精度会掉。batch16在 8GB 显存上跑 640 分辨率差不多是上限显存更大可以往上加。lr00.01是初始学习率微调场景下这个值偏大常见做法是降到 0.001 或 0.005。patience20是早停耐心值20 个 epoch 验证指标不提升就停防止过拟合。device0指定第一块 GPUCPU 训练把这一行去掉或者写devicecpu。如果训练中途报显存不足优先降batch其次降imgsz。如果 loss 震荡厉害把lr0再降一个数量级同时加warmup_epochs5让学习率慢慢升上去。3.3 训练过程监控与指标解读训练启动后runs/traffic/exp01/目录下会生成results.csv、weights/、confusion_matrix.png等文件。重点盯三个指标box_loss、cls_loss、mAP50。box_loss下降说明边界框回归在收敛cls_loss下降说明分类在收敛mAP50上升说明整体检测质量在提升。如果box_loss降但cls_loss不降大概率是类别不平衡或者某些类别标注质量差。如果mAP50在某个 epoch 后突然掉下来检查一下学习率是不是太大了导致跳出了局部最优。我一般会在训练结束后用验证集跑一遍yolo detect val拿到每个类别的 AP 值看看哪些类别拖后腿yolo detect val \ modelruns/traffic/exp01/weights/best.pt \ datadataset/data.yaml \ splitval \ save_jsonTruesave_jsonTrue会输出 COCO 格式的评估结果方便用 pycocotools 做更细的分析。如果某个类别的 AP 特别低先看训练集里这个类别的实例数是不是太少再看标注框是不是普遍偏小或者偏大。4. 避坑与排查标注、训练、评估里最容易翻车的五件事4.1 类别名顺序错位导致模型学偏现象训练 loss 正常下降但验证时发现 car 被识别成 busperson 被识别成 bike类别完全乱套。原因data.yaml里names的顺序和标注文件里 class_id 的实际含义不一致。比如标注时 car 是 0、bus 是 1但data.yaml里写成了 bus 是 0、car 是 1。解决找一份标注文件看第一列的数字分布再对照原始标注工具的类别列表把names的顺序改对。改完后重新训练不要试图在已有权重上继续训因为模型已经学错了映射关系。4.2 图片和标注不同步导致训练报错现象训练启动后报FileNotFoundError或AssertionError提示找不到某些标注文件。原因images 目录下有图但 labels 目录下没有对应的 txt或者文件名大小写不一致.JPGvs.jpg。解决跑一遍 2.1 节的配对检查脚本把缺标注的图片移走或者补上标注。文件名大小写问题在 Linux 上特别常见统一改成小写后缀。4.3 小目标漏检严重现象mAP50 整体还行但 traffic-sign、street light 这类小目标的 AP 很低可视化预测结果发现远处的小目标基本没框出来。原因输入分辨率太低小目标在特征图上只剩几个像素网络根本学不到有效特征。或者数据集中小目标实例太少模型偏向于预测大目标。解决把imgsz从 640 提到 1024 或 1280同时把batch降下来。如果显存不够用yolov8m或yolov8l这种更大的模型它们的特征金字塔对小目标更友好。另外可以在data.yaml里加overlap_maskTrue和mask_ratio4来增强小目标采样。4.4 验证集指标虚高但测试集拉胯现象验证集 mAP50 到了 0.85但拿测试集一跑只有 0.6 出头。原因验证集和训练集分布太接近比如都来自同一段视频的连续帧模型实际上在“背答案”。测试集如果包含不同场景夜间、雨天、山区泛化能力就暴露了。解决重新划分数据集确保训练、验证、测试三个集合的场景不重叠。如果原始数据已经是固定划分训练时把验证集比例调小比如从 0.2 降到 0.1让更多数据进训练集。另外可以加数据增强hsv_h0.015、hsv_s0.7、hsv_v0.4、flipud0.5、fliplr0.5、mosaic1.0。4.5 训练中断后恢复踩坑现象训练到一半断电或手动停了想从last.pt继续训结果 loss 突然飙升或者指标归零。原因YOLOv8 的last.pt保存了优化器状态和 epoch 信息但如果你改了data.yaml或者换了数据集路径恢复时类别数对不上就会出问题。另外学习率调度器在恢复时可能从错误的 step 开始。解决恢复训练用yolo detect train resume modelruns/traffic/exp01/weights/last.pt不要手动指定data和epochs让它从 checkpoint 里读。如果必须改配置先把last.pt里的模型权重单独导出再用model导出权重重新开始一个新训练把epochs设成剩余轮数。5. 进阶玩法用这份数据集做迁移学习与特殊车辆优先级识别这份数据集最值钱的地方不是 802 张图本身而是它覆盖了 ambulance、police car 这类特殊车辆以及东南亚特色的 jeep 型三轮车。这些类别在通用 COCO 数据集里要么没有要么极少拿来做一个“紧急车辆优先识别”的微调任务非常合适。具体做法是先用 COCO 预训练的 YOLOv8 在完整 30 类上训一个基线模型然后冻结 backbone只微调检测头专门针对 ambulance 和 police car 做二分类增强。代码上就是在data.yaml里把其他类别的图片过滤掉只保留包含这两类的样本再跑 20~30 个 epochimport shutil from pathlib import Path src_img Path(dataset/images/train) src_lbl Path(dataset/labels/train) dst_img Path(dataset_emergency/images/train) dst_lbl Path(dataset_emergency/labels/train) dst_img.mkdir(parentsTrue, exist_okTrue) dst_lbl.mkdir(parentsTrue, exist_okTrue) target_ids {3, 4} # police car 和 ambulance 的 class_id for txt_file in src_lbl.glob(*.txt): with open(txt_file, r) as f: lines f.readlines() # 只要包含目标类别就保留整张图 if any(int(line.split()[0]) in target_ids for line in lines if line.strip()): shutil.copy(txt_file, dst_lbl / txt_file.name) img_file src_img / (txt_file.stem .jpg) if img_file.exists(): shutil.copy(img_file, dst_img / img_file.name)这段脚本的逻辑是遍历所有标注文件只要某张图里出现了 police car 或 ambulance就把图和标注一起复制到新目录。这样得到的子集虽然小但类别聚焦微调时模型更容易学到特殊车辆的特征。参数上target_ids要根据你实际的 class_id 映射来改别照抄。另一个玩法是用这份数据做交通要素分布热力图。把每张图的标注框中心点提取出来按类别聚合再叠加到一张空白画布上生成密度图。这个在智能交通管理里可以用来分析哪些路段行人密集、哪些路口交通标志缺失。实现上用numpy.histogram2d加matplotlib的imshow就能出图不需要额外标注。我自己的习惯是每次拿到新数据集先跑一遍配对检查和类别统计再花十分钟可视化二十张随机样本的标注框确认没有系统性偏移或漏标。这个流程帮我省过至少三次“训练完才发现标注全错位”的后悔药。从那以后我每次开新数据集都强制走一遍这个检查希望帮到你。本文还有配套的精品资源点击获取