从零实现YOLOv8语义分割:Cityscapes数据集实战指南

在计算机视觉领域,语义分割技术正逐渐成为自动驾驶、智能监控等场景的核心支撑。不同于目标检测只需框出物体位置,语义分割需要精确到像素级别的分类,这对算法提出了更高要求。本文将手把手带您使用最新的YOLOv8框架,在Cityscapes数据集上构建完整的语义分割流水线。

1. 环境配置与数据准备

1.1 开发环境搭建

推荐使用Python 3.8+和PyTorch 1.12+环境,以下是关键依赖的安装命令:

pip install ultralytics torch==1.13.1 torchvision==0.14.1 --extra-index-url https://download.pytorch.org/whl/cu117
pip install cityscapesscripts opencv-python matplotlib

硬件配置建议:

  • GPU :至少8GB显存(如RTX 3070)
  • 内存 :16GB以上
  • 存储 :50GB可用空间(Cityscapes数据集约30GB)

1.2 Cityscapes数据集处理

Cityscapes原始数据包含34个类别,但通常只需关注19个主要类别。使用官方脚本转换标签:

from cityscapesscripts.preparation.createTrainIdLabelImgs import main
main({
    'cityscapes_path': '/path/to/cityscapes',
    'output_path': '/path/to/converted'
})

目录结构处理后应如下:

cityscapes/
├── leftImg8bit/
│   ├── train/
│   ├── val/
│   └── test/
└── gtFine/
    ├── train/
    ├── val/
    └── test/

注意:转换后会生成 *_labelTrainIds.png 文件,其中不关注的类别像素值为255

2. YOLOv8模型定制

2.1 配置文件调整

创建自定义的YOLOv8分割模型配置文件 yolov8-seg-cityscapes.yaml

# YOLOv8 Segmentation config
num_classes: 19
backbone:
  - [-1, 1, Conv, [64, 3, 2]]  # 0-P1/2
  - [-1, 1, Conv, [128, 3, 2]] # 1-P2/4
  # ...完整backbone结构...
head:
  - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
  - [[-1, 6], 1, Concat, [1]]  # 特征融合
  - [-1, 3, C2f, [512]]        # 分割头
  - [-1, 1, Conv, [19, 1, 1]]  # 19类输出

2.2 数据加载适配

创建数据集描述文件 cityscapes-seg.yaml

path: /path/to/cityscapes
train: leftImg8bit/train
val: leftImg8bit/val
test: leftImg8bit/test

names:
  0: road
  1: sidewalk
  2: building
  # ...完整19个类别...

3. 训练与优化策略

3.1 基础训练命令

启动训练的基本命令示例:

yolo segment train data=cityscapes-seg.yaml model=yolov8n-seg.yaml epochs=100 imgsz=1024 batch=8

关键参数说明:

参数 推荐值 作用
imgsz 1024 输入图像尺寸
batch 8-16 根据显存调整
lr0 0.01 初始学习率
weight_decay 0.0005 权重衰减

3.2 高级训练技巧

  1. 学习率调度

    from ultralytics import YOLO
    
    model = YOLO('yolov8n-seg.yaml')
    model.train(
        data='cityscapes-seg.yaml',
        lr0=0.01,
        lrf=0.1,  # 最终学习率=lr0*lrf
        warmup_epochs=3
    )
    
  2. 数据增强配置

    # 在cityscapes-seg.yaml中添加
    augment:
      hsv_h: 0.015  # 色调增强
      hsv_s: 0.7    # 饱和度增强
      flipud: 0.5   # 垂直翻转概率
      mixup: 0.2    # MixUp概率
    

4. 结果可视化与分析

4.1 Python可视化脚本

使用OpenCV实现结果可视化:

import cv2
import numpy as np

def visualize_segmentation(image_path, mask_path):
    image = cv2.imread(image_path)
    mask = cv2.imread(mask_path, cv2.IMREAD_GRAYSCALE)
    
    # Cityscapes官方配色方案
    palette = [
        (128, 64, 128),   # road
        (244, 35, 232),   # sidewalk
        (70, 70, 70),     # building
        # ...其他类别颜色...
    ]
    
    colored_mask = np.zeros((*mask.shape, 3), dtype=np.uint8)
    for class_id, color in enumerate(palette):
        colored_mask[mask == class_id] = color
    
    overlay = cv2.addWeighted(image, 0.7, colored_mask, 0.3, 0)
    return overlay

4.2 性能评估指标

使用官方评估脚本计算指标:

python cityscapesscripts/evaluation/evalPixelLevelSemanticLabeling.py \
    --gtPath gtFine/val \
    --predPath runs/segment/predict \
    --outputFile evaluation.json

典型优化方向:

  • mIoU提升 :关注低分类别,增加对应样本
  • 边界精度 :使用Dice Loss替代交叉熵
  • 推理速度 :尝试模型量化(FP16/INT8)

5. 常见问题解决方案

5.1 显存不足处理

当遇到CUDA out of memory错误时:

  1. 减小 batch_size (最低可设为1)
  2. 启用梯度累积:
    yolo train ... batch=4 accumulate=2  # 等效batch=8
    
  3. 使用更小的模型(如yolov8s-seg)

5.2 类别不平衡对策

Cityscapes中"road"类别占比约40%,可采用:

  1. 样本加权
    class_weights = torch.tensor([1.0, 2.0, ..., 0.5])  # 根据频率设置
    criterion = nn.CrossEntropyLoss(weight=class_weights)
    
  2. 过采样少数类
    # 在数据配置中添加
    sample_weights:
      - {class: 15, weight: 3.0}  # 对稀有类别加权
    

5.3 预测结果碎片化

改善分割连贯性的技巧:

  1. 后处理使用CRF(条件随机场):

    from pydensecrf import densecrf
    crf = densecrf.DenseCRF2D(width, height, 19)
    # 添加颜色和位置特征
    crf.addPairwiseBilateral(sxy=80, srgb=13, rgbim=image)
    
  2. 训练时加入边界感知损失:

    class EdgeAwareLoss(nn.Module):
        def forward(self, pred, target):
            edge = cv2.Canny(target, 0.1, 0.2)
            weight = 1 + edge * 5  # 边界区域权重更高
            return (F.cross_entropy(pred, target) * weight).mean()
    

在实际项目中,发现将图像尺寸调整为1024x1024时,相比默认的640x640能提升约3%的mIoU,但推理速度下降40%。对于实时性要求高的场景,建议使用768x768作为平衡点。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