查看全课大纲(第 69 / 93 节)
  1. 1.计算机视觉概述
  2. 2.计算机视觉应用场景
  3. 3.困难与挑战
  4. 4.开源库介绍
  5. 5.图像显示与存储
  6. 6.CLAHE
  7. 7.腐蚀膨胀与开闭运算
  8. 8.滤波与边缘填充
  9. 9.各种滤波
  10. 10.图像金字塔
  11. 11.傅里叶变换
  12. 12.短时傅里叶变换与小波变换
  13. 13.颜色特征与颜色直方图
  14. 14.几何特征_边缘
  15. 15.几何特征-角点与斑点
  16. 16.局部特征-SIFT特征描述子
  17. 17.局部特征-SURF特征描述子
  18. 18.局部特征-ORB特征描述子
  19. 19.其他特征描述子
  20. 20.传统图像分割技术
  21. 21.GraphCut
  22. 22.GrabCut
  23. 23.人脸检测的传统方法
  24. 24.行人检测的传统方法HOG+SVM
  25. 25.行人检测DPM
  26. 26.人工神经网络的架构
  27. 27.目标函数与梯度下降
  28. 28.误差反向传播
  29. 29.可手算的神经网络
  30. 30.改进目标函数与克服梯度消散
  31. 31.神经网络之传统神经网络与深度网络的差异
  32. 32.各种梯度下降算法
  33. 33.如何选择合适的梯度下降算法
  34. 34.避免过适应
  35. 35.CNN的架构
  36. 36.CNN的误差反向传播_卷积层
  37. 37.CNN的误差反向传播_池化层
  38. 38.分类所用的数据集
  39. 39.Alexnet详解
  40. 40.VGG详解
  41. 41.GoogLeNet_v1
  42. 42.BatchNormalization
  43. 43.GoogLeNet_v3v4
  44. 44.ResNet
  45. 45.ResNeXt
  46. 46.CNN设计准则
  47. 47.图像检索与推土机距离
  48. 48.基于颜色相似性
  49. 49.基于形状相似性
  50. 50.基于纹理相似性
  51. 51.基于局部特征相似性
  52. 52.DL的二值哈希编码
  53. 53.高维空间中检索KDTree
  54. 54.高维空间中检索LSH
  55. 55.目标识别任务综述
  56. 56.RCNN
  57. 57.SPP-Net
  58. 58.Fast R-CNN
  59. 59.Faster R-CNN
  60. 60.R-CNN系列模型回顾
  61. 61.R-FCN的设计思路
  62. 62.R-FCN的实现
  63. 63.YOLOv1
  64. 64.YOLOv2_9000
  65. 65.YOLOv3
  66. 66.图像分割应用场景与数据集
  67. 67.上采样的实现方式
  68. 68.FCN网络架构的由来
  69. 69.FCN构建细节
  70. 70.DeepLabv1
  71. 71.CRF
  72. 72.DeepLabv2
  73. 73.DeepLabv3
  74. 74.特定的医学影像分割任务
  75. 75.U-Net
  76. 76.3D U-Net
  77. 77.V-Net
  78. 78.DenseNet
  79. 79.病理切片分析任务及数据集
  80. 80.病理切片分析
  81. 81.图说任务及其传统处理方法
  82. 82.深度语言模型与RNN
  83. 83.LSTM及其变种
  84. 84.NIC模型
  85. 85.SAT模型
  86. 86.图说的性能指标
  87. 87.判别模型与生成模型
  88. 88.KL散度与JS散度
  89. 89.VAE
  90. 90.GAN的基本原理
  91. 91.DCGAN与CGAN
  92. 92.Wasserstein GAN
  93. 93.SRGAN

FCN构建细节

小象实战讲义 · 基于深度学习的计算机视觉

在上一节,我们学习了全卷积网络(FCN)的核心思想:通过卷积化、反卷积和跳层结构,将用于图像分类的深度网络改造为能够输出逐像素类别预测的分割网络。本节,我们将深入FCN的构建细节,从一张复杂的架构图出发,一步步拆解其网络结构、尺度变化、以及如何从VGG等主干网络改造而来。你将彻底理解FCN-32s、FCN-16s和FCN-8s的区别,并掌握其训练与初始化的关键技巧。

