共计 2112 个字符,预计需要花费 6 分钟才能阅读完成。
背景与痛点
Cityscapes 数据集是自动驾驶领域广泛使用的语义分割基准数据集,包含 50 个城市街景的 5000 张精细标注图像(2975 训练 /500 验证 /1525 测试)。但在实际使用中常遇到三个典型问题:

- 标注复杂性:19 个官方类别中存在大量『忽略区域』(如遮挡物体),且类间像素比例差异极大(道路占比 34.6% vs 交通标志仅 0.2%)
- 硬件资源消耗:2048×1024 的高分辨率图像导致普通 GPU(如 RTX 3090)batch_size 只能设为 4 -6
- 评估偏差:传统 mean IoU 指标对少数类(如行人)不敏感,可能掩盖关键安全隐患
技术方案对比
预处理方法实验
通过三组对比实验(baseline 为直接 resize):
- RandomCrop+Flip:在 512×1024 裁剪时,训练速度提升 2.1 倍,但 mIoU 下降 3.2%
- Class-aware 采样:针对稀有类别(如自行车)提高采样概率,可使 traffic sign 的 IoU 提升 8.7%
- AutoAugment:使用搜索得到的策略组合,验证集表现最优但训练耗时增加 40%
损失函数选择
测试四种主流损失函数在验证集的表现:
| 损失函数 | mIoU(%) | 训练稳定性 |
|---|---|---|
| CrossEntropy | 72.3 | 高 |
| FocalLoss | 73.1 | 中 |
| Lovasz-Softmax | 74.5 | 低 |
| OHEM | 73.8 | 中 |
核心实现
高效数据加载管道
class CityscapesDataset(Dataset):
def __init__(self, root, split='train', crop_size=(512,1024)):
self.images = sorted(glob(f'{root}/leftImg8bit/{split}/*/*.png'))
self.labels = sorted(glob(f'{root}/gtFine/{split}/*/*labelIds.png'))
self.crop_size = crop_size
# 类别权重计算(逆频率加权)self.class_weights = torch.tensor([0.8373, 0.918, 0.866, ..., 0.9393])
def __getitem__(self, idx):
img = cv2.cvtColor(cv2.imread(self.images[idx]), cv2.COLOR_BGR2RGB)
label = cv2.imread(self.labels[idx], cv2.IMREAD_GRAYSCALE)
# 随机裁剪 + 水平翻转
if self.crop_size:
h,w = img.shape[:2]
i,j = random.randint(0,h-self.crop_size[0]), random.randint(0,w-self.crop_size[1])
img = img[i:i+self.crop_size[0], j:j+self.crop_size[1]]
label = label[i:i+self.crop_size[0], j:j+self.crop_size[1]]
if random.random() > 0.5:
img, label = np.fliplr(img), np.fliplr(label)
return torch.from_numpy(img).float().permute(2,0,1)/255., \
torch.from_numpy(label).long()
性能优化
内存优化三连击
- 梯度检查点技术:在 ResNet-101 的 layer3 启用后,显存占用从 9.8GB 降至 6.2GB
model = torch.utils.checkpoint.checkpoint_sequential(model.layer3, 4, x) - 混合精度训练:Apex 库的 O1 模式减少 30% 显存,速度提升 22%
- 动态 Batch 策略:根据剩余显存动态调整后续 batch 的裁剪尺寸
分布式训练配置
# 启动命令示例(2 机 4 卡)python -m torch.distributed.launch --nproc_per_node=4 --nnodes=2 \
--node_rank=$NODE_RANK --master_addr=$MASTER_ADDR train.py
关键配置参数:
– 使用 SyncBN 保证跨卡统计一致性
– 梯度累积步长设为 2 补偿单卡 batch 较小问题
– All-reduce 通信启用 FP16 压缩
避坑指南
- 评估指标陷阱:除 mIoU 外,务必监控
- 关键类别的 IoU(如 person/rider)
- 边界 F -score(对自动驾驶尤为重要)
- 数据增强误区:避免过度使用色彩抖动,街景图像的色彩分布具有物理意义
- 标签编码检查 :官方提供的
labelTrainIds.png已处理忽略区域,直接使用原标签会导致性能虚高
总结与思考
通过组合类别加权采样、混合精度训练和梯度检查点技术,我们在 RTX 3090 上实现了 batch_size=12 的训练配置(原只能跑 batch_size=4),验证集 mIoU 达到 75.3%。值得思考的是:当扩展到更多城市(如雨雪天气数据)时,当前方案是否仍能保持鲁棒性?特别是对于 void 类别的处理策略是否需要调整?
正文完
发表至: 未分类
近两天内
