Ultralytics YOLO 中的 ADE20K 语义分割数据集实战指南:布局、label_mapping 原理与 YOLO26 训练
本文围绕 Ultralytics 仓库中 ade20k.yaml 数据集配置文档展开,讲清 ADE20K(20,210 张训练图 + 2,000 张验证图、150 个语义类别)在 YOLO 项目中的完整使用链路:官方目录结构与手动下载要求、YAML 中 masks_dir 与 label_mapping 字段的含义、源码层面 SemanticDataset 如何将源标签 ID 1–150 重映射为 0–149 并屏蔽 ignore 像素,以及用 YOLO26n-sem 在该数据集上训练与验证的具体命令。读完后,你可以独立完成 ADE20K 的下载、目录校验、训练启动,并理解 255 忽略标签在损失计算与指标统计中的作用。
一、ADE20K 数据集概览
ADE20K 是 MIT CSAIL 发布的大规模场景解析(scene parsing)基准数据集,包含 20,210 张训练图像与 2,000 张验证图像,全部带有密集的像素级标注,覆盖 150 个室内、室外、物体(object)与材质(stuff)类别。其完整的 SceneParsing 基准共 25,562 张图像:训练 20,210 张、验证 2,000 张、测试 3,352 张。由于测试集标注不公开,Ultralytics 的 ade20k.yaml 配置只使用训练集与验证集两个划分。
核心特性:
- 像素级密集标注:每张图像对应一张单通道掩码(mask),每个像素值即类别 ID,适合场景解析类密集预测任务;
- 150 个语义类别:细粒度类别集合兼顾室内外场景,例如
wall、building、sofa、sky、sea等,完整列表见 ade20k.yaml 中的names段; - 标准化评估:业界普遍使用 mIoU(mean Intersection over Union)作为主指标,ADE20K 因此成为密集预测模型的标准基准之一。
在 Ultralytics 项目中,ADE20K 语义分割属于 semantic 任务,模型文件使用 -sem 后缀(如 yolo26n-sem.pt),训练入口为 ultralytics/models/yolo/semantic/train.py 中的 SemanticSegmentationTrainer。
二、目录结构与手动下载要求
Ultralytics 的配置期望官方 ADEChallengeData2016 的原始布局:
ADEChallengeData2016/
├── images/
│ ├── training/
│ └── validation/
└── annotations/
├── training/
└── validation/
ADE20K 没有自动下载脚本(这与 COCO 等数据集不同,ade20k.yaml 末尾仅以注释形式给出了下载地址)。需要手动从 MIT 官方地址下载约 1 GB 的 ADEChallengeData2016.zip 压缩包,并直接解压到 datasets/ 目录下。这里有一个文档明确强调的坑:
压缩包自身的顶层文件夹已经命名为
ADEChallengeData2016/,解压后应直接得到datasets/ADEChallengeData2016/。不要自己先创建一个ADEChallengeData2016文件夹再解压进去,否则会形成嵌套的datasets/ADEChallengeData2016/ADEChallengeData2016/目录,YAML 将无法找到数据。
推荐的目录规划如 YAML 头部注释所示:
# parent
# ├── ultralytics
# └── datasets
# └── ADEChallengeData2016 ← downloads here (1 GB)
# ├── images
# └── annotations
三、ade20k.yaml 配置详解
完整配置位于 ultralytics/cfg/datasets/ade20k.yaml,共 326 行,由四部分组成:路径声明、150 类名称、标签映射、手动下载注释。
3.1 路径与掩码目录
# Dataset root directory
path: ADEChallengeData2016
train: images/training
val: images/validation
masks_dir: annotations # semantic mask directory
path:数据集根目录(相对datasets/或绝对路径均可);train/val:图像子目录,分别指向images/training与images/validation;masks_dir:掩码根目录,取值为annotations。
从源码看,ultralytics/data/dataset.py 中 SemanticDataset.get_label_files() 通过 img2label_paths(self.im_files, label_dir=self.data.get("masks_dir", "masks"), suffix=".png") 将每张图像路径镜像映射到对应的 PNG 掩码——例如 images/training/ADE_train_00000001.jpg 对应 annotations/training/ADE_train_00000001.png。也就是说,annotations/ 目录内部镜像 images/ 的 training/、validation/ 子结构,文件名主干一致,仅扩展名替换为 .png。
3.2 names:150 类训练标签
# ADE20K 150-class labels
names:
0: wall
1: building
2: sky
...
149: flag
names 段的键是训练 ID(0–149),与 label_mapping 的映射目标一一对应。注意这与原始 ADE20K 标注文件的源 ID(1–150)相差 1,后文会解释为什么。
3.3 label_mapping:源 ID 到训练 ID 的桥梁
# Map source label IDs to train IDs; ignore_label is converted to 255.
label_mapping:
0: ignore_label
1: 0
2: 1
3: 2
...
150: 149
原始 ADE20K 掩码中 0 表示 ignore(忽略/背景不确定区域),有效类别占用源 ID 1–150。label_mapping 的作用是把有效源标签 1–150 转换为连续的训练 ID 0–149,并把 ignore 像素统一映射为 255。这样模型输出通道数正好等于类别数 150,而 255 在损失与指标计算中被自动排除——这一点在 semantic 任务文档 中也有说明:像素值 255 被视为 "ignore",不参与损失计算。
四、源码视角:label_mapping 如何生效
ADE20K 标签映射的完整实现集中在 ultralytics/data/dataset.py 的 SemanticDataset 类中(约 L893 起),可以分四个环节理解:
1. 解析映射。_parse_label_mapping()(L930)把 YAML 中的 label_mapping 归一化为整数到整数的字典,其中字符串 ignore_label 与 None 值统一转为 255:
def _parse_label_mapping(self, mapping):
"""Normalize label_mapping entries from dataset YAML into integer-to-integer ids."""
if mapping is None:
return {}
...
for src, dst in mapping.items():
src = int(src)
if isinstance(dst, str):
dst = dst.strip()
dst = 255 if dst == "ignore_label" else int(dst)
elif dst is None:
dst = 255
else:
dst = int(dst)
normalized[src] = dst
2. 构建查找表(LUT)。_build_label_luts()(L950)基于映射构建 256 项的前向与逆向 uint8 查找表:前向表用于读取掩码时把源 ID 转成训练 ID,逆向表用于把模型预测还原回源 ID。
3. 读取掩码时做前向转换。load_mask()(L1028)以灰度方式读入 PNG 掩码,随后调用 convert_label(mask, inverse=False),用 cv2.LUT(label, lut) 一次性完成整张图的像素值重映射——这是向量化查表操作,比逐像素条件赋值高效得多。
4. 缓存一致性。get_cache_hash()(L969)把 label_mapping 的 JSON 序列化结果计入缓存哈希,保证修改映射后训练缓存会自动失效重建,避免用到旧的映射结果。
此外,get_image_and_label()(L1053)在加载图像的同时加载并缩放掩码(cv2.INTER_NEAREST 保证类别 ID 不被插值污染),并在指定 classes 过滤(include_class)时把未选中类别的像素改写为 255,使它们退出损失计算。
训练侧,SemanticSegmentationTrainer(ultralytics/models/yolo/semantic/train.py L78)的 get_class_counts() 会采样最多 1000 张掩码统计每类像素频率,过滤条件正是 valid = (mask >= 0) & (mask < nc) & (mask != 255)——255 像素同样被排除在类别权重统计之外;随后 compute_class_weights() 用 ENet 风格的逆对数权重 (1/ln(1.02+p))^cls_pw 缓解 150 类中前景类像素不平衡的问题。
验证侧,ultralytics/models/yolo/semantic/val.py L151 的 save_pred_masks() 在保存预测掩码 PNG 前,会检测数据集是否定义了 label_mapping,若有则调用 convert_label(preds, inverse=True) 把训练 ID 还原回 ADE20K 源 ID(1–150)再落盘,使导出的预测掩码可直接与官方标注对比。
五、训练实践
按 ade20k.md 给出的示例,以 yolo26n-sem.pt 预训练权重在 ADE20K 上微调 100 个 epoch、图像尺寸 512:
Python 方式:
from ultralytics import YOLO
# Load a model
model = YOLO("yolo26n-sem.pt") # load a pretrained model (recommended for training)
# Train the model
results = model.train(data="ade20k.yaml", epochs=100, imgsz=512)
CLI 方式:
# Start training from a pretrained *.pt model
yolo semantic train data=ade20k.yaml model=yolo26n-sem.pt epochs=100 imgsz=512
ade20k.yaml 头部注释也给出了最小用法:yolo semantic train data=ade20k.yaml model=yolo26n-sem.pt。完整参数列表可参考 Training 文档 与 semantic 任务文档。
训练完成后,在验证集上评估的命令为(与官方 ADE20K 基准表格的复现方式一致,图像尺寸 640):
yolo semantic val model=yolo26n-sem-ade20k.pt data=ade20k.yaml device=0 imgsz=640
官方 ADE20K 预训练模型在验证集上的表现(单模型单尺度,mIoU 为验证集数值):
| 模型 | 输入尺寸 (px) | mIoU (val) | 速度 RTX3090 PyTorch (ms) | 参数量 (M) | FLOPs (B) |
|---|---|---|---|---|---|
| YOLO26n-sem-ade20k | 640 | 38.8 | 3.9 ± 0.2 | 1.6 | 4.4 |
| YOLO26s-sem-ade20k | 640 | 45.6 | 4.2 ± 0.3 | 6.5 | 17.4 |
| YOLO26m-sem-ade20k | 640 | 47.4 | 4.7 ± 0.3 | 14.3 | 59.5 |
| YOLO26l-sem-ade20k | 640 | 49.7 | 8.3 ± 0.2 | 17.9 | 75.0 |
| YOLO26x-sem-ade20k | 640 | 51.5 | 9.9 ± 0.3 | 40.2 | 168.1 |
即预训练模型在 ADE20K 验证集上最高可达 51.5 mIoU。更多基准细节与 Cityscapes 系列模型对比见 语义分割任务文档。
六、许可证与引用
- ADE20K 图像仅限非商业研究与教育用途;数据集的配套标注软件单独采用 BSD-3 许可。商业用途需联系 MIT CSAIL 获取授权。因此在生产环境使用前务必确认许可条款。
- 若在研究工作中使用了 ADE20K,请引用其原始论文:
@inproceedings{zhou2017scene,
title={Scene Parsing through ADE20K Dataset},
author={Zhou, Bolei and Zhao, Hang and Puig, Xavier and Fidler, Sanja and Barriuso, Adela and Torralba, Antonio},
booktitle={Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition},
year={2017}
}
七、常见问题要点
ADE20K 的目录结构是什么? 官方 ADEChallengeData2016 布局:图像在 images/training/ 与 images/validation/,对应掩码在 annotations/training/ 与 annotations/validation/。Ultralytics 通过 masks_dir: annotations 将图像与掩码按同名主干配对。
必须手动下载吗? 是的。约 1 GB 的 ADEChallengeData2016.zip 需手动下载并直接解压到 datasets/ 目录,注意避免产生 ADEChallengeData2016/ADEChallengeData2016 的嵌套目录。
为什么需要 label_mapping? ADE20K 标注掩码以源标签 ID 存储,0 为 ignore 类。label_mapping 将有效标签 1–150 映射为连续训练 ID 0–149,并把 ignore 像素映射为 255,使其在训练与验证的损失、指标计算中被排除。
可以商用吗? 不可以(默认条款下)。图像发布条款限制为非商业研究与教育用途,商用需联系 MIT CSAIL 申请授权。
参考路径
- 数据集文档:docs/en/datasets/semantic/ade20k.md
- 数据集配置:ultralytics/cfg/datasets/ade20k.yaml
- 语义数据集实现(
SemanticDataset、LUT 映射):ultralytics/data/dataset.py - 语义分割训练器:ultralytics/models/yolo/semantic/train.py
- 语义分割验证器(预测掩码还原):ultralytics/models/yolo/semantic/val.py
- 语义分割任务总览:docs/en/tasks/semantic.md
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00