💡 核心导读

  • 架构图解析:通过一张颜色编码的FCN整体架构图,理解卷积、池化、融合(逐像素相加)、反卷积(上采样)和裁剪层的作用与数据流向。
  • 尺度变化推演:从输入图像(500×500)出发,详细推演经过大量补零(padding=100)、连续池化后特征图尺度的变化过程,直至最终的预测输出。
  • 从VGG改造FCN:学习如何将VGG网络的全连接层替换为卷积层,并依次构建出FCN-32s、FCN-16s和FCN-8s三种不同精度的网络变体。
  • 训练细节与性能:了解FCN训练时使用的优化器、学习率设置、参数初始化策略,并对比不同变体及不同主干网络(VGG, GoogLeNet, AlexNet)在Pascal VOC数据集上的分割性能。

整体架构图解析

FCN的完整网络架构图初看可能有些复杂,但它清晰地展示了数据从输入到输出的完整流程。为了便于理解,图中使用不同颜色对各类层进行了编码:

  • 蓝色:卷积层(Convolutional Layer),负责特征提取。
  • 绿色:池化层(Pooling Layer,图中主要为最大池化),用于下采样,扩大感受野。
  • 黄色:融合层(Fusion Layer),即逐像素相加(element-wise sum) 操作,用于融合来自不同深度的特征图。
  • 橙色:反卷积层(Deconvolution Layer),其核心作用是上采样(Upsampling),将低分辨率特征图恢复到高分辨率。
  • 灰色:裁剪层(Crop Layer),目的是统一尺寸,确保最终输出与输入图像尺寸一致。

理解这张图的关键在于追踪特征图尺度(分辨率)的变化关系。让我们从输入开始,一步步推导。

输入与初始补零(Padding) 网络的输入图像尺寸为 500×500×3(高×宽×RGB通道)。然而,你可能会注意到,图中第一个卷积层的输入尺度远大于500。这是因为作者在输入图像周围进行了大量的补零操作。

具体来说,在第一个卷积层,图像在两个方向(高度和宽度)上各补了 100 层零。因此,实际的卷积输入尺寸从 500×500 扩大到了 700×700。这种做法在当时被一些后续研究者诟病,但其目的是为了应对后续连续的五次池化(下采样)操作。如果初始尺寸太小,经过32倍(252^5)下采样后,特征图会变得过小(可能只有几个像素),丢失大量空间信息,使得后续的上采样恢复异常困难。因此,前置大量补零是为了让网络在深度特征提取后,仍保留一定的空间尺度供上采样重建。

下采样路径(编码器)尺度推演 从补零后的 700×700 开始,我们跟随卷积与池化层推演尺度变化:

  1. 第一次卷积与池化:conv1_1(3×3,padding=100)先把补零后的 700×700 收缩为 698×698(700 - 3 + 1);第一次池化后:698 / 2 = 349 → 349×349
  2. 第二次池化后:349 / 2 = 174.5,四舍五入后为 175×175
  3. 第三次池化后:175 / 2 = 87.5,四舍五入后为 88×88
  4. 第四次池化后:88 / 2 = 44 → 44×44
  5. 第五次池化后:44 / 2 = 22 → 22×22

至此,我们得到了图中标注的 22×22 的特征图,这也是原始图像经过32倍下采样后的结果。

改造与上采样路径(解码器)尺度推演 FCN对主干网络的改造始于第五次池化之后。改造的起始层(即第一个全连接层被替换后的卷积层)尺度为 16×16(从22×22经过卷积略有收缩)。选择16×16而非更小的尺度,也是为了避免信息过度压缩,为上采样保留基础。

接着是上采样过程:

  1. 从 16×16 上采样到 34×34:简单 2 倍只有 32,多出的 2 像素来自反卷积在边界处的扩张(恰好一个步长)。
  2. 进一步上采样到 70×70:同理,34×2=68,边界再扩张 2 像素。
  3. 再次上采样到 568×568:70×8=560,边界扩张 8 像素(也恰好是一个步长)。
  4. 最后,通过灰色裁剪层将 568×568 裁剪至 500×500,与输入图像尺寸保持一致,并输出 500×500×21 的最终预测结果(21对应Pascal VOC数据集的20个物体类别+1个背景类)。

