查看全课大纲(第 68 / 93 节)
- 1.计算机视觉概述
- 2.计算机视觉应用场景
- 3.困难与挑战
- 4.开源库介绍
- 5.图像显示与存储
- 6.CLAHE
- 7.腐蚀膨胀与开闭运算
- 8.滤波与边缘填充
- 9.各种滤波
- 10.图像金字塔
- 11.傅里叶变换
- 12.短时傅里叶变换与小波变换
- 13.颜色特征与颜色直方图
- 14.几何特征_边缘
- 15.几何特征-角点与斑点
- 16.局部特征-SIFT特征描述子
- 17.局部特征-SURF特征描述子
- 18.局部特征-ORB特征描述子
- 19.其他特征描述子
- 20.传统图像分割技术
- 21.GraphCut
- 22.GrabCut
- 23.人脸检测的传统方法
- 24.行人检测的传统方法HOG+SVM
- 25.行人检测DPM
- 26.人工神经网络的架构
- 27.目标函数与梯度下降
- 28.误差反向传播
- 29.可手算的神经网络
- 30.改进目标函数与克服梯度消散
- 31.神经网络之传统神经网络与深度网络的差异
- 32.各种梯度下降算法
- 33.如何选择合适的梯度下降算法
- 34.避免过适应
- 35.CNN的架构
- 36.CNN的误差反向传播_卷积层
- 37.CNN的误差反向传播_池化层
- 38.分类所用的数据集
- 39.Alexnet详解
- 40.VGG详解
- 41.GoogLeNet_v1
- 42.BatchNormalization
- 43.GoogLeNet_v3v4
- 44.ResNet
- 45.ResNeXt
- 46.CNN设计准则
- 47.图像检索与推土机距离
- 48.基于颜色相似性
- 49.基于形状相似性
- 50.基于纹理相似性
- 51.基于局部特征相似性
- 52.DL的二值哈希编码
- 53.高维空间中检索KDTree
- 54.高维空间中检索LSH
- 55.目标识别任务综述
- 56.RCNN
- 57.SPP-Net
- 58.Fast R-CNN
- 59.Faster R-CNN
- 60.R-CNN系列模型回顾
- 61.R-FCN的设计思路
- 62.R-FCN的实现
- 63.YOLOv1
- 64.YOLOv2_9000
- 65.YOLOv3
- 66.图像分割应用场景与数据集
- 67.上采样的实现方式
- 68.FCN网络架构的由来
- 69.FCN构建细节
- 70.DeepLabv1
- 71.CRF
- 72.DeepLabv2
- 73.DeepLabv3
- 74.特定的医学影像分割任务
- 75.U-Net
- 76.3D U-Net
- 77.V-Net
- 78.DenseNet
- 79.病理切片分析任务及数据集
- 80.病理切片分析
- 81.图说任务及其传统处理方法
- 82.深度语言模型与RNN
- 83.LSTM及其变种
- 84.NIC模型
- 85.SAT模型
- 86.图说的性能指标
- 87.判别模型与生成模型
- 88.KL散度与JS散度
- 89.VAE
- 90.GAN的基本原理
- 91.DCGAN与CGAN
- 92.Wasserstein GAN
- 93.SRGAN
FCN网络架构的由来
小象实战讲义 · 基于深度学习的计算机视觉
在 11.1 节我们了解了语义分割的基本概念和任务目标,11.2 节又补上了上采样这一必要工具。本节我们将深入探讨全卷积网络(FCN)这一里程碑式架构的由来。FCN 是首个将图像分类 CNN 通过全卷积化端到端改造为逐像素分割网络的工作(2015),是端到端全卷积语义分割的开山之作。它巧妙地改造了传统的图像分类 CNN,使其能够输出与输入图像同尺寸的分割图。理解FCN的诞生思路,是掌握现代图像分割技术发展的关键一步。
💡 核心导读
- 从分类到分割:了解如何将用于图像分类的CNN(如AlexNet)改造为适用于语义分割的全卷积网络(FCN)。
- 全卷积化:掌握将全连接层替换为卷积层的核心思想,以及由此带来的输入尺寸灵活性和空间信息保留优势。
- 上采样与跳层结构:学习FCN如何通过反卷积(上采样)恢复图像分辨率,并利用跳层结构融合深层语义信息与浅层细节信息,以得到精细的分割边界。
语义分割算法的演进与FCN的提出
图像分割任务,尤其是语义分割,其算法发展在2015年前后有一个明显的分水岭。
在2015年之前,主流方法依赖于手工提取的特征(如SIFT、HOG等)结合图模型进行推理。其中,条件随机场(Conditional Random Field, CRF) 是典型的图模型,它能够建模像素间的空间依赖关系,从而在给定图像观测值的条件下,推断出每个像素最可能的类别标签。这种方法在一定程度上能够实现语义分割,但其性能受限于手工特征的表征能力。
从2015年开始,随着深度学习在图像分类任务上取得巨大成功,研究者自然想到将其迁移到分割任务上。核心思路是:改造并利用那些在ImageNet等大型数据集上预训练好的CNN模型(如AlexNet、VGG16、GoogLeNet)。这些模型已经具备了强大的特征提取能力。
然而,传统的CNN是为图像分类设计的,直接用于分割会遇到两个根本问题:
- 空间信息丢失:CNN的后半部分通常是全连接层(Fully Connected Layers)。全连接层会将多维的特征图“展平”成一维向量,这个过程完全丧失了特征的空间排列信息。而分割任务恰恰需要为每个空间位置(像素)预测一个标签。
- 输入尺寸固定:由于全连接层的神经元数量是固定的,因此网络的输入图像尺寸也必须固定(例如AlexNet要求输入为227×227)。这限制了网络处理任意尺寸图像的能力。
全卷积网络(Fully Convolutional Networks, FCN) 的提出,正是为了解决这两个问题。其核心思想是:将网络中的所有全连接层都替换为卷积层,从而构建一个“全卷积”的网络。这样,网络可以接受任意尺寸的输入,并输出一个低分辨率的“热力图”(heatmap),其中每个空间位置都对应一个分类得分。
FCN的核心组件:全卷积化、反卷积与跳层结构
FCN架构主要由三个关键技术组件构成,下面我们逐一详解。
1. 全卷积化(Convolutionalization)
全卷积化是FCN的基础。它的操作非常直观:把CNN末尾的全连接层(FC层)全部用卷积层替代。
我们以经典的AlexNet为例进行说明。AlexNet原本的结构包含5个卷积层(Conv1-5)和3个全连接层(FC6-8)。FCN的改造如下:
- FC6层:原为4096个神经元的全连接层,每个神经元与 pool5 的全部输出相连。卷积化时,卷积核尺寸取 pool5 的空间尺寸(AlexNet 为 ,VGG 为 ),输出通道数为4096。这样当输入为 AlexNet 的标准尺寸 (VGG16 则为 )时,FC6 的输出恰好是 ;而当输入是更大的图像时,输出就变成 的分割热力图——这正是“全卷积”的关键价值。
- FC7层:原为4096个神经元、与FC6全连接。卷积化后变为 、输入输出均为4096通道的卷积层。
- FC8层:原为对应1000个ImageNet类别的输出层。改造为 的卷积层,其中 是当前分割任务的类别数(例如PASCAL VOC有21类,包括20个物体类别和1个背景类)。
需要说明的是,有些资料(包括本课原始课件)把 FC6 也简化标注为 卷积,那只是为了强调“全连接改成卷积”的结论;严格按 FCN 原论文,FC6 的卷积核尺寸等于其输入的空间尺寸,FC7、FC8 才是 卷积。
经过这样的改造,整个网络从输入到输出就全部由卷积层和池化层构成了。为什么 卷积可以等价于全连接层呢?我们可以这样理解:对于一个空间尺寸为 的输入特征图, 卷积会在每个空间位置 独立地进行一次“全连接”运算,将 个通道的信息融合成 个通道。当输入特征图的空间尺寸通过前面的池化层被压缩到 时,这个 卷积的操作就完全等同于一个传统的全连接层了。
全卷积化带来的好处:
- 任意尺寸输入:由于卷积和池化操作对输入尺寸没有硬性要求(只要步长和填充设置合理),因此FCN可以处理任意高度和宽度的输入图像。
- 输出是空间映射:网络的输出不再是一个一维的类别向量,而是一个二维的(实际上是三维 )特征图。这个特征图是输入图像经过多次下采样后的低分辨率版本,每个位置上的 维向量代表了该区域属于各个类别的得分,可以看作是一张粗糙的“分割热力图”。
2. 反卷积与上采样(Deconvolution / Upsampling)
全卷积化后,网络输出了一个低分辨率的分割热力图。仍以AlexNet为例:Conv1 的步长为4,其后又有3次步长为2的最大池化(分别接在 Conv1、Conv2、Conv5 之后),两者叠加使总下采样倍数为 。也就是说,对于一个 的输入,最终的特征图尺寸大约只有 (,取整时还需考虑填充)。
我们的目标是得到与输入图像同分辨率()的分割图。因此,我们需要将 的低分辨率热力图“放大”回原始尺寸。这个过程称为上采样(Upsampling)。在FCN的论文中,实现上采样的层被称为反卷积层(Deconvolution Layer),有时也称为转置卷积层(Transposed Convolution)。
反卷积可以理解为卷积的“逆过程”。它通过学习的卷积核,将小尺寸的输入映射到大尺寸的输出。在FCN中,最后一个反卷积层的步长被设置为32,以实现32倍的上采样,从而将输出恢复到输入图像的尺寸。
然而,直接进行32倍上采样会产生一个问题:结果非常粗糙,边界极不准确。因为从 直接插值到 ,丢失了太多的细节信息。
3. 跳层结构(Skip-layer Architecture)
为了解决直接上采样导致的边界粗糙问题,FCN引入了跳层结构。其核心思想是:融合深层特征图的语义信息和浅层特征图的细节信息。
- 深层特征:网络越深,特征图的感受野越大,捕获的语义信息(这是猫还是狗)越强,对类别的判断越准确。
- 浅层特征:网络较浅时,特征图的分辨率较高,保留了更多的细节和空间信息(物体的边缘、轮廓),但对语义的理解较弱。
跳层结构的具体操作如下(以FCN-8s为例,这是效果最好的变体;FCN-8s 以 VGG16 为基础,VGG16 有 pool1–pool5 共 5 个池化层,而本节前面举例用的 AlexNet 只有 3 个池化层、没有 pool4,下面的跳层尺度均按 VGG16 计):
- 将网络最终输出的低分辨率特征图(记为
conv8,即类别得分层,尺寸为 )进行 2倍上采样,得到尺寸为 的特征图。 - 从网络中提取较浅一层的特征图(记为
pool4,位于第4个池化层后,尺寸为 )。为了使其通道数与类别数 匹配,先通过一个 的卷积层进行降维。 - 将上采样后的
conv8特征图与处理后的pool4特征图进行逐元素相加(element-wise sum),实现特征融合。 - 将融合后的特征图再进行 2倍上采样,得到尺寸为 的特征图。
- 再提取更浅一层的特征图(
pool3,尺寸为 ),同样用 卷积调整通道数后,与上一步的特征图相加。 - 最后,对融合了
pool3细节信息的特征图进行 8倍上采样,最终得到 的分割预测图。
通过这种跳层融合,FCN-8s实际上只进行了最大8倍的上采样(而非32倍),大大降低了一次性上采样的难度,从而能够恢复出更精确的物体边界。
上采样与训练策略
从AlexNet到FCN的构建步骤
从分类网络到 FCN 的具体构建步骤(conv6/conv7/conv8 的通道数与核尺寸、FCN-32s/16s/8s 的逐级融合与上采样倍率)属于下一节《FCN 构建细节》的内容。这里只强调设计动机:把全连接层换成卷积层以获得任意尺寸输入,用反卷积恢复分辨率,用跳层融合浅层细节。具体逐层实现请见下一节。
上采样的实现与训练技巧
在FCN中,上采样(反卷积层)的训练有其特殊设定:
- 最后的反卷积层:即产生最终分割输出的那一层(如FCN-8s中的8倍上采样层)。该层的参数被固定为双线性插值核,不参与学习(学习率设为0)。双线性插值是一种确定性的、无需学习的上采样方法。
- 中间的反卷积层:跳层结构中用于融合前的上采样层(如将conv8上采样2倍的层)。这些层的参数初始化为双线性插值核,但允许在训练中进行微调(fine-tune)。
这种设定是作者通过实验发现的有效策略。固定最后的上采样层可能有助于训练的稳定性,而让中间的上采样层进行学习,可以使网络更好地学习如何将深层语义特征与浅层细节特征进行对齐和融合。
下面,我们用一个小例子来演示双线性插值上采样的效果,这是FCN中反卷积层初始化的基础。
import numpy as np
import cv2
# 创建一个2x2的简单图像(低分辨率特征图模拟)
low_res = np.array([[1, 2],
[3, 4]], dtype=np.float32)
print("低分辨率输入 (2x2):")
print(low_res)
# 使用OpenCV的resize函数进行2倍上采样(2x2 放大到 4x4),采用双线性插值
high_res = cv2.resize(low_res, (4, 4), interpolation=cv2.INTER_LINEAR)
print("\n双线性插值上采样后 (4x4):")
print(high_res)低分辨率输入 (2x2):
[[1. 2.]
[3. 4.]]
双线性插值上采样后 (4x4):
[[1. 1.25 1.75 2. ]
[1.5 1.75 2.25 2.5 ]
[2.5 2.75 3.25 3.5 ]
[3. 3.25 3.75 4. ]]可以看到,双线性插值根据相邻像素的值,平滑地生成了中间像素的值。在FCN中,用于上采样的反卷积核如果初始化为实现双线性插值的权重,那么在训练初期,上采样的行为就是平滑的插值。
一个简化的跳层融合概念演示
为了更直观地理解跳层融合中“相加”的操作,我们构造一个极度简化的例子。假设深层特征图代表“这是猫”的语义信心,浅层特征图代表“这里是边缘”的细节信心。
import numpy as np
# 模拟深层特征图 (粗糙的语义信息) - 经过上采样后与浅层同尺寸
# 值高表示“是猫”的信心高
deep_feat = np.array([[0.1, 0.1, 0.8, 0.8],
[0.1, 0.1, 0.8, 0.8],
[0.8, 0.8, 0.2, 0.2],
[0.8, 0.8, 0.2, 0.2]])
# 模拟浅层特征图 (精细的边缘细节)
# 值高表示“是边缘”的信心高
shallow_feat = np.array([[0.0, 0.9, 0.9, 0.0],
[0.0, 0.9, 0.9, 0.0],
[0.0, 0.9, 0.9, 0.0],
[0.0, 0.9, 0.9, 0.0]])
print("深层语义特征图 (4x4):")
print(deep_feat)
print("\n浅层细节特征图 (4x4):")
print(shallow_feat)
# 跳层融合:逐元素相加
fused_feat = deep_feat + shallow_feat
print("\n跳层融合后特征图 (deep + shallow):")
print(fused_feat)深层语义特征图 (4x4):
[[0.1 0.1 0.8 0.8]
[0.1 0.1 0.8 0.8]
[0.8 0.8 0.2 0.2]
[0.8 0.8 0.2 0.2]]
浅层细节特征图 (4x4):
[[0. 0.9 0.9 0. ]
[0. 0.9 0.9 0. ]
[0. 0.9 0.9 0. ]
[0. 0.9 0.9 0. ]]
跳层融合后特征图 (deep + shallow):
[[0.1 1. 1.7 0.8]
[0.1 1. 1.7 0.8]
[0.8 1.7 1.1 0.2]
[0.8 1.7 1.1 0.2]]观察融合后的特征图:在第二、三列(浅层特征指示的边缘区域),融合后的值显著提高了。这意味着网络在预测时,会对这些边缘区域赋予更高的权重,从而有助于最终分割图在边界处产生更准确、更锐利的变化。
2026 视角
FCN发表于2015年,是深度学习语义分割的开山之作,其思想影响深远。从今天的视角回看:
- 架构思想的延续:FCN提出的“编码器-解码器”结构(下采样提取特征,上采样恢复尺寸)成为后续许多分割网络的基础范式,U-Net、SegNet 以及 DeepLab v3+ 都沿着这条路线展开。其“跳层连接”思想在U-Net中被发扬光大。
- 全卷积成为标准:在现代分割模型中,全连接层已基本被摒弃,全卷积设计成为标准做法,确保了网络对输入尺寸的灵活性。
- 技术细节的演进:FCN中使用的“反卷积”(转置卷积)和双线性插值初始化仍是常用技术。然而,后续研究也提出了更多样的上采样方式,如Pixel Shuffle(亚像素卷积)、以及DeepLab系列倡导的“空洞卷积(Dilated Convolution)”配合普通上采样,以减少信息损失。
- 从FCN到现代模型:FCN的主要局限在于上采样后的分割结果依然不够精细,尤其是物体边界。后续的DeepLab系列通过引入空洞卷积和条件随机场(CRF)后处理来优化边界;U-Net则通过更密集的跳层连接和对称结构在生物医学图像上取得巨大成功。而如今,基于Transformer的架构(如SETR、Segmenter)和视觉基础模型(如SAM)正在引领新的方向,但FCN所确立的基本框架仍在许多场景中发挥着重要作用。
📝 动手练一练
- 概念辨析:全连接层和 卷积层在什么情况下是等价的?为什么将全连接层替换为卷积层后,网络就能接受任意尺寸的输入了?
👉 点击查看参考答案
- 等价条件:当 卷积层的输入特征图的空间尺寸(高度和宽度)均为 时,它与全连接层完全等价。此时,输入可以看作是一个 维的向量, 卷积操作就是用 个 的卷积核分别对这个向量做内积,得到 维的输出向量,这与全连接层的矩阵乘法运算一致。
- 任意尺寸输入:卷积和池化是局部操作,其输出尺寸由输入尺寸、卷积核大小、步长和填充共同决定。只要这些参数设置合理(例如使用
padding='same'),它们对输入尺寸没有固定要求。替换掉神经元数量固定的全连接层后,网络便由这些对尺寸友好的操作构成,因此可以处理任意尺寸的输入,并输出相应尺寸的特征图。
本章小结
本节我们深入剖析了全卷积网络(FCN)架构的由来与核心组件。FCN通过全卷积化改造,解决了传统CNN用于分割时空间信息丢失和输入尺寸固定的问题。通过反卷积(上采样),它将低分辨率的分割热力图恢复至输入尺寸。而关键的跳层结构,通过融合深层网络的强语义信息与浅层网络的精细空间信息,显著提升了分割边界的准确性。FCN-8s是这一架构的最佳实践,它奠定了编码器-解码器分割模型的基础。
📋 行动清单
- 复述 FCN 的三个核心组件(全卷积化、反卷积、跳层)各自解决什么问题,以及 FCN-8s 为何要融合三个尺度。
- 思考并解释:为什么跳层结构能改善分割边界?如果只用最深层的特征进行32倍上采样(FCN-32s),主要问题会是什么?
- (可选)尝试用NumPy手动计算一个2x2矩阵经过双线性插值上采样到4x4的结果,加深对插值原理的理解。
—— 小象教研组