共计 2236 个字符,预计需要花费 6 分钟才能阅读完成。
图像分割与 FCN 的核心原理
1. 图像分割任务与 CNN 的局限性
图像分割要求对每个像素进行分类,输出与输入同尺寸的预测图。传统 CNN 存在两大缺陷:

- 固定尺寸输出:全连接层迫使输入尺寸固定,破坏图像原始空间结构
- 空间信息丢失:池化层降低分辨率,导致无法精确定位物体边界
例如,VGG16 最后特征图尺寸仅为原图的 1 /32,直接上采样会产生严重锯齿。
2. FCN 三大创新设计
2.1 全卷积结构(Fully Convolutional)
替换全连接层为 1 ×1 卷积层,实现任意尺寸输入输出。数学等价性证明见[1]:
# 传统全连接层 vs 1x1 卷积实现
fc = nn.Linear(4096, 1000) # 固定输入维度
conv = nn.Conv2d(512, 1000, kernel_size=1) # 动态处理任意尺寸
2.2 跳跃连接(Skip Architecture)
融合深层语义信息与浅层细节信息:
Input Image
│
├──[Conv Layers]──低分辨率高级特征(语义强)│
└──[Skip Layer]──高分辨率低级特征(定位准)
2.3 转置卷积(Transposed Convolution)
通过可学习参数实现智能上采样,比双线性插值提升 8% mIoU[2]:
# 转置卷积参数设置要点
upsample = nn.ConvTranspose2d(
in_channels=512,
out_channels=256,
kernel_size=4, # 控制上采样倍率
stride=2, # 必须与下采样步长对应
padding=1 # 避免棋盘效应
)
PyTorch 实战实现
3. 模型构建关键代码
3.1 基于 VGG16 的编码器
class FCN32s(nn.Module):
def __init__(self, num_classes):
super().__init__()
vgg = models.vgg16(pretrained=True)
# 截取 VGG 前 30 层(到 conv5_3)self.features = nn.Sequential(*list(vgg.features.children())[:-1])
# 替换全连接层
self.fc6 = nn.Conv2d(512, 4096, 7)
self.fc7 = nn.Conv2d(4096, 4096, 1)
self.score = nn.Conv2d(4096, num_classes, 1)
self.upsample = nn.ConvTranspose2d(num_classes, num_classes, 64, 32, 0)
3.2 混合损失函数实现
class HybridLoss(nn.Module):
def __init__(self, class_weights):
super().__init__()
self.cross_entropy = nn.CrossEntropyLoss(weight=torch.tensor(class_weights)
)
self.dice_loss = DiceLoss()
def forward(self, pred, target):
ce = self.cross_entropy(pred, target)
dice = self.dice_loss(pred.softmax(dim=1), target)
return 0.7*ce + 0.3*dice # 实验调优的权重比例
4. 实战注意事项
4.1 显存优化策略
- 梯度累积:每 2 个小 batch 更新一次参数
- 自动混合精度:
scaler = torch.cuda.amp.GradScaler() with torch.cuda.amp.autocast(): output = model(input) loss = criterion(output, target) scaler.scale(loss).backward()
4.2 类别不平衡处理
对 Cityscapes 数据集采用中值频率加权[3]:
class_weights = [0.8, 1.2, 1.5, ..., 2.0] # 根据类别像素频率计算
4.3 mIoU 实现要点
需注意忽略特定标签(如 255 表示背景):
def miou(pred, target, num_classes, ignore_index=255):
mask = (target != ignore_index)
pred = pred[mask].argmax(dim=1)
target = target[mask]
# 计算混淆矩阵...
进阶优化方向
5. 性能提升技巧
- 预训练权重:在 Pascal VOC 上微调仅需 1 /10 迭代次数
- 渐进式上采样:
低分辨率特征图 → 2 倍上采样 → 融合中层特征 → 再 2 倍上采样
6. 扩展思考与推荐阅读
思考题:要实现实时分割(>30FPS),可尝试:
1. 替换 backbone 为 MobileNetV3
2. 采用空洞空间金字塔池化(ASPP)
3. 知识蒸馏压缩模型
推荐论文:
– DeepLabv3+
– BiSeNet
[1] Long J, et al. Fully convolutional networks for semantic segmentation. CVPR 2015.
[2] 转置卷积可视化教程:https://github.com/vdumoulin/conv_arithmetic
[3] Eigen D, et al. Predicting Depth, Surface Normals and Semantic Labels with a Common Multi-Scale Convolutional Architecture. ICCV 2015.
正文完
发表至: 未分类
近三天内