从VGG网络改造FCN

FCN可以使用多种分类网络作为其主干(Backbone),如AlexNet、VGG、GoogLeNet等。实验表明,使用VGG16作为主干网络时,FCN的性能最好。这可能是因为VGG结构规整、深度适中,在迁移到分割任务时泛化能力更强,而GoogLeNet等网络可能对分类任务有些过拟合。

改造的核心步骤是卷积化(Convolutionalization):将网络末端的全连接层替换为卷积层。

第一步:构建FCN-32s 这是最基础的变体。我们以VGG16为例:

  1. 保留VGG16的前5个卷积块(包含卷积和池化层)及其预训练参数。
  2. 舍弃最后的三个全连接层(FC6, FC7, FC8)。
  3. 将原来的FC6、FC7(在空间上可视为1×1×4096的全连接层)替换为两个卷积层:conv6的卷积核为7×7、输出通道4096,把22×22的特征图收缩为16×16×4096;conv7的卷积核为1×1、输出通道4096,保持16×16×4096。
  4. 追加一个预测卷积层(相当于原来的FC8),卷积核1×1,输出通道为21(Pascal VOC类别数),得到 16×16×21 的特征图。
  5. 最后,直接追加一个步长为32的反卷积层进行上采样。该层固定为双线性插值,不参与学习。上采样后得到粗略的分割图,再经裁剪得到 500×500×21 的输出。

FCN-32s因为一次性上采样32倍,边缘信息丢失严重,结果非常模糊。

第二步:构建FCN-16s 为了改善边缘,FCN引入了跳层结构(Skip Architecture),融合浅层特征。FCN-16s利用了pool4层的输出(尺度为44×44)。

  1. 首先,如FCN-32s一样,conv7(即改造后的最后一层卷积)输出16×16×4096,再经1×1预测卷积把通道数降为21,得到16×16×21。
  2. 对上述 16×16×21 的预测结果进行2倍上采样,得到 34×34×21 的特征图。
  3. 另一方面,对pool4的输出(44×44×512)施加一个1×1的卷积层,将其通道数调整为21,得到 44×44×21 的特征图。
  4. 将pool4调整后的特征图裁剪至与上采样后的conv7特征图尺度一致(34×34)。
  5. 将两个 34×34×21 的特征图进行逐像素相加(融合)。
  6. 最后,对融合结果进行步长为16的反卷积上采样(同样固定为双线性插值),再裁剪至500×500。

通过融合pool4(下采样16倍)的特征,FCN-16s只需上采样16倍,保留了更多细节。

第三步:构建FCN-8s 为了进一步精化,FCN-8s继续融合了更浅的pool3层(尺度为88×88)的特征。

  1. 取FCN-16s中融合后的特征图(34×34×21)。
  2. 对其进行2倍上采样,得到约 70×70×21 的特征图。
  3. 对pool3的输出(88×88×256)施加1×1卷积调整通道至21,得到 88×88×21 的特征图,并裁剪至 70×70。
  4. 将两者逐像素相加融合。
  5. 最后,对融合结果进行步长为8的反卷积上采样,再裁剪得到最终输出。

FCN-8s融合了pool3(下采样8倍)的细节信息,只需上采样8倍,因此在三种变体中边缘恢复效果最好,性能最优。

import numpy as np

# 模拟特征图融合(逐像素相加)操作
# 假设我们有两个来自不同层的特征图,经过调整后尺寸相同
np.random.seed(42) # 固定随机种子,确保输出确定
# 模拟裁剪到 70x70 的 pool3 分支特征图 (70x70x21),量级稍小
feat_pool3 = np.random.randn(70, 70, 21) * 0.1
# 模拟上采样到 70x70 的 conv7 分支特征图 (70x70x21),量级稍大并带一个偏置
feat_conv7_up = np.random.randn(70, 70, 21) * 0.5 + 0.2

# FCN-8s 的融合操作:逐像素相加
fused_feat_8s = feat_pool3 + feat_conv7_up

