共计 2157 个字符,预计需要花费 6 分钟才能阅读完成。
背景痛点
传统 CNN 在图像分割任务中存在两个主要缺陷:

-
固定尺寸输入限制:传统 CNN 要求输入图像尺寸固定,这在实际应用中非常不便。比如医学图像往往尺寸各异,强行 resize 会导致信息丢失或变形。
-
空间信息丢失:CNN 通过全连接层输出固定长度的特征向量,丢失了原始图像中的空间位置信息,而分割任务恰恰需要精确的像素级定位。
技术对比
FCN vs U-Net vs DeepLab
- FCN:
- 优点:完全卷积化,可接受任意尺寸输入;通过反卷积恢复空间信息;计算效率高
-
缺点:细节恢复能力有限,小物体分割效果一般
-
U-Net:
- 优点:对称编码器 - 解码器结构,跳跃连接保留更多细节;适合医学图像
-
缺点:参数量较大,训练时间更长
-
DeepLab:
- 优点:ASPP 模块有效捕获多尺度信息;空洞卷积保持感受野
- 缺点:计算复杂度高,显存占用大
核心实现
PyTorch 实现 FCN-8s
import torch
import torch.nn as nn
from torchvision import models
class FCN8s(nn.Module):
def __init__(self, num_classes):
super().__init__()
# 加载预训练 VGG16
vgg = models.vgg16(pretrained=True)
features = list(vgg.features.children())
# 编码器部分
self.features3 = nn.Sequential(*features[:17]) # 到 conv3_3
self.features4 = nn.Sequential(*features[17:24]) # 到 conv4_3
self.features5 = nn.Sequential(*features[24:]) # 到 conv5_3
# 反卷积层
self.upscore2 = nn.ConvTranspose2d(num_classes, num_classes, 4, stride=2, padding=1)
self.upscore_pool4 = nn.ConvTranspose2d(num_classes, num_classes, 4, stride=2, padding=1)
self.upscore8 = nn.ConvTranspose2d(num_classes, num_classes, 16, stride=8, padding=4)
# 跳跃连接调整层
self.score_pool4 = nn.Conv2d(512, num_classes, 1)
self.score_pool3 = nn.Conv2d(256, num_classes, 1)
def forward(self, x):
# 前向传播逻辑
pool3 = self.features3(x)
pool4 = self.features4(pool3)
pool5 = self.features5(pool4)
# 反卷积过程
score5 = self.score_pool5(pool5)
upscore5 = self.upscore2(score5)
score4 = self.score_pool4(pool4)
score4 += upscore5 # 第一次跳跃连接
upscore4 = self.upscore_pool4(score4)
score3 = self.score_pool3(pool3)
score3 += upscore4 # 第二次跳跃连接
# 最终上采样
output = self.upscore8(score3)
return output
反卷积层数学原理
关键参数解释:
kernel_size=4:决定了每个输出像素受周围多少个输入像素影响stride=2:输出尺寸是输入的两倍padding=1:保证输出尺寸计算正确,公式为:output_size = (input_size - 1)*stride + kernel_size - 2*padding
性能优化
混合精度训练
from torch.cuda.amp import autocast, GradScaler
scaler = GradScaler()
with autocast():
output = model(input)
loss = criterion(output, target)
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
TensorRT INT8 量化
- 校准过程:收集激活值统计信息
- 生成量化引擎:
trtexec --onnx=fcn.onnx --int8 --saveEngine=fcn_int8.engine
避坑指南
边缘处理策略
- 推荐使用
reflectpadding 模式,避免引入人工边缘 - 对于医学图像,可考虑
replicate模式
类别不平衡
- 使用加权交叉熵损失:
class_weights = 1 / torch.log(freq + 1e-6) criterion = nn.CrossEntropyLoss(weight=class_weights)
BN 层固定
验证阶段必须设置:
model.eval()
with torch.no_grad():
output = model(input)
开放问题
在处理 4K 医学图像时,FCN 的哪些设计会成为性能瓶颈?如何改进?欢迎在评论区分享你的见解。
正文完
发表至: 未分类
近一天内
