1. 环境准备与数据集获取
第一次接触BDD100K数据集时,我被它10万张标注图像的规模震撼到了。这个由伯克利大学发布的驾驶场景数据集,包含了丰富的天气、光照和道路条件变化,是训练自动驾驶模型的绝佳素材。但当我兴冲冲下载完数据准备用YOLOv5训练时,发现标注格式不兼容——这就像买了进口电器却发现插头不匹配,需要个"转换器"才能用。
先解决环境问题。我强烈建议使用conda创建独立环境,避免包版本冲突。实测Python 3.8最稳定,太新的版本可能遇到依赖问题:
conda create -n bdd2yolo python=3.8 conda activate bdd2yolo接着从GitHub克隆官方工具库。这里有个坑:不要直接pip安装bdd100k包,而是克隆整个仓库,因为格式转换脚本在tools目录下:
git clone https://github.com/bdd100k/bdd100k.git cd bdd100k pip install -r requirements.txt数据集下载建议用官方提供的torrent文件,速度比直接下载快3倍。解压后你会看到这样的目录结构:
- images/ - 包含100k图片(注意train/val/test分目录存放)
- labels/ - JSON格式的标注文件(det_20/det_train.json等)
2. BDD100K转COCO格式详解
BDD100K原生使用自定义JSON格式,而YOLO需要的是每张图片对应的txt标注文件。直接转换就像把中文小说翻译成英文诗,需要先转成"通用语"COCO格式。官方提供的to_coco.py脚本就是干这个的。
转换时要注意几个关键参数:
-m det指定目标检测任务(还有seg分割任务)--nproc 4使用4个进程加速(根据CPU核心数调整)-i输入JSON路径要写绝对路径,相对路径容易报错
完整命令示例:
python -m bdd100k.label.to_coco -m det \ -i "/data/bdd100k/labels/det_20/det_train.json" \ -o "/output/det_train_coco.json" \ --nproc 4转换过程中可能会遇到两个典型问题:
- 内存不足:处理10万级数据时建议32GB以上内存,否则可以分批次处理
- 类别映射错误:BDD100K的原始类别如"traffic light"会被映射为COCO的"traffic light"类别ID(注意不是所有类别都能完美对应)
转换完成后,检查生成的COCO格式JSON文件应该包含:
{ "images": [{"id": 0, "file_name": "xxx.jpg", ...}], "annotations": [{"image_id": 0, "bbox": [x,y,w,h], ...}], "categories": [{"id": 0, "name": "person"}, ...] }3. COCO转YOLO格式全流程
现在来到重头戏——把COCO的JSON变成YOLO需要的txt。YOLO格式的特点是:
- 每个图片对应一个同名txt文件
- 每行表示一个物体:[class_id] [x_center] [y_center] [width] [height]
- 所有坐标都是归一化后的相对值(0~1之间)
我写了两个版本的转换脚本,区别主要在处理精度上:
基础版(适合快速验证):
import json import os coco_json = "/path/to/det_train_coco.json" output_dir = "/path/to/yolo_labels" with open(coco_json) as f: data = json.load(f) for img in data['images']: txt_path = os.path.join(output_dir, img['file_name'].replace('.jpg', '.txt')) with open(txt_path, 'w') as f: for ann in [a for a in data['annotations'] if a['image_id']==img['id']]: # 坐标转换逻辑 x,y,w,h = ann['bbox'] x_center = (x + w/2) / img['width'] y_center = (y + h/2) / img['height'] f.write(f"{ann['category_id']} {x_center:.6f} {y_center:.6f} {w/img['width']:.6f} {h/img['height']:.6f}\n")增强版增加了这些特性:
- 多线程处理加速大文件转换
- 自动创建不存在的目录
- 更完善的错误处理(如图片宽高为0的情况)
- 支持保留原始文件名映射
实测发现,小数点后保留6位足够用,更多位数不会提升模型精度,反而增加存储负担。转换完成后,检查生成的txt文件应该类似这样:
2 0.548923 0.712345 0.123456 0.078901 0 0.312345 0.498765 0.056789 0.1234564. 验证与调试技巧
转换完成后千万别直接开训模型!我吃过这个亏——因为格式错误导致模型学到的全是噪声。推荐三个验证方法:
方法一:可视化检查用OpenCV绘制标注框是最直观的:
import cv2 img = cv2.imread("image.jpg") h,w = img.shape[:2] with open("label.txt") as f: for line in f: cls, x,y,w,h = map(float, line.split()) # 转换回绝对坐标 x1 = int((x - w/2)*w) y1 = int((y - h/2)*h) x2 = int((x + w/2)*w) y2 = int((y + h/2)*h) cv2.rectangle(img, (x1,y1), (x2,y2), (0,255,0), 2) cv2.imshow("check", img) cv2.waitKey(0)方法二:统计验证检查类别分布是否合理:
# 统计每个类别的实例数 find labels/ -name "*.txt" | xargs cat | awk '{print $1}' | sort | uniq -c方法三:YOLO预校验用YOLO官方提供的验证脚本:
python yolov5/val.py --data data.yaml --weights yolov5s.pt --task study常见问题排查:
- 坐标越界:所有坐标值应该在0-1之间,如果出现1.2或-0.1说明转换有误
- 类别ID不连续:YOLO要求类别ID从0开始连续编号
- 标注文件缺失:检查每张图片是否都有对应的txt文件
5. 高效训练配置建议
完成格式转换后,给几个让YOLO训练更高效的建议:
数据配置:
# data.yaml train: ../bdd100k/images/train val: ../bdd100k/images/val nc: 10 # 根据你的类别数修改 names: ['person', 'car', 'traffic light', ...] # 与转换时的类别顺序一致训练参数优化:
- 输入分辨率建议640x640(BDD100K原始图像是1280x720)
- batch-size根据GPU显存调整(11G显存可设batch=16)
- 启用马赛克增强能显著提升小物体检测效果
python yolov5/train.py \ --img 640 \ --batch 16 \ --epochs 50 \ --data ./data.yaml \ --cfg yolov5s.yaml \ --weights yolov5s.pt \ --hyp hyp.scratch-low.yaml如果遇到显存不足,可以:
- 减小batch-size
- 使用--adam优化器替代SGD
- 启用梯度累积(--accumulate 2)
转换后的数据集在YOLOv5上训练时,预期mAP@0.5应该能达到:
- 小模型(YOLOv5s):约35-40%
- 大模型(YOLOv5x):约45-50%