共计 3378 个字符,预计需要花费 9 分钟才能阅读完成。
一、BDD100K 数据集背景与价值
BDD100K 是由加州大学伯克利分校发布的自动驾驶领域大规模数据集,包含 10 万张高清行车视频帧(1280×720 分辨率),覆盖不同天气(晴天 / 雨天 / 雪天)、时段(白天 / 夜间)和驾驶场景(城市 / 高速 / 乡村)。其标注体系包含:

- 目标检测(100k 图像,8 类物体)
- 语义分割(10k 图像,19 类标签)
- 车道线检测(100k 图像)
- 可驾驶区域分割(10k 图像)
该数据集因场景多样性和标注完整性,成为自动驾驶算法研发的基准测试集,在 CVPR、ICCV 等顶会论文中频繁出现。
二、数据集结构深度解析
解压后的目录结构如下:
bdd100k/
├── images/ # 原始图像
│ ├── train/ # 训练集(70k)│ ├── val/ # 验证集(10k)│ └── test/ # 测试集(20k)└── labels/ # JSON 标注文件
├── train.json
└── val.json
标注文件采用 COCO 风格 JSON 格式,关键字段说明:
{
"name": "b1c66a42-6f7d68ca.jpg",
"attributes": {
"weather": "rainy", # 天气标签
"scene": "highway", # 场景标签
"timeofday": "day" # 时间段
},
"labels": [
{
"category": "car",
"box2d": {"x1": 712.4, "y1": 521.3, "x2": 810.2, "y2": 562.7},
"occluded": false # 是否被遮挡
}
]
}
三、PyTorch 数据加载实战
1. 自定义 Dataset 实现
import torch
from torch.utils.data import Dataset
import json
from PIL import Image
class BDD100KDataset(Dataset):
def __init__(self, image_dir, label_path, transform=None):
self.image_dir = image_dir
with open(label_path) as f:
self.labels = json.load(f)
self.transform = transform
# 类别 ID 映射(示例)self.class_map = {"car":0, "person":1, "traffic light":2}
def __len__(self):
return len(self.labels)
def __getitem__(self, idx):
label_info = self.labels[idx]
img_path = os.path.join(self.image_dir, label_info["name"])
image = Image.open(img_path).convert("RGB")
# 解析标注
boxes, classes = [], []
for obj in label_info["labels"]:
if "box2d" in obj: # 只处理目标检测标注
box = [obj["box2d"]["x1"], obj["box2d"]["y1"],
obj["box2d"]["x2"], obj["box2d"]["y2"]]
boxes.append(box)
classes.append(self.class_map[obj["category"]])
# 转换为 Tensor
boxes = torch.tensor(boxes, dtype=torch.float32)
classes = torch.tensor(classes, dtype=torch.int64)
if self.transform:
image = self.transform(image)
return image, {"boxes": boxes, "labels": classes}
2. 数据增强策略
推荐使用 Albumentations 库处理目标检测任务:
import albumentations as A
train_transform = A.Compose([A.HorizontalFlip(p=0.5),
A.RandomBrightnessContrast(p=0.2),
A.Resize(height=640, width=960), # 适当降低分辨率
A.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225))
], bbox_params=A.BboxParams(format="pascal_voc", label_fields=["class_labels"]))
四、YOLOv3 训练示例
1. 模型适配
修改 YOLO 的 anchor 配置(BDD100K 目标尺寸统计):
# 在 config/yolov3.cfg 中调整 anchors
[anchors]
10,13, 16,30, 33,23 # 小目标
30,61, 62,45, 59,119 # 中目标
116,90, 156,198, 373,326 # 大目标
2. 训练循环关键代码
dataset = BDD100KDataset("bdd100k/images/train", "bdd100k/labels/train.json")
dataloader = DataLoader(dataset, batch_size=16, shuffle=True, collate_fn=collate_fn)
for epoch in range(50):
for imgs, targets in dataloader:
imgs = imgs.to(device)
# 转换 target 格式为 YOLO 所需
yolo_targets = convert_to_yolo_format(targets)
optimizer.zero_grad()
loss = model(imgs, yolo_targets)
loss.backward()
optimizer.step()
五、避坑指南
1. 标注问题处理
-
错误标注识别:使用可视化工具检查(如 labelImg)
def show_annotations(image, boxes): plt.imshow(image) ax = plt.gca() for box in boxes: rect = patches.Rectangle((box[0],box[1]), box[2]-box[0], box[3]-box[1], linewidth=2, edgecolor='r', facecolor='none') ax.add_patch(rect) -
常见问题:
- 部分遮挡物体标注不完整(需手动补全)
- 远处小物体漏标(建议过滤像素面积 <20 的框)
2. 内存优化技巧
- 分块加载 :使用
torch.utils.data.Subset分割大数据集 - 延迟加载 :在
__getitem__中读取图像而非__init__ - 梯度累积:小 batch 训练时设置
accumulation_steps
3. 多 GPU 训练策略
# 使用 DistributedDataParallel
model = torch.nn.parallel.DistributedDataParallel(
model,
device_ids=[local_rank],
output_device=local_rank
)
# 数据分片
sampler = torch.utils.data.distributed.DistributedSampler(dataset)
dataloader = DataLoader(dataset, sampler=sampler)
六、进阶思考
- 如何利用 BDD100K 的场景属性(天气 / 时间段)提升模型鲁棒性?
- 对比 COCO 格式,BDD100K 的 JSON 标注设计有哪些优缺点?
- 当处理 4K 分辨率图像时,如何优化检测模型的计算效率?
实验环境复现
pip install torch==1.12.0+cu113 torchvision==0.13.0+cu113
pip install albumentations opencv-python matplotlib
# 推荐使用 RTX 3060 及以上显卡
通过本文的实践,你应该能够快速搭建基于 BDD100K 的目标检测 Pipeline。建议先从验证集抽取 1000 张样本快速验证流程,再扩展到全量数据训练。
正文完
