首页
/ Ultralytics Cityscapes8 数据集实战指南:8 张城市场景图像快速验证 YOLO26 语义分割流水线

Ultralytics Cityscapes8 数据集实战指南:8 张城市场景图像快速验证 YOLO26 语义分割流水线

2026-09-06 19:05:57作者:秋泉律Samson

本文基于 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 掩码

两个关键机制:

  1. 掩码配对masks_dir: masks 字段告诉框架在何处查找掩码文件,掩码目录镜像 images/ 的结构(images/train/xxx.png 对应 masks/train/xxx.png),按同名文件(stem)一一配对。
  2. 标签转换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 官方 leftImg8bitgtFine 压缩包并重新组织目录)简化为一个 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_maskconvert_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 数据集的验证集。

登录后查看全文
热门项目推荐
相关项目推荐