Ultralytics Cityscapes8 数据集实战指南:8 张城市场景图像快速验证 YOLO26 语义分割流水线
本文基于 Ultralytics 仓库中的 Cityscapes8 数据集文档展开,介绍这个从 Cityscapes 中抽样的 8 图像语义分割子集的目录结构、完整数据集 YAML(含 label_mapping 标注映射机制)、如何用 YOLO26n-sem 在其上完成 100 个 epoch 的训练(Python 与 CLI 两种方式),并深入源码剖析 label_mapping 如何通过 256 项查找表在数据加载阶段把 Cityscapes 原始标签 ID 转换为 19 个连续训练 ID。读完本文,你可以用零下载成本的迷你数据集完整跑通语义分割的训练、验证与导出流程,再无缝切换到完整 Cityscapes 数据集。
1. 什么是 Cityscapes8:定位与使用边界
Cityscapes8 是一个紧凑的语义分割数据集,从完整 Cityscapes 数据集中抽取 8 张城市场景图像:4 张用于训练(train)、4 张用于验证(val)。它的设计目标不是性能基准测试,而是快速测试、调试与实验——在投入完整 Cityscapes 数据集的下载与训练成本之前,用它验证 YOLO26 语义分割模型及训练流水线的正确性,包括掩码加载、数据增强、验证与导出各环节。
Cityscapes8 与完整 Cityscapes 数据集使用相同的 19 个评估类别和相同的 label_mapping 行为,并完全兼容 YOLO26 语义分割工作流。因此一条能在 Cityscapes8 上跑通的流水线,只需把 data= 参数从 cityscapes8.yaml 改为 cityscapes.yaml 即可原封不动地迁移到完整数据集上。
注意:Cityscapes8 仅用于流水线测试,不能用于基准评测——8 张图像太少,不足以支撑有意义的 mIoU 对比。需要代表性评测结果时,请使用完整 Cityscapes 数据集的验证集(500 张图像)。
2. 数据集结构:images 与 masks 双目录镜像布局
Cityscapes8 镜像了完整数据集的目录布局,唯一区别是没有 test 划分:
cityscapes8/
├── images/
│ ├── train/ # 4 张图像
│ └── val/ # 4 张图像
└── masks/
├── train/ # 4 张单通道 PNG 掩码
└── val/ # 4 张单通道 PNG 掩码
两个关键机制:
- 掩码配对:
masks_dir: masks字段告诉框架在何处查找掩码文件,掩码目录镜像images/的结构(images/train/xxx.png对应masks/train/xxx.png),按同名文件(stem)一一配对。 - 标签转换:
label_mapping把 Cityscapes 的源标签 ID 转换为 0–18 的 19 个连续训练 ID,未被映射的类别(如背景、其他车辆部件等)统一转为忽略标签 255,训练时不参与损失计算。
这一布局约定由 SemanticDataset 的类文档明确定义:“掩码目录通过数据集 YAML 的 masks_dir 键指定,并镜像 images/ 目录结构(例如 images/train/ -> masks/train/);掩码像素值即类别 ID,255 为忽略标签。”
3. 数据集 YAML 完整解析
Cityscapes8 的官方配置文件为 cityscapes8.yaml,其完整内容如下:
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
# Cityscapes semantic segmentation dataset (19 classes)
# Documentation: https://docs.ultralytics.com/datasets/semantic/cityscapes8
# Example usage: yolo semantic train data=cityscapes8.yaml model=yolo26n-sem.pt
# Dataset root directory
path: cityscapes8 # dataset root dir
train: images/train # train images (relative to 'path') 4 images
val: images/val # val images (relative to 'path') 4 images
masks_dir: masks # semantic mask directory
# Cityscapes 19-class labels
names:
0: road
1: sidewalk
2: building
3: wall
4: fence
5: pole
6: traffic light
7: traffic sign
8: vegetation
9: terrain
10: sky
11: person
12: rider
13: car
14: truck
15: bus
16: train
17: motorcycle
18: bicycle
# Map source label IDs to train IDs; ignore_label is converted to 255.
label_mapping:
-1: ignore_label
0: ignore_label
1: ignore_label
2: ignore_label
3: ignore_label
4: ignore_label
5: ignore_label
6: ignore_label
7: 0
8: 1
9: ignore_label
10: ignore_label
11: 2
12: 3
13: 4
14: ignore_label
15: ignore_label
16: ignore_label
17: 5
18: ignore_label
19: 6
20: 7
21: 8
22: 9
23: 10
24: 11
25: 12
26: 13
27: 14
28: 15
29: ignore_label
30: ignore_label
31: 16
32: 17
33: 18
# Download URL (optional)
download: https://github.com/ultralytics/assets/releases/download/v0.0.0/cityscapes8.zip
逐字段说明:
| 字段 | 值 | 说明 |
|---|---|---|
path |
cityscapes8 |
数据集根目录,相对工作目录;框架会自动下载并解压到此处 |
train |
images/train |
训练图像目录(相对 path),4 张图像 |
val |
images/val |
验证图像目录(相对 path),4 张图像 |
masks_dir |
masks |
语义掩码目录名,内部结构镜像 images/ |
names |
0–18 共 19 类 | Cityscapes 19 类评测标签:road、sidewalk、building、wall、fence、pole、traffic light、traffic sign、vegetation、terrain、sky、person、rider、car、truck、bus、train、motorcycle、bicycle |
label_mapping |
源 ID → 训练 ID | 将 Cityscapes 原始 34 种标签 ID(0–33 及 -1)映射为 19 个连续训练 ID,其余转为 ignore_label |
download |
cityscapes8.zip 的 URL | 可选下载地址,首次运行时自动拉取该打包子集,无需手动下载 |
与完整 cityscapes.yaml 相比,cityscapes8.yaml 的差异只有三点:训练/验证图像数(2975/500 → 4/4)、无 test 字段(完整数据集含 1525 张 test 图像)、download 从一段 Python 整理脚本(要求先手动下载 Cityscapes 官方 leftImg8bit 与 gtFine 压缩包并重新组织目录)简化为一个 zip 直链。
4. 源码剖析:label_mapping 的查找表实现
label_mapping 并非简单的字典查表,Ultralytics 在数据加载阶段把它编译成了两张 256 项的查找表(LUT),利用掩码本身是单通道 uint8 数组的特性,一次 cv2.LUT 调用即可完成整幅掩码的标签转换。核心实现位于 SemanticDataset:
(1)解析与归一化(_parse_label_mapping):
def _parse_label_mapping(self, mapping):
"""Normalize label_mapping entries from dataset YAML into integer-to-integer ids."""
...
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)
...
YAML 中的字符串 ignore_label 被统一归一化为整数 255。因此 Cityscapes8 掩码中所有被映射到 ignore_label 的像素(源 ID 0–6、9、10、14–16、18、29–30,以及 -1)在加载后即变成 255,训练损失自动跳过这些像素。
(2)构建前向/逆向 LUT(_build_label_luts):
def _build_label_luts(self) -> tuple[np.ndarray, np.ndarray]:
"""Build the 256-entry forward and inverse lookup tables for the dataset label mapping."""
forward, inverse = np.arange(256, dtype=np.uint8), np.arange(256, dtype=np.uint8)
for k, v in self.label_mapping.items():
if 0 <= k < 256:
forward[k] = v
if 0 <= v < 256:
inverse[v] = k & 0xFF
return forward, inverse
前向表(label_lut)把源 ID 映射为训练 ID,用于训练与验证时加载掩码;逆向表(inverse_lut)把训练 ID 映射回源 ID,用于可视化、结果导出等需要还原为 Cityscapes 原始标签的场景。
(3)掩码加载即转换(load_mask 与 convert_label):
mask = cv2.imread(mask_file, cv2.IMREAD_GRAYSCALE) # 单通道灰度读取
...
if self.label_mapping:
mask = self.convert_label(mask, inverse=False)
return mask.astype(np.uint8, copy=False)
convert_label 内部对 uint8 掩码调用 cv2.LUT(label, lut)——GPU/核加速的逐像素查表,整幅掩码转换只有一次内存遍历,这也是掩码被要求为单通道 PNG 的原因。
另外一个容易被忽略的工程细节:数据集缓存哈希(get_cache_hash)会把 label_mapping 的内容序列化后纳入计算,即一旦修改标签映射,框架会自动使旧的标签缓存失效,避免读到与映射不匹配的旧标注。
5. 用 Cityscapes8 训练 YOLO26n-sem
在 Cityscapes8 上训练 YOLO26n-sem 模型 100 个 epoch、图像尺寸 1024,Python 与 CLI 两种用法如下(完整训练参数见 YOLO 训练文档):
Python:
from ultralytics import YOLO
# Load a pretrained YOLO26n-sem model
model = YOLO("yolo26n-sem.pt")
# Train the model on Cityscapes8
results = model.train(data="cityscapes8.yaml", epochs=100, imgsz=1024)
CLI:
# Train YOLO26n-sem on Cityscapes8 using the command line
yolo semantic train data=cityscapes8.yaml model=yolo26n-sem.pt epochs=100 imgsz=1024
几点补充:
- 模型结构:YOLO26 语义分割模型定义于 yolo26-sem.yaml,默认
nc: 19(即 Cityscapes 默认类别数),头部由 P3/8 与 P4/16 两个分辨率的特征图经上采样拼接后送入SemanticSegment头。n 档规模约 260 层、257 万参数、6.1 GFLOPs,s/m/l/x 各档参数规模依次扩大(最大 x 档约 5900 万参数)。 - 训练器:
SemanticSegmentationTrainer强制task=semantic,并覆写了set_class_weights——对多类别数据集会按训练掩码中各类别的像素频率计算类别权重,以缓解城市场景中 road/sky 占绝对像素优势导致的类别不平衡;二分类(nc=1)则跳过加权、使用未加权 BCE 损失。 - 验证器:
SemanticSegmentationValidator基于检测验证器扩展,评价指标为 mIoU(平均交并比)与像素准确率,由SemanticMetrics计算器维护混淆矩阵。值得注意的是,该类的官方文档字符串示例正是使用data="cityscapes8.yaml"进行验证——Cityscapes8 就是验证器的一条“自检路径”。
验证命令示例:
yolo semantic val data=cityscapes8.yaml model=yolo26n-sem.pt imgsz=1024
from ultralytics import YOLO
model = YOLO("yolo26n-sem.pt")
metrics = model.val(data="cityscapes8.yaml", imgsz=1024)
此外,你也可以在 Ultralytics Platform 云端托管 Cityscapes8 数据集并在云端训练语义分割模型。
6. Cityscapes8 与完整 Cityscapes 对比
| 维度 | Cityscapes8 | 完整 Cityscapes |
|---|---|---|
| 训练图像 | 4 张 | 2975 张 |
| 验证图像 | 4 张 | 500 张 |
| test 划分 | 无 | 1525 张(images/test) |
类别与 label_mapping |
相同 19 类、相同映射 | 相同 19 类、相同映射 |
| 获取方式 | YAML 内置 zip 直链,自动下载 | 需手动下载官方压缩包,再执行 YAML 内 Python 脚本整理目录(约 11 GB) |
| 适用场景 | 流水线测试、调试、CI 验证 | 正式训练与基准评测 |
正因为两者共享同一套类别与映射约定,在 Cityscapes8 上验证过的代码、增广配置和目录习惯可以直接复用到完整数据集,唯一改动是 data= 参数。
7. 引用、许可与致谢
Cityscapes8 采样自 Cityscapes,遵循 Cityscapes 的非商业研究许可。在研究或开发中使用了该数据集,请引用:
@inproceedings{Cordts2016Cityscapes,
title={The Cityscapes Dataset for Semantic Urban Scene Understanding},
author={Cordts, Marius and Omran, Mohamed and Ramos, Sebastian and Rehfeld, Timo and Enzweiler, Markus and Benenson, Rodrigo and Franke, Uwe and Roth, Stefan and Schiele, Bernt},
booktitle={Proc. of the IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},
year={2016}
}
完整许可条款详见 Cityscapes 数据集文档。感谢 Cityscapes 团队对自动驾驶与计算机视觉社区的持续贡献。
8. 常见问题(FAQ)
Q1:Ultralytics Cityscapes8 数据集的用途是什么? 它为语义分割模型提供快速测试与调试环境。仅 8 张图像(4 训练 + 4 验证)的配置,使其非常适合在扩展到完整 Cityscapes 之前,验证 YOLO 语义分割流水线的掩码加载、数据增强、验证与导出路径是否正常工作。更多细节可查阅 Cityscapes8 YAML 配置。
Q2:Cityscapes8 与完整 Cityscapes 数据集有何不同?
Cityscapes8 从完整数据集 2975 训练 / 500 验证的划分中抽取 8 张图像(4 训练 + 4 验证),使用相同的 19 个类别和 label_mapping,因此能在 Cityscapes8 上运行的流水线无需任何修改即可运行在完整数据集上——只需把 data= 从 cityscapes8.yaml 指向 cityscapes.yaml。与完整数据集不同,Cityscapes8 没有手动下载步骤,也没有 test 划分。
Q3:如何用 Cityscapes8 训练 YOLO26 模型?
使用 Python(model.train(data="cityscapes8.yaml", epochs=100, imgsz=1024))或 CLI(yolo semantic train data=cityscapes8.yaml model=yolo26n-sem.pt epochs=100 imgsz=1024)均可,代码示例见上文第 5 节;更多训练选项参见 YOLO 训练文档。
Q4:能否用 Cityscapes8 做基准评测? 不能。Cityscapes8 规模过小,无法支撑有意义的模型对比,它仅用于训练与评测流水线的正确性检查。需要代表性的语义分割基准结果时,请使用完整 Cityscapes 数据集的验证集。
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 StartedRust0626
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