新闻详情

新闻详情

首页 / 资讯中心 / 详情

YOLOV5数据集格式从入门到实战:智能小车赛道目标检测训练指南

发布时间:2026/9/16 5:13:00来源:尧图网络
YOLOV5数据集格式从入门到实战:智能小车赛道目标检测训练指南
简介这套面向智能小车赛道自动驾驶的交通指示牌目标检测数据集按YOLOV5目录格式组织共包含左转、右转、红灯、绿灯、人行道等8个类别图像为200×120分辨率的RGB图片可直接作为目标检测训练数据免去格式转换和手工整理。压缩包内共2000个文件主要含872张jpg图片、1127个txt标注文件以及1个可视化脚本其中训练集由901张图片和对应txt标签组成测试集含225张图片与标签另附类别名称字典txt便于映射类别ID。提供的可视化py脚本无需任何改动即可运行随机读取一张图片就能绘制预测边界框并保存到当前目录非常适合快速验证标注效果或辅助教学演示。整个资源仅10.31MB轻量紧凑已有151人学习适合智能车竞赛、自动驾驶入门、目标检测课程实验等场景帮助使用者直接上手训练与评估。1. 智能小车赛道自动驾驶为什么要先卡死在 YOLOV5 目录格式上做智能小车赛道自动驾驶的目标检测我见过最多的情况不是模型 train 不起来而是数据集本身让 train 脚本跑不起来。很多同学从网上下一个 COCO 子集把交通指示牌相关类别挑出来放到 YOLOV5 里一训练发现小车在固定赛道视角下根本检测不到——公开数据集里都是远景街拍你的赛道是俯视、近距离、强反光。这种 8 类别数据集的聪明之处在于它把范围锁在赛道自动驾驶场景并且直接按 YOLOV5 目录格式给到手里你基本不用改数据加载代码克隆官方仓库、改一个 data.yaml、调几个超参数就能开始训练。把目录格式和类别定义吃透比急着标图重要得多。适合准备竞赛、毕设和入门目标检测的人也适合想把手里图片整理成可复用数据集的一线工程师。2. YOLOV5目录格式拆解images/labels 分层、类别文件与索引对应2.1 一张图配一个同名 txt是 YOLO 格式的根先不要急着跑训练从目录开始看。YOLOV5 对数据读取的路径很敏感目录不对后面所有脚本都会报错。YOLO 格式不把标注写在数据库或者 json 里而是每张图对应一个同名 txt。训练脚本在images/train下读到000001.jpg后会去labels/train找000001.txt找不到就报错找到了就按行解析归一化坐标。这种命名绑定方式对做 train/val 划分很友好只要同步移动同名文件就不会乱。这里容易混淆的是YOLO 标注里的坐标不是 VOC 的(xmin,ymin,xmax,ymax)而是class x_center y_center width height。中心点坐标和宽高都除以原图宽高范围是 0~1。正因为是比例值训练时无论把输入缩放到 640 还是 320标签都不需要重新生成。这个设计是 YOLO 系模型最值得理解的部分。2.2 最小目录树先跑通一个能 train 的骨架我一般会先搭一个最小目录树确认结构能跑通再加数据# 用 find 或 tree 查看数据集目录结构 traffic8/ ├── images/ │ ├── train/ │ │ └── 000001.jpg │ └── val/ │ └── 002001.jpg ├── labels/ │ ├── train/ │ │ └── 000001.txt │ └── val/ │ └── 002001.txt └── data.yaml这段结构看起来简单但它定义了后面所有脚本的输出目标。images和labels必须放在同级目录因为 YOLOV5 源码里会用字符串替换的方式把images改成labels。如果你把标签放在labels/train/images之类的深层路径训练时就会得到labels not found。目录名建议保持官方默认的train和val不要用test当验证集因为val.py默认读取val目录。2.3 data.yaml 里的 names 顺序就是训练时的类别索引接下来是很多新手第一次踩坑的地方data.yaml 里的names列表顺序直接决定标注 txt 里的数字代表什么。names[0]对应 class 0names[1]对应 class 1以此类推。训练时你写nc: 8但names里如果没有列出 8 个名字训练脚本不一定会立刻报错到评估时类别就串了。# 数据配置文件示例 path: ../datasets/traffic8 # 数据集根目录 train: images/train # 相对 path 的训练图片目录 val: images/val # 相对 path 的验证图片目录 nc: 8 # 类别数必须与模型 yaml 一致 names: 0: stop_line 1: go_left 2: go_right 3: speed_limit 4: construction_cone 5: crosswalk 6: traffic_light 7: obstacle注意这里的类别名只是示例最终以你手里的数据集 data.yaml 为准。如果你的数据集把traffic_light放在第 6 位而标注脚本写成 class 2那训练出的模型会把别的类别当成红绿灯。写配置文件时我会从数据集自带的说明里复制 names而不是自己凭感觉写。2.3.1 为什么不能跳过 names有时候你看到训练能跑但验证集 AP 全为 0第一反应是模型问题其实先检查 names。我曾遇到一个项目把names列表和标注文件用了不同顺序结果 AP 曲线毫无规律。YOLOV5 的 dataloader 不会校验名字它只按行下标读所以语义错误要自己用代码查。建议训练前打印任意三个 txt 的 class ID 和 data.yaml names 的对应关系确认没有错位。这个测试 5 分钟就能做完能省掉至少一个晚上的无用训练。下表展示了一个赛道数据集的典型类别分配它不一定和你手里的数据集完全一致但能帮助你理解索引和语义的对应关系class index类别名赛道中典型出现位置0stop_line停止线前地面1go_left左转箭头指示牌2go_right右转箭头指示牌3speed_limit限速牌4construction_cone路边锥桶5crosswalk斑马线6traffic_light红绿灯7obstacle赛道上的障碍物2.4 先跑一次“假训练”验证目录格式搭建好后不要急着标几百张图先用两张图跑一个最小训练确认数据配置没写错。用 YOLOV5 仓库默认参数只训练 1 个 epoch# 用最小 batch 验证数据链路不关心精度 python train.py --data ../datasets/traffic8/data.yaml --weights yolov5s.pt --img 640 --batch 2 --epochs 1 --cache如果这一步能正常输出每个 batch 的 loss说明目录格式已经对了。后面就算加大量数据也只是数量问题。常见报错AssertionError: Label class 8 exceeds nc8意思是你的 txt 里出现了索引为 8 的类别而nc8只放行 0~7这是类别索引越界不是目录结构问题。看到这类报错先回 data.yaml 检查 names 顺序和标注文件里的数字。3. 把赛道图片变成 YOLOV5 数据集标注、划分与转格式实操3.1 标注工具选型与输出格式检查要给赛道图片打标我一般首选 X-AnyLabeling 或 LabelImg。标注时先建立一个classes.txt内容就是 data.yaml 的 names一列一个顺序必须一致。LabelImg 保存成 YOLO 格式时会在图片同目录生成同名 txt方便直接复制到labels/train。如果素材原来已经有 VOC xml 或者 COCO json也不用重新标写脚本转换即可。转换前先看两个关键点一是类别名是否和 names 一一对应二是坐标是否可能超出图片边界。我见过不少 json 转出来的坐标比原图大上几个像素直接导致训练时 loss 异常。3.2 一个最小可用的 VOC/COCO 转 YOLO 脚本以 VOC 为例假设你读到了 annotation 里的 bndbox转换函数核心逻辑如下# 将 VOC 像素坐标转为 YOLO 归一化坐标写入 txt def voc_to_yolo(size, box, class_id, out_path): dw 1.0 / size[0] # 宽归一化系数 dh 1.0 / size[1] # 高归一化系数 x_center (box[0] box[2]) / 2.0 y_center (box[1] box[3]) / 2.0 width box[2] - box[0] height box[3] - box[1] with open(out_path, w, encodingutf-8) as f: f.write(f{class_id} {x_center*dw:.6f} {y_center*dh:.6f} f{width*dw:.6f} {height*dh:.6f}\n)这里box是归一化之前的绝对像素坐标(xmin, ymin, xmax, ymax)size是(width, height)。除以图片宽高后所有坐标都在 0~1训练时无论缩放到 640 还是 320 都适用。.6f保留 6 位小数就够不需要更多精度。我自己会把这段函数单独放一个utils.py因为后续每次加数据都要用。3.3 train/val 划分脚本图片和标签必须同步移动划分数据集时不要手动拖文件用脚本散列到目录。这里有一个容易出错的点按文件名随机排列后移动图片却忘记移动标签或者标签移动了图片没动。所以我的脚本只维护一个文件名列表然后同时移动图片和同名 txt。import os import random import shutil from pathlib import Path src_images Path(raw_images) # 原始图片目录 src_labels Path(raw_labels) # 原始标签目录 train_img Path(images/train) # 训练图片目录 val_img Path(images/val) # 验证图片目录 train_lbl Path(labels/train) val_lbl Path(labels/val) train_img.mkdir(parentsTrue, exist_okTrue) files list(src_images.glob(*.jpg)) random.seed(2024) # 固定随机种子保证划分可复现 random.shuffle(files) val_count int(len(files) * 0.2) val_files, train_files files[:val_count], files[val_count:] for f in train_files: shutil.move(str(f), train_img / f.name) # 移动图片 lbl src_labels / (f.stem .txt) # 通过同名去找标签 if lbl.exists(): shutil.move(str(lbl), train_lbl / lbl.name)这段代码先把所有图片路径打乱前 20% 作 val其余作 train。移动图片时用f.stem .txt找到同名标签如果标签不存在训练时就会报labels not found。注意val_count至少要大于 1如果总共只有 10 张图验证集会没有意义但这是数据量问题不是脚本问题。固定随机种子能保证多次运行结果一致方便对比实验。3.3.1 划分后目录不一致怎么办划分完如果发现某个图片没有标签先不要急着补标。常见原因是原始标签目录里文件名后缀不是.txt而是_label.txt或.xml。我习惯在划分脚本里先打印缺失标签的文件名列表人工确认是不是命名规则问题。如果是统一重命名后再跑一次划分避免手忙脚乱移动文件。3.4 划分之后先做一次标签合法性检查完成目录生成后我还会跑一个检查脚本批量统计类别数量并找出空标签和越界坐标。下面表格列出几个常见问题异常类型常见原因处理方式txt 为空标注时漏了框删除对应图片或重新标注坐标不在 0~1原图尺寸与标注尺寸不一致转格式时用原图宽高重新归一化类别索引 ncnames 顺序不一致重新映射类别 ID一图多框但 txt 行数少存错了文件检查标注工具输出路径检查脚本核心代码如下它只打印异常文件避免人工逐一打开from pathlib import Path bad [] # 收集异常文件 for txt in Path(labels/train).glob(*.txt): lines [l.strip() for l in txt.read_text().splitlines() if l.strip()] if not lines: bad.append((txt, empty)) # 空标签 continue for line in lines: parts line.split() if len(parts) ! 5: bad.append((txt, fields)) # 字段数不对 break cx, cy, w, h map(float, parts[1:5]) if not (0 cx 1 and 0 cy 1 and 0 w 1 and 0 h 1): bad.append((txt, range)) # 归一化坐标越界 break print(bad[:20])这段脚本遍历labels/train下所有 txt检查每行是否有 5 个字段以及中心点坐标和宽高是否在 0~1。只要发现一个异常就记录并跳出避免同一文件刷屏。赛道图片里常有极小的标牌宽高可能小于 0.01这种不一定非法但我会留意后续训练时模型是否漏检。4. 交通指示牌与赛道元素的8类别设定及标注边界4.1 8类别的设计逻辑多一类不如准一类赛道上的交通指示牌和城市道路场景不同小车观察距离近、视角低、运动方向固定。我倾向于把类别设计成“能直接映射到控制指令”的元素而不是严格按物理对象划分。比如“限速标志”和“解除限速标志”可以合并成speed_limit一类因为对小车来说都是需要减速的事件“左转”“右转”单独成类因为它们决定方向盘方向。锥桶和障碍物可以合并成obstacle但如果赛道里锥桶出现频率很高我会单独给它一类避免它淹没在其他障碍物里。表8类别设定的常见划分示例类别判定标准典型误标stop_line可见完整停止线边缘把阴影当停止线go_left箭头符号完整可辨左转和直行箭头同时可见时只标一个speed_limit圆形牌面可见牌面反光看不到数字仍要标construction_cone锥体主体露出只露出一小角时不标obstacle阻挡前进的未知物体远处背景里的车子不标这里再强调一遍具体 8 个类别以你的数据集 data.yaml 为准如果别人已经做好了类别定义你只需要在训练前把标注的 class id 对齐。4.1.1 类别合并的例子把“禁止左转”和“左转”放一起会让控制逻辑混乱所以在定义类别前先问自己这个目标类别是否能对应一个明确动作能对应就保留不能就合并到更大的类别里。8 个类别的容量并不大所以每一个类别都要服务最终的控制决策。4.2 标注边界遮挡、截断和模糊怎么处理小车在赛道上拍到指示牌经常是斜着的、被杆子挡了一半、或者因为运动模糊看不清。标注时我会给一个统一边界目标主体超过 30% 被遮挡就不标否则标完整外接框视觉上无法判断类别时宁可删除样本不要硬标。多标一个错框比少标一个框危害更大因为它会给模型一个错误的正样本。另外同一张图里出现多个相同指示牌时每个都要标注不要只标最清晰的那一个否则推理时模型对重复目标的召回率会明显偏低。4.2.1 一个框还是要两个框两辆锥桶挨得特别近边界框重叠超过 50%我会看成两个独立目标分别标如果它们本身就是连在一起的障碍物只标一个框。关键在于训练时 NMS 会抑制重叠框标两个框并不会让模型学会区分两个锥桶反而可能让它输出重复框。所以判定标准是物理上是否可分离而不是视觉上是否接触。4.3 用脚本检查类别分布和标注一致性8 类别数据集的另一个常见问题是类别严重不平衡。赛道视频天然就是“直行”出现几百次“右转”只出现几回。训练前先统计一下每个类别的框数量决定是否需要做扩充。下面的脚本输出所有类别的框数from pathlib import Path from collections import Counter counter Counter() for split in [train, val]: for txt in Path(flabels/{split}).glob(*.txt): for line in txt.read_text().splitlines(): parts line.split() if len(parts) 1: counter[int(parts[0])] 1 # 第一项是类别索引 print(counter)Counter统计的是目标框个数不是图片张数。如果某个类别只有几十个框而其他类别有几千个我一般会先把这类图片复制几份做复制粘贴增强或者用 Mosaic 增加包含该类别的合成图。如果你的数据集中有一些类别原本就难以出现比如obstacle可以考虑对少样本图片做平移翻折但注意交通指示牌有语义方向左右翻转会把“左转”变成“右转”这种情况要做 label 同步翻转并保证类别逻辑成立。交通指示牌不全是左右对称的翻转增强要谨慎。4.4 数据增强策略取舍YOLOV5 默认开启 Mosaic 和 HSV 扰动对赛道场景通常够用。如果原始图片来自固定摄像头我建议调高hsv_h、hsv_s的值来模拟不同光照但不要用太多随机裁剪因为赛道交通指示牌大多是中小目标随机裁剪可能把目标切没。YOLOV5 自带的cache选项可以让数据预加载到内存加快小数据集的训练轮转。8 类数据集如果只有几百张图epochs可以设 80~100配合早停观察 loss 曲线我一般会在hyp.scratch-low.yaml里把hsv_h从0.015加到0.03效果更平滑。5. 用 YOLOV5 训练自己的数据集超参数、配置与常见报错现在数据集目录格式正确、类别也定了可以进入训练阶段。YOLOV5 仓库本身不需要改任何代码你只需要准备两个配置文件数据集 data.yaml 和模型结构 yaml。5.1 修改 nc 并确认 names 顺序模型结构文件里yolov5s.yaml第一行nc: 80必须改成nc: 8。这里的nc和 data.yaml 的nc必须一致。很多人只在模型 yaml 里改了nc忘了 data.yaml导致训练命令报错或类别数不对。# 图像尺寸、批次、轮数、数据配置一次配齐 python train.py \ --data datasets/traffic8/data.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 16 \ --epochs 80 \ --cache \ --name traffic8_run参数说明--weights表示加载 COCO 预训练权重通常比随机初始化收敛快得多而且不会影响最终输出类别数因为 YOLOV5 会自动替换最后一层--cache把图片加载到内存避免每个 epoch 都读磁盘数据集小时非常有效--name只是输出目录名不是模型名。对于 8 类别小车数据集--batch 16在 8G 显存上比较安全显存小就降到 8。5.2 必调的一组超参数lr0、batch、imgsz、anchorYOLOV5 的hyp.scratch-low.yaml默认超参数比较稳但我对小车数据集会重点关注下面几个参数参数作用我的建议值lr0初始学习率0.01 或 0.005类别少时可以小一点batch每批次图片数显存 8G 用 1612G 用 32imgsz训练分辨率640 起步小目标多可试 800anchor锚框配置先用默认检测不准再--evolve这里特别注意imgsz对交通指示牌这类小目标影响很大。如果赛道指示牌在原图只占几十个像素640 分辨率下容易漏检可以先升到 800 看 mAP 结果。代价是显存占用翻倍batch 要相应减半。锚框方面YOLOV5 在训练时会自动重新聚类锚框你也可以用仓库里的 kmeans 脚本先跑出自己的 anchor 再写进模型 yaml但这不是必备步骤。我自己一般先不动 anchor等训练完看 recall 再决定。5.2.1 小目标多的场景怎么调小车赛道里限速牌在远处可能只有 20×20 像素。imgsz640时它会被缩得更小模型很难学到特征。我一般把imgsz试到 800同时把batch减半。如果显存不够就裁剪原图后再训练把 1280×720 切分成左右两半分别标注和推理也能缓解小目标问题。但要注意裁剪后的样本会失去一部分上下文必要时混合全图一起训练。5.3 三个高频报错与排查路径报错一AssertionError: Label class 8 exceeds nc8。前面提过这是 txt 类别索引越界说明标注文件里出现 class 8 或更大。用第 3 章的检查脚本找出对应文件把类别映射修正。报错二This is the first time you train不是 GPU 层面的报错但说明你用了不完整的预训练权重路径模型会从头初始化。检查--weights路径是否正确。报错三CUDA out of memory。降低batch到 8 或 4或者把--workers从 8 降到 4。还不行就把imgsz降到 480。注意训练时显存占用大约是 batch 与图片大小的乘积超参数表里第一优先改 batch。5.4 训练过程中的监控与提前停止训练启动后我一般只看两个东西results.png里的mAP0.5曲线和val/obj_loss。如果val/obj_loss已经连续 20 个 epoch 不再下降就提前终止不必跑满 80 个 epoch。YOLOV5 自带学习率调度前几个 epoch 是 warmuploss 升高是正常的不要在 epoch 5 之前急着停。小车数据集比较干净时一般 30~50 个 epoch 就能收敛到不错的效果。把--patience设为 30可以自动保存最佳权重并停止。6. 从 mAP 到实车验证、导出与部署到智能小车的最后技巧6.1 先看 per-class AP而不是只看整体 mAP训练结束后用val.py评估验证集# 用 best.pt 评估验证集输出每个类别的 AP python val.py --data datasets/traffic8/data.yaml --weights runs/train/traffic8_run/weights/best.pt --img 640--data指向验证时使用的类别配置--weights指向训练产物--img必须和训练时的输入尺寸一致。输出里除了整体 mAP还会列出每个类别的 AP。交通指示牌和锥桶的 AP 差距如果超过 15 个百分点说明少样本类别没学好。我的做法不为拉高整体 mAP 去刻意增强多数类别而是单独给低 AP 类别补样本或调权重。6.2 导出 ONNX 时需要固定输入尺寸小车端推理我常用 Jetson Nano 或树莓派一般不用 PyTorch 权重而是导出成 ONNX 或 TorchScript。导出时注意--img 640要和训练分辨率一致。如果不一致边界框坐标会出现系统性偏移因为 YOLO 输出坐标是相对输入图片的归一化值。# 导出 ONNX输入尺寸与训练保持一致 python export.py --weights best.pt --include onnx --img 6406.3 部署时的 letterbox 必须与训练保持一致小车摄像头画面是 1280x720训练用了 640x640推理时如果不做 letterbox 直接把画面 resize 到 640x640检测框会整体偏移。我一般复用 YOLOV5 仓库里的letterbox函数并保留 padding 信息还原到原图坐标时减掉 padding 再按比例放大。这个小细节是实车检测框漂移最常见的来源。6.4 验证类别 ID 没有被搞乱最后一个小技巧拿 5 张已标注的验证集图片跑一次检测# 用验证过的配置文件跑检测观察输出的类别编号 python detect.py --weights best.pt --source test_images/ --data data.yaml不要只看画框把输出类别和 data.yaml 的 names 顺序对比一遍。--source指定图片目录--data指向同一个 yaml 可以避免 names 错位。如果 class 0 的 stop_line 被显示成别的名字通常是推理脚本加载的 names 和训练时的 names 不一致。实测里这个错位经常出现在你手动改了 names 但忘记同步重标文件时回归测试能立刻暴露问题。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