print("融合后特征图形状:", fused_feat_8s.shape)
print("融合后特征图左上角第一个通道的左上角3x3区域值:")
print(fused_feat_8s[:3, :3, 0].round(4))
融合后特征图形状: (70, 70, 21)
融合后特征图左上角第一个通道的左上角3x3区域值:
[[ 0.4837  0.3823 -0.0123]
 [-0.2251 -0.3674  0.1658]
 [-0.4036  1.4204  0.6168]]

训练细节与初始化

FCN的训练采用了一些经典且有效的技巧:

  • 优化器:使用带动量(Momentum)的随机梯度下降(SGD),动量参数设置为0.9。
  • 学习率(Learning Rate):学习率的设置与网络复杂度相关。网络越复杂,学习率应设置得越小,以防止震荡。
    • AlexNet: 0.001
    • VGG16: 0.0001
    • GoogLeNet: 0.00001 (再小一个数量级)
  • 小批量大小(Mini-batch Size):设置为20。
  • 参数初始化:
    • 卷积层:前5个卷积层(来自VGG16主干)直接使用在ImageNet上预训练好的参数。新增的conv6、conv7并不是置零初始化,而是用 net surgery(网络手术) 把VGG16的fc6、fc7权重直接重塑迁移过来:fc6 的 4096×25088 权重重塑为 4096×512×7×7 的 conv6 卷积核,fc7 的 4096×4096 权重复制为 conv7 的 1×1 卷积核。这正是“卷积化”的本义——保留预训练学到的表征,迁移完成后整个网络一起 fine-tune。
    • 反卷积层(上采样层):最后一层(即直接输出最终尺寸的反卷积层)固定为双线性插值核,不进行学习。中间的反卷积层(如FCN-16s、FCN-8s中用于2倍上采样的层)则初始化为双线性插值核,但允许在训练中学习调整。

性能对比与分析

根据论文中的实验结果,我们可以得出以下结论:

  1. 跳层结构有效性:FCN-8s > FCN-16s > FCN-32s。FCN-32s的结果边缘模糊,几乎难以辨认物体轮廓;而FCN-8s的结果则与真实标注(Ground Truth)非常接近。这证明了融合浅层特征对恢复细节至关重要。
  2. 主干网络性能:在AlexNet、VGG16、GoogLeNet中,VGG16作为FCN主干时性能最好。这印证了之前关于VGG结构泛化能力更强的分析。
  3. 主干微调的必要性:性能表中还给出了带 fixed 标记的版本,它指主干网络(VGG16)的权重被固定、不做 fine-tuning。此时效果明显变差,说明只替换分类头而不微调主干是不够的。
  4. FCN的局限性:
    • 大量补零:第一层补100像素的零,虽然保证了后续尺度,但也引入了大量无效的边界噪声。
    • 频繁裁剪:为了对齐不同分支的特征图尺寸以进行相加,以及最终匹配输入尺寸,网络中多次使用裁剪层,这并非一个优雅的设计。
    • 边缘准确性:尽管FCN-8s有很大改善,但其分割结果的边缘精确度仍有提升空间,这与一次性上采样/反卷积的方式有关。

针对这些问题,分割领域给出了不同的解法:DeepLab 系列用空洞卷积避免过度下采样,U-Net 用对称的编码解码结构与跳跃连接恢复细节。

📝 动手练一练

  1. 概念辨析:FCN-32s、FCN-16s和FCN-8s中的数字(32, 16, 8)代表什么含义?这三种结构最主要的区别是什么?
  2. 尺度计算:假设我们有一张输入图像尺寸为384×384,使用VGG16作为主干(5次步长为2的池化),且不在第一层补零。请问特征图经过第五次池化后,尺度会变为多少?如果我们要构建FCN-8s,需要对哪几层的特征进行融合?
