ARTICLE DETAIL

资讯详情

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

YOLOV5数据集格式详解:自动驾驶目标检测的数据校验与训练实践

YOLOV5数据集格式详解:自动驾驶目标检测的数据校验与训练实践 简介面向自动驾驶目标检测任务的现成数据集包按YOLOv5目录格式整理可直接投入训练与验证省去数据格式转换与清洗步骤。数据内容覆盖卡车、行人、交通信号灯等11个常见道路类别图像为512×512 RGB图每张含多目标边界框标注清晰图像内容完整适合自动驾驶感知、密集目标检测等场景。资源共2000个文件以txt标签为主1999个另有1个可视化脚本py标签文件与图片一一对应训练集21031张、验证集5266张并分别存放于 datasets-images-train 与 datasets-images-val 分目录中同时附有11类别对应的txt信息文件压缩包约493MB开箱即用。包内另附类别文本文件与可视化脚本运行后即可在随机图片上绘制边界框并保存结果方便快速核查标注质量。目前已有173人学习下载适合需要高性价比数据支撑的目标检测练手或项目验证。1. 拿到一份YOLOV5目录格式的自动驾驶目标检测数据集先别急着训练做大型自动驾驶道路信息检测时我拿到一份YOLOV5目录格式的目标检测数据集11个类别训练集、验证集都齐了——很多人觉得这就能直接yolo train跑模型了。真跑起来就会意识到数据集本身的坑比模型结构多得多标签索引是不是从 0 开始、坐标有没有归一化、训练集和验证集有没有按场景切干净、小目标类别占比是不是低到让模型直接放弃。这份数据集的目录格式是对的但格式对不等于训练顺利。这篇文章按我自己的实践顺序拆解先讲清 YOLOV5 目录格式的每条规则再讲训练集和验证集怎么划分、怎么校验、真正训练时会踩哪些坑最后落到怎么验证这份数据集到底值不值得投入。2. 拆开 YOLOV5 目录格式目录结构、标签编码与 11 类映射2.1 目录结构images/labels 的配对规则与 train/val 划分YOLOV5 的目录格式不是随便把图片和 txt 放在一起就行。标准做法是项目根目录下分images和labels两个主目录各自内部再按train、val分子目录图片和标签的文件名必须完全一致只是扩展名不同例如img_0001.jpg对应img_0001.txt。yolov5 官方仓库里找数据时也是这个标准结构做目标检测数据集转换的第一步就是对齐这个格式。autopilot-dataset/ ├── images/ │ ├── train/ # 训练集图片 │ └── val/ # 验证集图片 ├── labels/ │ ├── train/ # 训练集标签 │ └── val/ # 验证集标签 ├── data.yaml # 类别名与路径配置 └── classes.txt # 类别清单辅助文件我一般会在根目录再放一个classes.txt内容就是 11 个类别的名字每一行一个。它不是 YOLOV5 训练必需的文件但后面写data.yaml、做标签校验、重新聚类 anchor 时都要用提前准备能省不少事。需要注意images和labels的文件配对是按文件名 strict 匹配的任何一方多出一个文件都不会报错只会导致那个样本被静默跳过这是后面要重点排查的问题。2.2 标签编码归一化坐标、类别索引从 0 开始YOLO 系列的标签格式每行代表一个目标框共五项class x_center y_center width height。这里的x_center、y_center、width、height全部是相对图像宽度和高度的比值取值范围在 0 到 1 之间。这与 COCO 的像素坐标格式有本质区别把 COCO 或 VOC 格式转换成 YOLO 格式是必经步骤转换公式如下。x_center (x_min x_max) / 2 / image_widthy_center (y_min y_max) / 2 / image_heightwidth (x_max - x_min) / image_widthheight (y_max - y_min) / image_height其中x_min、y_min、x_max、y_max是像素坐标。跑这段转换逻辑时有一个关键点类别索引必须从 0 开始不能从 1 开始。项目里类别索引一旦错位训练不会报错但模型会把car学成pedestrian验证时 mAP 看起来还行实际推理全乱属于最隐蔽的坑。所以我拿到数据集第一件事就是用脚本扫描所有标签文件确认类别索引的范围是 0 到 10而不是 1 到 11。2.3 11 类自动驾驶目标怎么映射到类别索引落实这份数据集之前先建一张类别映射表。11 个类别在自动驾驶场景里的常见构成大概是car、truck、bus、motorcycle、bicycle、pedestrian、rider、traffic_light、traffic_sign、stop_sign、lane_marker 这类组合。具体类别名以数据集实际标注为准我按常见做法列出映射关系索引类别名典型尺寸规模说明0car中轿车、SUV数量最多1truck大货车、挂车2bus大公交车3motorcycle小摩托车4bicycle小自行车5pedestrian小行人6rider小骑手含摩托车/自行车骑手7traffic_light极小红绿灯远距离时很小8traffic_sign小交通标志牌9stop_sign小停车让行标志10lane_marker极小车道线标记细长形这 11 类里traffic_light和lane_marker是小目标的重灾区。远距离红绿灯在 640×640 分辨率下可能只有 10×10 像素模型在小目标上先天劣势。这也是为什么后面要谈训练分辨率、anchor 重聚类和数据增强策略这三件事都和类别特性强相关。2.4 为什么自动驾驶数据集偏爱 YOLOV5 目录格式而不是 COCO/VOC目标检测数据集的常见格式有 COCO 的 JSON、VOC 的 XML、YOLO 的 txt 三类。自动驾驶场景下我倾向于用 YOLOV5 目录格式原因在于标签读取效率。COCO 的 JSON 有几十 MB 到上百 MB每次 dataloader 启动都要解析整个文件训练时读样本也要查字典VOC 的 XML 是单个文件一个目标框列表标注繁琐但读取不算慢可它的标签层级结构对自动驾驶这种大量重叠目标不友好。YOLO 的 txt 格式是纯文本一行一个目标读取零解析成本配合images/labels的目录结构dataloader 能随机访问任意样本不需要维护全局索引。对自动驾驶这种动辄几万张图片、每张十几个目标的数据集训练时 IO 效率直接影响迭代速度。YOLOV5 目录格式另一个好处是切分方便train/val就是两个目录换比例或换场景子集时只需移动文件不需要重新生成 JSON。数据增强工具如 mosaic、mixup 的实现也天然适配这种格式。数据可视化、边界框检查、训练集成、推理演示这些环节我都用 YOLOV5 目录格式作为事实标准。3. 训练集与验证集划分比例、划分策略和数据分布检查3.1 按场景划分还是按帧随机划分自动驾驶数据的特殊性很多人划分训练集和验证集时直接对所有图片做随机抽样比如 8:2 分割这在自动驾驶数据集上是错误做法。自动驾驶数据通常来自连续视频帧相邻帧之间高度相似如果同一段视频的前后帧被随机分到训练集和验证集验证集相当于在做开卷考试——模型见过几乎一样的画面指标虚高部署到真实场景立刻打回原形。正确做法是按场景或按视频序列 ID 划分。数据集如果带序列 ID 字段就按序列划分如果没有就按文件名前缀划分。假设文件名是seq_001_frame_0001.jpg这种格式提取seq_001作为分组键同一组内的所有帧必须全部进入同一个集合。我通常会把 80% 的场景进训练集、20% 的场景进验证集而不是按图片数量直接切分这样验证集的指标才有参考意义。3.2 写一个划分脚本按文件收集、场景分组、输出图片与标签下面是我常用的按场景 ID 划分脚本核心是先用os.walk收集图片路径再提取场景 ID最后用train_test_split以场景为单位切分。注意脚本要保证images/train、images/val、labels/train、labels/val四个目录的内容同步移动图片复制过去标签也必须对应复制否则会出现图片有标签、标签无图片的错位。import os import shutil from collections import defaultdict from sklearn.model_selection import train_test_split src_images raw_data/images src_labels raw_data/labels dst_dir autopilot_dataset train_ratio 0.8 # 收集所有图片文件 image_paths [] for root, _, files in os.walk(src_images): for file in files: if file.lower().endswith((.jpg, .jpeg, .png)): image_paths.append(os.path.join(root, file)) # 按文件名前缀提取场景ID例如 seq_001_frame_0001.jpg - seq_001 def get_scene_id(path): fname os.path.basename(path) # 按数据集的命名规律调整分割规则 return fname.split(_frame_)[0] scene_to_images defaultdict(list) for img_path in image_paths: scene_id get_scene_id(img_path) scene_to_images[scene_id].append(img_path) scene_ids list(scene_to_images.keys()) train_scenes, val_scenes train_test_split( scene_ids, train_sizetrain_ratio, random_state42 ) # 按场景切分并复制到目标目录 for split_name, scene_list in [(train, train_scenes), (val, val_scenes)]: for scene_id in scene_list: for img_path in scene_to_images[scene_id]: label_path img_path.replace(src_images, src_labels).rsplit(., 1)[0] .txt dst_img os.path.join(dst_dir, images, split_name, os.path.basename(img_path)) dst_lbl os.path.join(dst_dir, labels, split_name, os.path.basename(label_path)) os.makedirs(os.path.dirname(dst_img), exist_okTrue) os.makedirs(os.path.dirname(dst_lbl), exist_okTrue) shutil.copy2(img_path, dst_img) shutil.copy2(label_path, dst_lbl)逻辑说明先收集所有图片路径按场景 ID 分组再对场景 ID 做随机划分。这样划分的最小单位是场景而不是单张图片验证集中的任何帧都不会在训练集中出现同场景画面。random_state42固定随机种子保证重复执行划分结果一致这在我反复调试时很重要否则每次跑训练验证集都变结果无法对比。参数说明train_ratio控制训练集比例一般取 0.8数据量少可以提到 0.85 或 0.9。get_scene_id函数里的分割规则需要按数据集的命名格式调整如果文件名是20240101_123456_01.jpg这种时间戳格式就直接取整段前缀。还要注意标签路径的替换逻辑img_path.replace(src_images, src_labels)要求图片与标签目录结构对称如果不对称需要单独映射。3.3 类别分布统计脚本统计每类框数发现类别不平衡划分完成后第一件事不是训练而是统计类别分布。自动驾驶数据集的类别分布极不均衡car可能占一半以上stop_sign可能只有几百个框。YOLOV5 的损失函数默认对每个类别一视同仁类别不平衡会导致少样本类别几乎学不出来。统计脚本可以直接解析每个 txt 文件的第一列。import os from collections import Counter label_dirs [autopilot_dataset/labels/train, autopilot_dataset/labels/val] class_counter Counter() for label_dir in label_dirs: for label_file in os.listdir(label_dir): if not label_file.endswith(.txt): continue with open(os.path.join(label_dir, label_file), r) as f: for line in f: line line.strip() if not line: continue class_id int(line.split()[0]) class_counter[class_id] 1 for class_id in sorted(class_counter.keys()): print(fclass {class_id}: {class_counter[class_id]} boxes)逻辑说明遍历所有标签文件读取每一行的第一个字段作为类别索引累加计数。Counter会按类别自动聚合。打印结果后对照映射表如果发现某个类别的框数比其他少一个数量级训练前就要处理。参数说明这个脚本是纯读取不修改数据。如果类别不平衡严重常见做法是给 YOLOV5 的data.yaml中的类别配置权重或者在训练时开启针对少样本的过采样。但更稳妥的做法是直接增加该类别的数据量因为权重提升容易让模型对多数的误检率上升。少样本类别如stop_sign框数低于 1000 时我会优先考虑补数据而不是调权重。3.4 data.yaml 的写法路径、类别名与索引保持一致data.yaml是 YOLOV5 训练的入口配置路径写错或类别索引不匹配都会直接导致训练失败或学错。YOLOV5 目录格式下的data.yaml基本结构如下。path: ../autopilot_dataset train: images/train val: images/val nc: 11 names: 0: car 1: truck 2: bus 3: motorcycle 4: bicycle 5: pedestrian 6: rider 7: traffic_light 8: traffic_sign 9: stop_sign 10: lane_markerpath是相对data.yaml文件的上一级目录路径train和val是相对于path的目录。nc是类别总数必须与实际类别数一致。names字典的 key 和标签文件里的 class 索引必须一一对应顺序不能错。有一个容易被忽略的点path配置写绝对路径时换电脑训练就会失效我习惯用相对路径配合在工作目录下启动训练命令这样整个项目可以迁移到另一台机器直接跑。4. 训练前必须做的三件校验图像、标签、配对关系4.1 坏图与截断图检测PIL 验证 SHA 校验训练集图片来自采集车或公开道路数据集下载、压缩、传输过程都可能产生损坏图片。YOLOV5 的 dataloader 读图失败时通常不会中断训练而是跳过该样本但如果坏图占比超过 1%实际训练样本数就和配置对不上影响收敛效果。我用 PIL 做基础验证再配合文件大小过滤。from PIL import Image import os img_dir autopilot_dataset/images/train bad_images [] for img_file in os.listdir(img_dir): if not img_file.lower().endswith((.jpg, .jpeg, .png)): continue img_path os.path.join(img_dir, img_file) try: with Image.open(img_path) as img: img.verify() # 检查文件完整性 # 额外验证分辨率 width, height img.size if width 32 or height 32: bad_images.append((img_path, too_small)) except Exception as e: bad_images.append((img_path, str(e))) for path, reason in bad_images: print(fBAD: {path} - {reason})逻辑说明img.verify()会读取文件的解码结构遇到截断或损坏会抛异常比单纯检查文件大小可靠。文件实际上能打开但分辨率过低的图片也要过滤因为 YOLOV5 在训练时会将图片 resize 到 640×640一张 20×20 的图片会被拉伸到严重失真模型学到的是噪声。参数说明分辨率阈值 32×32 是我常用的下限具体取决于你的img_size训练参数。YOLOV5 的 mosaic 增强会拼接四张图如果一张图过小mosaic 增强时拉大变形的程度会很夸张。灰度图不需要过滤YOLOV5 的 dataloader 会自动转成三通道但如果你发现灰度图占比过高建议检查数据来源是否采集出了问题。4.2 标签内容合法性校验坐标范围、越界、重复框YOLO 标签里五个字段都是浮点数类别索引应为整数中心点坐标和宽高都应满足约束条件。我见过不少标签文件里的坐标小于 0 或大于 1原因多是标注工具导出时未归一化、或者在转换脚本里把长边除以了宽边。这类数据直接训练会导致 loss 不收敛或精度极差。下面这个脚本能找出所有非法标签。import os label_dirs [autopilot_dataset/labels/train, autopilot_dataset/labels/val] errors [] for label_dir in label_dirs: for label_file in os.listdir(label_dir): if not label_file.endswith(.txt): continue label_path os.path.join(label_dir, label_file) with open(label_path, r) as f: lines f.readlines() if len(lines) 0: errors.append((label_path, empty_file)) continue seen_boxes set() for line_num, line in enumerate(lines): parts line.strip().split() if len(parts) ! 5: errors.append((label_path, fline {line_num}: field_count ! 5)) continue try: cls int(float(parts[0])) x_c, y_c, w, h map(float, parts[1:]) except ValueError: errors.append((label_path, fline {line_num}: non-numeric value)) continue if cls 0 or cls 10: errors.append((label_path, fline {line_num}: class index {cls} out of range)) if not (0 x_c 1 and 0 y_c 1 and 0 w 1 and 0 h 1): errors.append((label_path, fline {line_num}: coord out of range)) # 检查重复框类别坐标完全一致 box_key (cls, round(x_c, 6), round(y_c, 6), round(w, 6), round(h, 6)) if box_key in seen_boxes: errors.append((label_path, fline {line_num}: duplicate box)) seen_boxes.add(box_key) for path, msg in errors: print(fINVALID: {path} - {msg}) print(ftotal errors: {len(errors)})逻辑说明逐行解析每个标签文件验证字段数量、数值类型、类别范围、坐标范围。坐标等于 0 的宽度或高度是无效的因为模型无法学习到零大小的目标。重复框做精确匹配对比标注工具在合并多次标注结果时容易产生完全一样的重复行重复框会让模型对同一个目标重复计算损失导致对该目标的预测置信度异常偏高。参数说明类别索引范围cls 10要按你数据集的类别数调整。坐标范围校验中x_c 0合法但width 0非法需要区分。如果文件里只有一行0.5 0.5 0.1 0.1这种坐标但宽高为 0就是标注工具导出问题这种文件训练时不会报错只会默默影响那个样本的 loss。4.3 图像与标签配对检查找出未配对文件配对检查是训练前最容易被跳过的步骤。YOLOV5 的 dataloader 在加载时会先查找同名标签文件找不到就跳过该图或该标签。如果 labels 目录里的文件名与 images 不对应错误不会报出来训练日志里的样本数会变少。import os images_train set(os.listdir(autopilot_dataset/images/train)) labels_train set(os.listdir(autopilot_dataset/labels/train)) img_stems {os.path.splitext(f)[0] for f in images_train} lbl_stems {os.path.splitext(f)[0] for f in labels_train} missing_labels img_stems - lbl_stems missing_images lbl_stems - img_stems if missing_labels: print(fimages without labels: {len(missing_labels)}) for s in list(missing_labels)[:10]: print(f {s}) if missing_images: print(flabels without images: {len(missing_images)}) for s in list(missing_images)[:10]: print(f {s}) if not missing_labels and not missing_images: print(all paired OK)逻辑说明把images/train和labels/train下的文件名去掉扩展名后取集合两个集合做差集就能找出未配对的文件。图片有标签缺失的要么补标签要么删图标签有但图片缺失的要么补图要么删标签。需要特别注意的是这个脚本只检查 train 目录val 目录要再跑一遍。参数说明脚本本身没有参数但如果数据集按子目录组织比如images/train/daytime和images/train/night需要把os.listdir改成os.walk递归收集文件。很多自动驾驶数据集会按天气或时段分子目录但 YOLOV5 标准格式要求所有训练图片在同一个目录下下载后需要合并目录。4.4 抽帧可视化把标注框画回图像上肉眼检查偏移脚本校验只能查数值合法性标注框是否真的框住了目标要靠可视化确认。每类随机抽 20 张图把标签画回图上检查框的位置是否偏移、类别是否正确、有没有漏标注严重的图。下面这段用 OpenCV 画框的脚本可以直接跑。import cv2 import os import random label_dir autopilot_dataset/labels/val image_dir autopilot_dataset/images/val output_dir visual_check os.makedirs(output_dir, exist_okTrue) class_names [ car, truck, bus, motorcycle, bicycle, pedestrian, rider, traffic_light, traffic_sign, stop_sign, lane_marker ] colors [ (0, 255, 0), (0, 165, 255), (0, 0, 255), (255, 0, 0), (255, 255, 0), (255, 0, 255), (0, 255, 255), (128, 128, 0), (128, 0, 128), (0, 128, 128), (255, 128, 0) ] label_files random.sample(os.listdir(label_dir), min(20, len(os.listdir(label_dir)))) for label_file in label_files: stem os.path.splitext(label_file)[0] label_path os.path.join(label_dir, label_file) img_path os.path.join(image_dir, stem .jpg) if not os.path.exists(img_path): continue img cv2.imread(img_path) h, w img.shape[:2] with open(label_path, r) as f: for line in f: parts line.strip().split() if len(parts) ! 5: continue cls int(float(parts[0])) x_c, y_c, bw, bh map(float, parts[1:]) x1 int((x_c - bw / 2) * w) y1 int((y_c - bh / 2) * h) x2 int((x_c bw / 2) * w) y2 int((y_c bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), colors[cls], 2) cv2.putText( img, class_names[cls], (x1, max(0, y1 - 5)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, colors[cls], 1 ) out_path os.path.join(output_dir, stem _check.jpg) cv2.imwrite(out_path, img) print(fsaved: {out_path})逻辑说明随机抽取验证集中的 20 个标签文件读对应图片把每个归一化坐标乘以图像宽高还原成像素坐标用不同颜色画框并标注类别名。重点看三件事框是否贴住目标边缘、类别和实际目标是否匹配、有没有一张图里被重复标注或完全漏标的情况。参数说明random.sample的 20 是抽样数量类别少时可以每类固定抽固定数量保证每个类都覆盖到。颜色列表长度要大于等于类别数否则索引越界。输出目录visual_check是新建的不会覆盖原图。这一步不能省标注偏移在自动驾驶场景中尤其危险——红绿灯偏移一两个像素在 640 分辨率下还能忍但行人框偏了半个身位训练出来的模型在真车上就得误判。5. 训练集和验证集的常见翻车现场与排查清单5.1 现象训练日志显示的样本数比 images 目录文件数少第一次用这个数据集训练时启动日志里显示的train images数量比ls images/train | wc -l的数字少了几百张当时没在意后来才发现是数据里有坏图和未配对标签。YOLOV5 的 dataloader 初始化时会扫描所有图片并尝试匹配对应标签匹配失败的静默跳过不报错。原因一是 images 目录里有一些损坏或格式不被支持的图片文件二是 labels 目录里有图片找不到对应标签三是文件扩展名大小写不一致比如图片是.JPG而标签生成时用的是.jpg。解决用 4.1 的坏图检测脚本扫一遍 images用 4.3 的配对脚本比对 train 和 val 两个集合。把无法配对的图片直接移出目录不要留在原目录里否则每次训练启动日志都吓人一跳。扩展名大小写问题在 Linux 上训练时最常出现建议统一转成小写。5.2 现象loss 不下降mAP 约等于 0训练跑了 50 个 epochbox_loss 和 cls_loss 都在高位震荡验证集 mAP 接近 0这时模型实际上什么都没学到。我排查了一圈发现标签类别索引和data.yaml里的类别映射错位了。原因标签文件中的类别索引从 1 开始而 YOLOV5 的类别索引从 0 开始。比如原本应该是class 0 car但标签文件里写的是class 1 car模型把 car 当成第二类所有类别整体偏移一位。还有一种可能是data.yaml里的nc和实际类别数不一致比如nc: 11但标签文件里出现索引 11 的行超出范围的那部分样本在损失计算时行为异常。解决用 4.2 的类别范围校验脚本扫描所有标签文件看最小索引是多少、最大索引是多少。如果最小索引是 1写一个批量转换脚本把所有标签文件的第一个字段减 1。然后同步检查data.yaml的names列表顺序和标签索引一一对应。这个逻辑必须严格执行改标签或改 yaml 选一个即可但两个都改等于没改。5.3 现象小目标类别 AP 极低尤其是 traffic_light 和 lane_marker训练结束后看每个类别的 APcar、truck能到 0.8 以上但traffic_light只有 0.2lane_marker甚至几乎为 0。这不是模型的问题是数据集本身的性质决定的。原因自动驾驶场景中远距离的小目标在 640×640 分辨率下只有几个像素。YOLOV5 默认的 anchor 尺寸是针对 COCO 的通用目标设计的对微小的交通灯和车道线并不友好另外这些小目标类别样本数少在类别不平衡下模型倾向于忽略它们。解决有两步第一步在训练时把--img提高到 1280小目标在更高分辨率下像素数变多检测率明显上升代价是显存占用和训练时间增加第二步针对标签数据重新聚类 anchorYOLOV5 提供脚本自动做这件事命令是python utils/autoanchor.py --cfg yolov5s.yaml它会分析你的标签分布生成适配小目标的 anchor 集合。数据增强上我一般会调高--hsv_h和--hsv_s让模型在颜色维度更鲁棒但这对小目标的实际帮助有限主要还是分辨率和 anchor。如果数据集的类别分布统计显示小目标框数远低于其他类别也可以考虑用图像切块的方式把小目标放大后单独训练。5.4 现象验证集指标虚高部署后性能打回原形训练时验证集 mAP 0.85模型导出后到实际道路视频上一测大量漏检和误检。最开始我以为是过拟合后来排查发现验证集划分方式不对。原因训练集和验证集是从同一批视频帧里随机切分的同一段路的连续帧同时出现在两边。模型在训练时见过几乎一样的画面验证时当然表现好但面对没见过的场景就露馅。解决按 3.1 的方法重新划分以场景 ID 为最小单位。具体做法是打开原始数据看文件名如果文件名包含时间戳或场景编号直接用字符串切分提取前缀把相同前缀的帧归到同一个场景。重新划分后验证集 AP 掉到 0.7 都是正常的这个 0.7 才代表真实泛化能力。如果原始数据没有场景信息可以用图像相似度做聚类把相似度高的帧分到同一边但这实现起来复杂优先检查文件名或目录结构。5.5 现象中文路径或特殊字符导致训练中断在 Windows 上用中文用户名的电脑训练启动时报错找不到文件或者读取到一半报编码错误这在跨平台协作时尤其常见。原因YOLOV5 依赖 OpenCV 和 numpy 处理图片OpenCV 在 Windows 上对中文路径支持差标签文件里包含中文字符也会导致编码错误。Linux 服务器上如果路径里有空格或特殊符号有些 shell 命令和工具会解析出错。解决最稳妥的做法是一开始就统一规范数据集路径和文件命名只用英文字母、数字、下划线目录结构里不出现空格。如果已经有一批中文目录的文件写个脚本把文件复制到新的纯英文路径下不要直接在原目录上做重命名因为还要同步改标签文件里的路径引用。另外注意 txt 文件要用 UTF-8 编码保存不要用 Windows 默认的 GBK。这个问题会反复出现在团队协作中最好的习惯是把数据集放在服务器固定目录~/data/autopilot_dataset这种位置所有人按同一套路径规范操作。6. 训练后的验证技巧混淆矩阵与类别 AP 决定数据集的去留训练结束后验证集上的 mAP 只是门槛真正决定这份数据集值不值得投入的是验证集上每个类别的详细表现。我训练完第一件事是运行验证脚本看混淆矩阵和每类 APYOLOV5 的命令很直接。python val.py --weights runs/train/exp/weights/best.pt --data autopilot_dataset/data.yaml --img 640 --conf 0.25 --iou 0.45运行完成后runs/val/exp目录下会生成confusion_matrix.png、F1_curve.png和PR_curve.png。我重点看混淆矩阵里background那一行如果很多目标被预测成背景说明模型漏检严重如果traffic_light经常被预测成traffic_sign说明这两类特征接近且训练数据里出现频次差异太大。这些小细节直接决定下一步是加数据、调权重还是换模型结构。对数据集质量本身的评估我有一个习惯挑验证集里所有 mAP 低于 0.5 的类别单独跑一次预测把预测结果可视化出来逐张看图判断是标注问题还是数据量问题。如果发现某张图里明明有 5 个行人但标签文件里只有 2 个那份标签就是漏标需要回炉。每次拿到新的自动驾驶数据集我都会做一遍这个检查现在已经成为固定动作。最后再说一句11 类道路目标的数据集做出来后先拿 500 张图做一轮冒烟测试确认 loss 能降、mAP 不是 0再上全量训练这能帮你省下大量调试周期。希望这篇笔记对你有帮助。本文还有配套的精品资源点击获取
返回列表