Cityscapes数据集详解:从数据标注到模型训练的最佳实践

1次阅读
没有评论

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

image.webp

Cityscapes 数据集概述

Cityscapes 是自动驾驶和城市场景理解领域最权威的语义分割数据集之一,由奔驰主导采集。数据集包含:

Cityscapes 数据集详解:从数据标注到模型训练的最佳实践

  • 50 个欧洲城市的街景数据
  • 5,000 张精细标注图像(分为训练集 2,975 张、验证集 500 张、测试集 1,525 张)
  • 20,000 张粗标注图像(仅用于预训练)
  • 19 个语义类别(如道路、车辆、行人等)

该数据集特别适合开发自动驾驶系统中的场景理解模块,其挑战性在于复杂的城市场景和细粒度物体边界。

数据标注解析

官方标注使用 JSON 格式存储,每个像素对应一个标签 ID。关键点包括:

  1. 标签映射关系 :

    # 官方提供的 ID 到类别映射(部分示例)ID2LABEL = {
        0: 'unlabeled',
        7: 'road', 
        8: 'sidewalk',
        11: 'building',
        24: 'person'
    }

  2. 类别不平衡问题 :

  3. 道路类占比最高(约 30%)
  4. 交通标志等小物体占比不足 1%

  5. 标注文件结构 :

    gtFine/
    ├── train/
    │   ├── city_a/
    │   │   ├── image1_gtFine_labelIds.png  # 标签 ID 图
    │   │   └── image1_gtFine_polygons.json # 多边形标注
    ├── val/
    └── test/

数据加载实战

使用 OpenCV 和 Python 的标准加载流程:

import cv2
import numpy as np
import os

# 定义类别颜色映射(RGB 格式)COLOR_MAP = {0: (0, 0, 0),       # 未标注
    7: (128, 64, 128),  # 道路
    8: (244, 35, 232)   # 人行道
    # 其他类别...
}

def load_cityscapes_sample(img_path, label_path):
    """加载单张图像和对应标签"""
    # 读取原始图像(BGR 格式)img = cv2.imread(img_path)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # 转 RGB

    # 读取标签图(实际存储的是类别 ID)label = cv2.imread(label_path, cv2.IMREAD_GRAYSCALE)

    # 可视化:将标签 ID 转为彩色
    colored_label = np.zeros((*label.shape, 3), dtype=np.uint8)
    for id, color in COLOR_MAP.items():
        colored_label[label == id] = color

    return img, label, colored_label

模型训练技巧

在 PyTorch 中构建高效训练流程的关键步骤:

  1. 自定义 Dataset 类

    class CityscapesDataset(torch.utils.data.Dataset):
        def __init__(self, root, split='train', crop_size=(512, 1024)):
            self.images = sorted(glob(f"{root}/leftImg8bit/{split}/*/*.png"))
            self.labels = [p.replace('leftImg8bit', 'gtFine').replace('.png', '_labelIds.png') 
                           for p in self.images]
            self.crop_size = crop_size
    
        def __getitem__(self, idx):
            img, label = load_cityscapes_sample(self.images[idx], self.labels[idx])
            # 随机裁剪
            h, w = self.crop_size
            y = random.randint(0, img.shape[0] - h)
            x = random.randint(0, img.shape[1] - w)
            return img[y:y+h, x:x+w], label[y:y+h, x:x+w]

  2. 损失函数选择

  3. 推荐使用加权交叉熵损失(Weighted Cross-Entropy)
  4. 各类别权重与频率成反比

  5. 评估指标

  6. 官方使用 mIoU(平均交并比)
  7. 需忽略 ’unlabeled’ 类别

性能优化建议

数据增强策略

  • 几何变换 :
  • 随机水平翻转(p=0.5)
  • 缩放(0.5-2.0 倍)
  • 旋转(±10 度)

  • 颜色扰动 :

    def color_jitter(img):
        # 亮度、对比度、饱和度
        img = transforms.ColorJitter(
            brightness=0.2,
            contrast=0.2,
            saturation=0.2
        )(img)
        return img

处理类别不平衡

  1. 采样策略 :
  2. 过采样稀有类别图像
  3. 在损失函数中增加类别权重

  4. 联合训练 :

  5. 先用粗标注数据预训练
  6. 再用精细标注微调

避坑指南

  1. 标签 ID 混淆
  2. 错误:直接使用 PNG 图像的 RGB 值作为标签
  3. 正确:读取灰度图获取类别 ID

  4. 评估指标计算错误

  5. 必须忽略 ’unlabeled’ 类别(ID=0)
  6. 测试集需提交到官方服务器获取准确结果

  7. 内存溢出

  8. 原始图像分辨率高达 2048×1024
  9. 训练时务必使用裁剪或降采样

  10. 数据泄露

  11. 同一城市的图像需放在同一数据分片
  12. 避免验证集包含训练城市

  13. 标注不一致

  14. 粗标注和精细标注不要混合训练
  15. 测试集没有公开标注

延伸思考

  1. 如何利用 Cityscapes 的实例级标注(如车辆个体)提升分割性能?
  2. 在模型部署时,如何平衡 2048×1024 高分辨率输入和实时性要求?
  3. 对比其他街景数据集(如 BDD100K),Cityscapes 的优缺点有哪些?

通过系统性地处理数据加载、模型训练和性能优化,开发者可以充分发挥 Cityscapes 数据集的价值。建议在实践中多尝试不同的数据增强组合,并关注小类别的表现提升。

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