👉 点击查看参考答案
  1. 含义与区别:

    • 数字代表网络最终输出前,所需进行的上采样倍数。FCN-32s需要一次性上采样32倍,FCN-16s需要上采样16倍,FCN-8s需要上采样8倍。
    • 最主要的区别在于跳层融合的特征来源不同。FCN-32s不进行跳层融合;FCN-16s融合了pool4层的特征;FCN-8s则进一步融合了pool3层的特征。融合的层越浅(下采样倍数越小),其特征图分辨率越高,包含的空间细节越多,因此FCN-8s的边缘恢复能力最强。
  2. 尺度计算:

    • 输入384×384,经过5次/2的池化,最终尺度为 384 / (2^5) = 384 / 32 = 12。因此,第五次池化后的特征图尺度为 12×12。
    • FCN-8s 融合的是三路不同尺度的信息:pool3(下采样 8 倍,48×48)、pool4(下采样 16 倍,24×24)与 conv7(下采样 32 倍,12×12;再经 conv6 的 7×7 无填充卷积收缩后实际为 6×6,此处按各路下采样倍数近似标注)。做法分两级:先把 conv7 的 21 通道预测结果 2 倍上采样,与 pool4 的预测结果相加(这一级输出的是 16 倍分辨率的 FCN-16s 融合特征);再把这个融合结果 2 倍上采样,与 pool3 的预测结果相加。因此最后一级直接参与相加的是 pool3(8 倍)与 FCN-16s 的融合结果(其中包含 16 倍的 pool4 和 32 倍的 conv7)。

本章小结

本节我们深入剖析了全卷积网络(FCN)的构建细节。我们从一张总览图出发,理解了网络中每一类层的作用,并详细推演了特征图尺度变化的完整链条,特别是理解了初始大量补零的缘由。我们重点学习了如何从VGG16分类网络改造出FCN,并逐步构建出精度不断提升的FCN-32s、FCN-16s和FCN-8s变体,其核心在于利用跳层结构融合浅层高分辨率特征来优化上采样结果。最后,我们掌握了FCN的关键训练参数与初始化方法,并通过性能对比认识到其优势与局限性。FCN作为深度学习语义分割的开山之作,其“全卷积”与“跳层融合”的思想影响深远;但需要说明的是,这套具体结构在今天已基本退出主流,它的历史价值在于奠定范式,现代分割架构的演进见下方「2026 视角」。

📋 行动清单

  • 在白纸或绘图软件上,尝试画出FCN-8s的数据流图,标出pool3, pool4, conv7等关键层及其尺度变化。
  • 思考并回答:如果不使用反卷积,还有哪些方法可以实现特征图的上采样?它们各有何优缺点?
  • (进阶)假设现在有一个更深的分类网络(如ResNet-50),你如何借鉴FCN的思想,将其改造成一个分割网络?会遇到什么新的挑战?

2026 视角

FCN在2015年提出的“全卷积”与“跳层融合”范式,为深度学习语义分割奠定了坚实基础。站在2026年的视角回望,分割领域已涌现出诸多超越FCN局限性的强大架构与范式:

  • Transformer与通用架构的崛起:以Vision Transformer(ViT)为代表的视觉Transformer模型,通过自注意力机制捕获全局上下文,在分割任务上表现出色。而Mask2Former等通用架构,通过设计统一的掩码分类头,能够同时处理语义分割、实例分割和全景分割任务,展现了强大的通用性和高性能,成为当前研究与应用的热点。
  • 提示式分割与交互智能:2023年发布的SAM(Segment Anything Model) 带来了范式变革。SAM是一个超大规模的提示式分割基础模型,它可以根据点、框、掩码等简单提示,零样本地分割出图像中的任何物体(文本提示需要外接检测模型配合)。这极大地降低了分割任务的应用门槛,使得图像编辑、数据标注、机器人交互等场景变得更加智能和便捷。
  • 更高效的解码器设计:FCN中简单的反卷积上采样已被更复杂的解码器结构所取代。例如,DeepLabv3+ 引入了包含空间金字塔池化(ASPP)的编码器和轻量级解码器;U-Net及其变体的对称编码-解码结构配合密集跳跃连接,在医学影像等领域仍是黄金标准。这些设计能更好地恢复细节和边界。
  • 端到端实例分割:FCN主要解决语义分割(同类物体不区分个体)。如今,如Mask R-CNN(在Faster R-CNN上增加掩码头)、YOLACT、SOLO等端到端实例分割网络,能够直接输出每个物体实例的掩码,满足了更细粒度的分割需求。

尽管FCN的具体网络结构已非主流,但其核心思想——摒弃全连接、保持空间维度、融合多尺度特征——已深深融入现代分割网络的血液之中。学习FCN,正是理解这一领域演进脉络的关键起点。

—— 小象教研组