共计 4072 个字符,预计需要花费 11 分钟才能阅读完成。
4.1 语义分割(Semantic Segmentation)
语义分割的目标是为图像中的 每个像素 分配一个类别标签(如“人”、“车”、“天空”),但 不区分同一类别的不同个体。例如,图中有两个人,语义分割会将他们都标记为“人”,而不区分谁是谁。
4.1.1 U-Net
U-Net 是由 Ronneberger 等人在 2015 年提出的经典语义分割网络,最初用于生物医学图像分割。
网络结构特点:
- 编码器 - 解码器结构(Encoder-Decoder):
- 编码器(下采样路径):使用卷积 + 池化逐步提取高层语义特征,空间分辨率降低,通道数增加。
- 解码器(上采样路径):通过转置卷积(或插值)逐步恢复空间分辨率。
- 跳跃连接(Skip Connections):
- 将编码器中对应层级的高分辨率特征图与解码器的上采样结果拼接(concatenate),融合局部细节与全局语义。
- 输出:与输入图像同尺寸的像素级分类图。
优点:
- 对小数据集表现优异(得益于跳跃连接保留细节)
- 结构清晰,易于实现和改进
- 广泛应用于医学图像、遥感图像等场景
# 伪代码示意(PyTorch 风格)class UNet(nn.Module):
def __init__(self, n_channels, n_classes):
super().__init__()
self.inc = DoubleConv(n_channels, 64)
self.down1 = Down(64, 128)
self.down2 = Down(128, 256)
self.down3 = Down(256, 512)
self.down4 = Down(512, 1024)
self.up1 = Up(1024, 512)
self.up2 = Up(512, 256)
self.up3 = Up(256, 128)
self.up4 = Up(128, 64)
self.outc = OutConv(64, n_classes)
def forward(self, x):
x1 = self.inc(x)
x2 = self.down1(x1)
x3 = self.down2(x2)
x4 = self.down3(x3)
x5 = self.down4(x4)
x = self.up1(x5, x4)
x = self.up2(x, x3)
x = self.up3(x, x2)
x = self.up4(x, x1)
logits = self.outc(x)
return logits
4.1.2 DeepLab 系列
DeepLab 是 Google 提出的一系列高性能语义分割模型,核心思想是 在保持空间分辨率的同时扩大感受野。
关键技术演进:
| 版本 | 核心技术 |
|---|---|
| DeepLab v1 | 空洞卷积(Atrous Convolution) |
| DeepLab v2 | 空洞空间金字塔池化(ASPP)+ CRF 后处理 |
| DeepLab v3 | 改进 ASPP + 多尺度特征融合 |
| DeepLab v3+ | 引入编码器 - 解码器结构,结合 Xception 骨干网络 |
核心组件:
- 空洞卷积(Atrous/Dilated Convolution)
- 在不增加参数量和计算量的前提下,扩大卷积核的感受野。
- 公式:输出位置 $$ y[i] = \sum_k x[i + r \cdot k] \cdot w[k] $$,其中 $ r $ 为膨胀率。
- ASPP(Atrous Spatial Pyramid Pooling)
- 使用不同膨胀率的空洞卷积并行处理特征图,捕获多尺度上下文信息。
- 通常包含:1×1 卷积 + 多个不同 rate 的 3×3 空洞卷积 + 全局平均池化。
- 编码器 - 解码器(v3+)
- 编码器:DeepLab v3 的输出
- 解码器:上采样 + 低层特征融合(类似 U -Net)
优点:
- 对多尺度目标鲁棒性强
- 边界分割精度高
- 在 Cityscapes、PASCAL VOC 等基准上表现优异
4.2 实例分割(Instance Segmentation)
实例分割不仅区分类别,还 区分同一类别的不同个体,即为每个对象生成独立的像素级掩码(mask)。
4.2.1 Mask R-CNN
Mask R-CNN 是 He 等人在 2017 年提出的实例分割框架,是 Faster R-CNN 的自然扩展。
网络结构:
- 骨干网络(Backbone):如 ResNet + FPN(特征金字塔网络)
- 区域建议网络(RPN):生成候选框
- RoIAlign(关键改进):
- 替代 RoIPooling,通过双线性插值避免量化误差,精准对齐特征与原始像素
- 三个并行分支:
- 分类分支:预测类别
- 边界框回归分支:精修框坐标
- 掩码分支:为每个 RoI 生成 $28 \times 28$ 的二值掩码(sigmoid 激活)
输出:
- 每个实例:类别标签 + 边界框 + 像素级掩码
优点:
- 精度高,是 COCO 实例分割竞赛的标杆模型
- 框架灵活,可扩展至关键点检测等任务
- 开源实现成熟(Detectron2、MMDetection)
4.3 图像分割评估指标
4.3.1 IoU(Intersection over Union)
IoU 是最常用的分割评估指标,衡量预测区域与真实区域的重叠程度。
$$
\text{IoU} = \frac{|A \cap B|}{|A \cup B|}
$$
- $A$:预测掩码
- $B$:真实掩码(Ground Truth)
- 取值范围:[0, 1],值越大越好
注意 :在语义分割中,通常计算 每个类别的 IoU,再取平均(mIoU,mean IoU)。
4.3.2 Dice 系数(Dice Coefficient)
Dice 系数与 IoU 密切相关,常用于医学图像分割。
$$
\text{Dice} = \frac{2|A \cap B|}{|A| + |B|} = \frac{2 \cdot \text{TP}}{2 \cdot \text{TP} + \text{FP} + \text{FN}}
$$
- 与 IoU 的关系:$$\text{Dice} = \frac{2 \cdot \text{IoU}}{1 + \text{IoU}}$$
- 对小目标更敏感(因分母为面积和而非并集)
4.3.3 其他指标
| 指标 | 说明 |
|---|---|
| Pixel Accuracy | 正确分类像素数 / 总像素数(忽略类别不平衡) |
| mIoU | 所有类别 IoU 的平均值(主流指标) |
| Boundary F1-score (BF-score) | 衡量边界分割精度 |
| AP (Average Precision) | 实例分割常用(如 COCO AP@0.5:0.95) |
4.4 方法对比总结
| 方法 | 类型 | 是否区分实例 | 典型应用场景 |
|---|---|---|---|
| U-Net | 语义分割 | 否 | 医学图像、遥感 |
| DeepLab | 语义分割 | 否 | 自动驾驶、街景理解 |
| Mask R-CNN | 实例分割 | 是 | COCO、工业检测、机器人视觉 |
4.5 实战代码示例(简要)
4.5.1 使用 torchvision 加载 DeepLabV3
import torch
import torchvision.transforms as T
from PIL import Image
# 加载预训练模型
model = torch.hub.load('pytorch/vision:v0.10.0', 'deeplabv3_resnet50', pretrained=True)
model.eval()
# 预处理
input_image = Image.open("input.jpg")
preprocess = T.Compose([
T.ToTensor(),
T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
input_tensor = preprocess(input_image).unsqueeze(0)
# 推理
with torch.no_grad():
output = model(input_tensor)['out'][0]
output_predictions = output.argmax(0)
# 可视化
palette = torch.tensor([2 ** 25 - 1, 2 ** 15 - 1, 2 ** 21 - 1])
colors = torch.as_tensor([i for i in range(21)])[:, None] * palette
colors = (colors % 255).numpy().astype("uint8")
r = Image.fromarray(output_predictions.byte().cpu().numpy()).resize(input_image.size)
r.putpalette(colors)
r.save("segmentation_result.png")
4.5.2 计算 mIoU 和 Dice
import numpy as np
def compute_iou(pred, target, num_classes):
ious = []
for cls in range(num_classes):
pred_cls = (pred == cls)
target_cls = (target == cls)
intersection = np.logical_and(pred_cls, target_cls).sum()
union = np.logical_or(pred_cls, target_cls).sum()
iou = intersection / union if union != 0 else 0
ious.append(iou)
return np.mean(ious)
def dice_coefficient(pred, target):
smooth = 1e-6
intersection = (pred * target).sum()
dice = (2. * intersection + smooth) / (pred.sum() + target.sum() + smooth)
return dice
4.6 本课小结
- 语义分割:像素级分类,不区分实例 → U-Net、DeepLab
- 实例分割:像素级分类 + 实例区分 → Mask R-CNN
- 评估指标:
- IoU/mIoU:通用标准
- Dice:医学图像常用
- 技术趋势:
- 从 FCN → U-Net → DeepLab → Transformer-based(如 SegFormer)
- 实时分割(如 BiSeNet)、弱监督分割也是研究热点
建议实践:使用 Cityscapes 或 Pascal VOC 数据集,分别训练 U-Net 和 DeepLab,并对比 mIoU;尝试用 Detectron2 运行 Mask R-CNN 进行实例分割。

