MMSegmentation 实战:BDD100K 语义分割数据的下载、目录组织与模型训练配置指南
【免费下载链接】mmsegmentationOpenMMLab Semantic Segmentation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmsegmentation
BDD100K 是伯克利大学发布的自动驾驶场景大规模数据集,覆盖 10 万张行车图像,其中语义分割任务常用其 10K 子集(1 万张带标注图像)。本文以 MMSegmentation 仓库中projects/bdd100k_dataset项目为线索,完整讲解 BDD100K 数据的注册下载、解压与目录摆放、数据集类与数据管线配置,以及基于 PSPNet 的端到端训练命令,帮助读者在 MMSegmentation 中快速复现 BDD100K 语义分割实验。
读完本文,你将掌握:如何在 BDD100K 官网获取10K Images与Segmentation标注包、如何将解压结果整理成 MMSegmentation 期望的目录结构、BDD100KDataset数据类的实现原理,以及如何直接运行官方提供的 PSPNet 训练配置并理解其中的关键参数。
一、数据集概览与获取途径
BDD100K 数据集需要先在官方网站注册账号,登录后才能进入下载页面获取数据。对应语义分割任务,需要下载两个压缩包:
10K Images:1 万张行车图像,包含train(7000 张)、val(1000 张)、test(2000 张)三个子集,图像为.jpg格式;Segmentation:语义分割标注包,压缩包名称通常为bdd100k_sem_seg_labels_trainval.zip,内含训练/验证集的多种标注形式(后文详述)。
官方数据集准备指南见 projects/bdd100k_dataset/docs/en/user_guides/2_dataset_prepare.md,对应的中文版本见 projects/bdd100k_dataset/docs/zh_cn/user_guides/2_dataset_prepare.md。该指南强调:语义分割实验主要使用10K 子集,图像与分割标注需配套下载,二者缺一不可。
二、下载与解压步骤
将两个压缩包下载到本地后(假设放在~/目录下),依次执行如下命令解压:
unzip ~/bdd100k_images_10k.zip -d ~/mmsegmentation/data/ unzip ~/bdd100k_sem_seg_labels_trainval.zip -d ~/mmsegmentation/data/说明:
-d指定解压目标目录,这里直接解压到 MMSegmentation 仓库根目录下的data/文件夹,与仓库中其他数据集的默认摆放位置保持一致;- 若你的仓库路径不同,请将
~/mmsegmentation/替换为实际的仓库绝对路径; - 解压后,两个压缩包会自动合并出
data/bdd100k/目录,其中images/来自图像包,labels/来自标注包。
三、期望的目录结构
解压完成后,data/目录下应当呈现如下结构(这也是 MMSegmentation 读取该数据集的默认约定):
mmsegmentation ├── mmseg ├── tools ├── configs ├── data │ ├── bdd100k │ │ ├── images │ │ │ └── 10k │ │ │ ├── test │ │ │ ├── train │ │ │ └── val │ │ └── labels │ │ └── sem_seg │ │ ├── colormaps │ │ │ ├── train │ │ │ └── val │ │ ├── masks │ │ │ ├── train │ │ │ └── val │ │ ├── polygons │ │ │ ├── sem_seg_train.json │ │ │ └── sem_seg_val.json │ │ └── rles │ │ ├── sem_seg_train.json │ │ └── sem_seg_val.json各子目录的含义:
| 路径 | 内容 | 训练时是否使用 |
|---|---|---|
images/10k/train、images/10k/val、images/10k/test | 原始行车图像(.jpg) | 是(train/val) |
labels/sem_seg/masks/train、masks/val | 像素级分割掩码(.png,类别索引编码) | 是,MMSegmentation 直接读取该目录 |
labels/sem_seg/colormaps/train、colormaps/val | 带调色板着色的可视化图(RGB 编码) | 否,仅用于人工查看 |
labels/sem_seg/polygons/*.json | 多边形(Polygon)形式的标注文件 | 否 |
labels/sem_seg/rles/*.json | 游程编码(RLE)形式的标注文件 | 否 |
关键点:MMSegmentation 训练/验证时实际使用的是masks下的 PNG 掩码;colormaps、polygons、rles属于 BDD100K 官方提供的其他标注形态,解压后保留即可,无需额外转换。
四、数据集类实现:BDD100KDataset
本项目的核心代码位于 projects/bdd100k_dataset/mmseg/datasets/bdd100k.py,仅需约 30 行即可把 BDD100K 接入 MMSegmentation 的数据体系:
from mmseg.datasets.basesegdataset import BaseSegDataset class BDD100KDataset(BaseSegDataset): METAINFO = dict( classes=('road', 'sidewalk', 'building', 'wall', 'fence', 'pole', 'traffic light', 'traffic sign', 'vegetation', 'terrain', 'sky', 'person', 'rider', 'car', 'truck', 'bus', 'train', 'motorcycle', 'bicycle'), palette=[[128, 64, 128], [244, 35, 232], [70, 70, 70], [102, 102, 156], [190, 153, 153], [153, 153, 153], [250, 170, 30], [220, 220, 0], [107, 142, 35], [152, 251, 152], [70, 130, 180], [220, 20, 60], [255, 0, 0], [0, 0, 142], [0, 0, 70], [0, 60, 100], [0, 80, 100], [0, 0, 230], [119, 11, 32]]) def __init__(self, img_suffix='.jpg', seg_map_suffix='.png', reduce_zero_label=False, **kwargs) -> None: super().__init__( img_suffix=img_suffix, seg_map_suffix=seg_map_suffix, reduce_zero_label=reduce_zero_label, **kwargs)从源码结构可以提炼出以下实现细节:
- 类别与调色板:
METAINFO声明了 19 个语义类别(road、sidewalk、building、car、person 等),并给出了每个类别对应的 RGB 调色板,用于可视化与结果着色;该元信息会被BaseSegDataset的_load_metainfo机制加载。 - 继承自
BaseSegDataset:基类实现在 mmseg/datasets/basesegdataset.py,它本身继承自 mmengine 的BaseDataset,负责按img_suffix与seg_map_suffix自动匹配图像与掩码文件对(要求同名仅后缀不同)。BDD100K 的图像是.jpg、掩码是.png,与基类默认值一致。 reduce_zero_label=False:BDD100K 的掩码中类别 0 对应road,是有实际语义的类别,因此不能像 Cityscapes 那样把 0 视为背景并丢弃;这也是 BDD100K 与 Cityscapes 在数据类实现上的关键差异。- 无需显式注册:该数据集类通过配置文件中的
custom_imports机制被动态导入(见下文第六节),因此源码中@DATASETS.register_module()被注释掉也完全不影响使用。
五、数据加载与增强管线配置
数据集配置文件为 projects/bdd100k_dataset/configs/base/datasets/bdd100k.py,它完整定义了训练/验证/测试三套数据管线与评测指标。
5.1 训练管线
dataset_type = 'BDD100KDataset' data_root = 'data/bdd100k/' crop_size = (512, 1024) train_pipeline = [ dict(type='LoadImageFromFile'), dict(type='LoadAnnotations'), dict( type='RandomResize', scale=(2048, 1024), ratio_range=(0.5, 2.0), keep_ratio=True), dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75), dict(type='RandomFlip', prob=0.5), dict(type='PhotoMetricDistortion'), dict(type='PackSegInputs') ]各环节作用:
RandomResize:以(2048, 1024)为基准尺度(BDD100K 原始图像即 1280×720,缩放保持宽高比),ratio_range=(0.5, 2.0)表示在 0.5~2.0 倍之间随机缩放,实现尺度增强;RandomCrop:裁剪到(512, 1024),cat_max_ratio=0.75限制单次裁剪中某一类别占比不超过 75%,避免裁剪块被单一类别(如大片 road)主导;RandomFlip:50% 概率水平翻转,符合自动驾驶场景的左右对称先验;PhotoMetricDistortion:光度扰动(亮度、对比度、饱和度等),提升模型对光照变化的鲁棒性。
5.2 验证/测试管线与 TTA
test_pipeline = [ dict(type='LoadImageFromFile'), dict(type='Resize', scale=(2048, 1024), keep_ratio=True), # add loading annotation after ``Resize`` because ground truth # does not need to do resize data transform dict(type='LoadAnnotations'), dict(type='PackSegInputs') ] img_ratios = [0.5, 0.75, 1.0, 1.25, 1.5, 1.75] tta_pipeline = [ dict(type='LoadImageFromFile', backend_args=None), dict( type='TestTimeAug', transforms=[ [dict(type='Resize', scale_factor=r, keep_ratio=True) for r in img_ratios], [dict(type='RandomFlip', prob=0., direction='horizontal'), dict(type='RandomFlip', prob=1., direction='horizontal')], [dict(type='LoadAnnotations')], [dict(type='PackSegInputs')] ]) ]- 验证管线先将图像缩放到
(2048, 1024)再加载标注,注释明确说明标注不需要参与 resize,因此LoadAnnotations必须放在Resize之后; tta_pipeline定义了 6 种尺度(0.5~1.75)乘以水平翻转组合的测试时增强(Test-Time Augmentation),实际评测时按需启用。
5.3 DataLoader 与评测器
train_dataloader = dict( batch_size=2, num_workers=2, persistent_workers=True, sampler=dict(type='InfiniteSampler', shuffle=True), dataset=dict( type=dataset_type, data_root=data_root, data_prefix=dict( img_path='images/10k/train', seg_map_path='labels/sem_seg/masks/train'), pipeline=train_pipeline)) val_dataloader = dict( batch_size=1, num_workers=4, persistent_workers=True, sampler=dict(type='DefaultSampler', shuffle=False), dataset=dict( type=dataset_type, data_root=data_root, data_prefix=dict( img_path='images/10k/val', seg_map_path='labels/sem_seg/masks/val'), pipeline=test_pipeline)) test_dataloader = val_dataloader val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU']) test_evaluator = val_evaluatordata_prefix中的img_path与seg_map_path正是第三节目录结构中实际生效的两个路径,它们以data_root为根拼接;- 训练采用
InfiniteSampler(配合 IterBasedTrainLoop 的按迭代训练模式),验证/测试采用DefaultSampler且不 shuffle; - 评测指标为标准语义分割的
mIoU(IoUMetric),验证与测试复用同一套配置。
六、模型训练配置与启动命令
6.1 完整配置解析
官方提供的 PSPNet 训练配置为 projects/bdd100k_dataset/configs/pspnet_r50-d8_4xb2-80k_bdd100k-512x1024.py,全文如下:
_base_ = [ '../../../configs/_base_/models/pspnet_r50-d8.py', './_base_/datasets/bdd100k.py', '../../../configs/_base_/default_runtime.py', '../../../configs/_base_/schedules/schedule_80k.py' ] custom_imports = dict( imports=['projects.bdd100k_dataset.mmseg.datasets.bdd100k']) crop_size = (512, 1024) data_preprocessor = dict(size=crop_size) model = dict(data_preprocessor=data_preprocessor)关键点:
- 四个
_base_继承:PSPNet + ResNet50-d8 模型结构(configs/base/models/pspnet_r50-d8.py)、第五节的数据集配置、默认运行时(日志/checkpoint 钩子等,见 configs/base/default_runtime.py)、80k 迭代训练计划; custom_imports:通过imports=['projects.bdd100k_dataset.mmseg.datasets.bdd100k']在配置加载阶段动态导入BDD100KDataset,这是 MMSegmentationprojects/目录下自定义数据集的标准接入方式——无需修改核心包代码即可扩展新数据集;data_preprocessor:将输入统一归一化到(512, 1024),与crop_size保持一致。
6.2 训练调度细节
80k 计划来自 configs/base/schedules/schedule_80k.py:
- 优化器:SGD,
lr=0.01、momentum=0.9、weight_decay=0.0005; - 学习率策略:
PolyLR(多项式衰减),power=0.9、eta_min=1e-4; - 训练循环:
IterBasedTrainLoop,max_iters=80000,每 8000 迭代验证一次并保存一次 checkpoint; - 命名含义:配置文件名的
4xb2表示 4 卡 × 每卡 batch_size 2(与第五节batch_size=2对应),80k表示 8 万迭代,512x1024表示输入尺寸。
6.3 训练命令
在 MMSegmentation 仓库根目录执行:
python tools/train.py projects/bdd100k_dataset/configs/pspnet_r50-d8_4xb2-80k_bdd100k-512x1024.py \ --work-dir your_work_dirtools/train.py是 MMSegmentation 的标准训练入口(支持单卡;多卡请使用tools/dist_train.sh);--work-dir指定日志与 checkpoint 的输出目录,不指定时默认输出到work_dirs/下与配置同名的目录;- 训练前请确认
data/bdd100k/目录结构正确,且images/10k/train与labels/sem_seg/masks/train中存在 7000 对同名文件、val中存在 1000 对,test中 2000 张图像仅供推理使用(无标注)。
七、验证与排错建议
- 数量核对:
ls data/bdd100k/images/10k/train | wc -l应为 7000,val应为 1000,test应为 2000; - 后缀匹配:确保图像为
.jpg、掩码为.png且同名,否则BaseSegDataset无法配对数据(配对逻辑见 mmseg/datasets/basesegdataset.py); - 掩码类别编码:
masks下的 PNG 使用类别索引(0~18)编码,colormaps才是 RGB 可视化图,训练配置指向的是masks,不要混淆; - 背景类别:BDD100K 的 0 号类别是
road而非背景,reduce_zero_label必须保持False,否则类别会整体错位导致指标异常。
结语
通过projects/bdd100k_dataset这个官方示例项目,可以看到 MMSegmentation 接入新数据集的完整范式:注册下载 → 解压摆放到data/约定目录 → 实现继承BaseSegDataset的数据类(声明类别与调色板)→ 通过custom_imports在配置中动态导入 → 复用标准 train/test pipeline 与 IoUMetric 评测。掌握这一流程后,你可以轻松将其推广到其他自动驾驶或遥感自定义数据集,快速开展语义分割实验。
【免费下载链接】mmsegmentationOpenMMLab Semantic Segmentation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmsegmentation
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考