基于BDD100K数据集的目标检测实战:从数据预处理到模型优化

1次阅读
没有评论

共计 2305 个字符,预计需要花费 6 分钟才能阅读完成。

image.webp

1. BDD100K 数据集特性分析

BDD100K 是当前最大的自动驾驶场景数据集之一,包含 10 万张高清图像(1280×720 分辨率),覆盖多种天气条件(晴天、雨天、雾天)、光照变化(白天 / 夜晚)和复杂道路场景(城市 / 高速 / 乡村)。其标注格式采用 JSON,包含以下关键特性:

基于 BDD100K 数据集的目标检测实战:从数据预处理到模型优化

  • 多样化标注类型:同时支持 2D 框、实例分割、车道线检测等多任务标注
  • 复杂对象分布:包含车辆(car)、行人(pedestrian)、交通标志(traffic sign)等 10 个类别,其中小目标占比高达 32%
  • 特殊挑战场景:包含大量遮挡、截断和模糊对象,约 15% 的标注存在重叠现象

实际使用时需特别注意:原始 JSON 中的坐标采用 [x1,y1,x2,y2] 格式,但 YOLO 系列需要归一化的中心坐标(cx,cy,w,h)

2. 数据预处理实战

2.1 JSON 标注解析

核心代码片段(PyTorch 实现):

import json
from pathlib import Path

def convert_bdd_to_yolo(json_path, output_dir):
    with open(json_path) as f:
        data = json.load(f)

    for item in data:
        img_name = Path(item['name']).stem
        txt_path = output_dir / f"{img_name}.txt"

        with open(txt_path, 'w') as f_txt:
            for label in item['labels']:
                if 'box2d' not in label: continue

                # 坐标转换逻辑
                x1, y1 = label['box2d']['x1'], label['box2d']['y1']
                x2, y2 = label['box2d']['x2'], label['box2d']['y2']

                # 归一化处理
                cx = (x1 + x2) / 2 / 1280
                cy = (y1 + y2) / 2 / 720
                w = (x2 - x1) / 1280
                h = (y2 - y1) / 720

                # 写入 YOLO 格式
                class_id = CLASS_MAP[label['category']]
                f_txt.write(f"{class_id} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}\n")

2.2 类别不平衡处理

针对行人样本较少的问题,推荐两种解决方案:

  1. 过采样(Oversampling):复制包含行人的图像样本
  2. 损失函数加权 :在 YOLOv5 中修改model.yamlclass_weights参数

3. 模型选型对比

模型 mAP@0.5 FPS (Tesla V100) 显存占用
Faster R-CNN 42.1 18 6.2GB
YOLOv5s 39.7 95 2.1GB
YOLOv5x 47.3 32 8.4GB

实验表明:YOLOv5 在速度 - 精度权衡上表现最优,适合车载设备部署。

4. YOLOv5 实现细节

4.1 关键训练配置

修改data/bdd100k.yaml

train: ../bdd100k/images/train
val: ../bdd100k/images/val

nc: 10  # 类别数
names: ['pedestrian', 'rider', 'car', 'truck', 'bus', 'train', 'motorcycle', 'bicycle', 'traffic light', 'traffic sign']

4.2 自定义数据加载

重写 dataset.pyLoadImagesAndLabels类,增加对夜间图像的增强:

class BDD100KDataset(LoadImagesAndLabels):
    def __init__(self, ..., augment_night=True):
        self.augment_night = augment_night

    def __getitem__(self, index):
        img, labels = super().__getitem__(index)

        # 夜间图像增强
        if self.augment_night and is_night_image(self.img_files[index]):
            img = adjust_gamma(img, gamma=1.5)  # 亮度提升

        return img, labels

5. 性能优化技巧

5.1 多尺度训练

train.py 中设置:

parser.add_argument('--multi-scale', action='store_true', help='vary img-size +/- 50%')

5.2 困难样本挖掘

使用 Focal Loss 替换标准交叉熵:

# 修改 loss.py
class FocalLoss(nn.Module):
    def __init__(self, alpha=0.25, gamma=2.0):
        super().__init__()
        self.alpha = alpha
        self.gamma = gamma

6. 避坑指南

6.1 常见错误处理

  • 标注错误 :约 3% 的标注存在框体不准确问题,建议使用labelImg 工具手动修正
  • 内存溢出:当 batch_size>16 时可能出现,解决方案:
  • 使用梯度累计(--accumulate 2
  • 启用混合精度训练(--fp16

6.2 分布式训练建议

python -m torch.distributed.launch --nproc_per_node 4 train.py --sync-bn

开放性问题

当前模型在极端天气(如暴雨、浓雾)下的检测性能下降明显:
– 如何利用 GAN 生成对抗样本提升鲁棒性?
– 是否需要针对不同天气条件训练专用子模型?
– 多模态融合(雷达 + 视觉)是否是更优解?

期待读者在实践中探索这些方向,也欢迎分享你的解决方案。

正文完
 0
评论(没有评论)