智能计算系统ZIP:带签名与互操作能力的AI可执行部署包 2026/9/16 6:16:03

智能计算系统ZIP:带签名与互操作能力的AI可执行部署包

简介:本资源是面向Python初学者与AI入门学习者的「智能计算系统」综合实践包,聚焦数据处理、机器学习与深度学习全流程开发能力培养,适用于高校课程实训、自学进阶及项目原型开发。压缩包共67个文件,含24个可运行Python脚本&#…

阅读更多 →
Gemini 3.1 Pro多模态大模型架构与应用解析 2026/9/16 6:16:03

Gemini 3.1 Pro多模态大模型架构与应用解析

1. Gemini 3.1 Pro技术架构解析作为Google DeepMind团队最新推出的多模态大模型,Gemini 3.1 Pro在架构设计上采用了混合专家系统(MoE)与密集计算相结合的创新方案。其核心由128个专家子网络组成,每个子网络专门处理特定类型的数据…

阅读更多 →
Qwen3.5-Max大模型技术解析与应用实践 2026/9/16 6:16:03

Qwen3.5-Max大模型技术解析与应用实践

1. Qwen3.5-Max的技术定位与行业影响Qwen3.5-Max作为阿里云千问系列的最新旗舰模型,在中文大模型评测基准C-Eval和CMMLU上均取得首位成绩。这个基于Transformer架构优化的千亿参数模型,在32K长文本理解、代码生成和数学推理等专业领域展现出明显优势。从…

阅读更多 →
YOLO格式LOGO检测数据集与小目标优化实战 2026/9/16 6:16:03

YOLO格式LOGO检测数据集与小目标优化实战

简介:本资源是一份面向深度学习初学者与目标检测实践者的轻量级商品LOGO图像数据集,专为YOLO系列模型训练与验证设计,适用于商品品牌识别、零售场景自动化检测等实际任务。数据集共1403个文件,包含700张JPG格式图像(训…

阅读更多 →
YOLOv8训练托盘检测数据集:从解压到部署全流程 2026/9/16 6:16:03

YOLOv8训练托盘检测数据集:从解压到部署全流程

简介:面向仓库管理、物流自动化和目标检测学习者的托盘检测专用数据集,同时提供VOC与YOLO两种主流标注格式,可直接用于YOLO、Faster R-CNN、SSD等模型训练、验证与性能对比,解决仓库托盘识别场景的数据集准备问题。压缩包约192.54…

阅读更多 →
车载测试培训避坑指南:以太网与网络管理才是核心 2026/9/16 6:13:03

车载测试培训避坑指南:以太网与网络管理才是核心

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

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