标准卷积神经网络,特别是那些为图像分类任务设计的网络,例如VGG或ResNet,通常以一个或多个全连接层结束。这些层将卷积滤波器学习到的空间信息汇聚成一个固定大小的向量,适用于为整个输入图像预测单一类别标签。然而,这种汇聚过程丢弃了分割任务所需的精确空间信息,因为分割要求对每个像素进行预测。如果将最后一个卷积层的特征图展平,就会丢失其二维结构。由Long、Shelhamer和Darrell提出的全卷积网络(FCNs)提供了一种巧妙的办法。其基本思路是将分类网络中的全连接层替换为等效的卷积层。例如,一个作用于$7 \times 7 \times 512$特征图(在VGG的最终分类层之前很常见)的全连接层,可以看作是对该特征图应用一个$7 \times 7$卷积核的卷积操作,为每个滤波器(类别)生成一个$1 \times 1$的输出图。通过使用$1 \times 1$卷积代替全连接层,FCNs在整个网络中保持了空间尺寸,使其能够输出与输入图像空间布局相对应的热图或密集预测图。编码器-解码器结构FCNs通常采用编码器-解码器结构:编码器(下采样路径): 这部分通常是一个预训练的分类网络(如VGG、ResNet),其中最终的全连接层已被移除或转换为卷积层。随着数据流经编码器,一系列卷积和池化操作逐渐降低空间分辨率($H \times W$),同时增加特征深度($C$)。这捕捉到日益复杂的语义特征,但会损失精细的空间细节。解码器(上采样路径): 为了生成与输入图像分辨率相同的分割图,网络需要对编码器输出的低分辨率、高深度特征图进行上采样。FCNs中实现此目的的主要机制是转置卷积(有时称为反卷积)。转置卷积操作本质上是常规卷积空间变换的逆过程,它增加了特征图的高度和宽度,同时可能减小其深度。它是一个可学习的上采样层。通过跳跃连接恢复细节基本编码器-解码器结构的一个重要难题是,深度、低分辨率的特征图虽然捕获了语义信息,但却缺少在池化过程中丢失的精确位置信息。仅对这些粗糙的图进行上采样,通常会导致分割边界模糊或定义不清。FCNs通过加入跳跃连接来解决这个问题。这些连接将编码器中较早、高分辨率层的特征图直接连接到解码器中相应的层。解码器随后将来自深层网络的粗粒度语义信息与来自浅层网络的精细空间细节结合起来。例如,深层编码器层的输出可能会被上采样2倍。这个上采样后的图会与来自具有相同空间尺寸的早期编码器层的特征图进行逐元素相加。这个组合后的图随后会进一步上采样,并可能与更早层的特征结合。digraph FCN { rankdir=LR; node [shape=box, style=filled, fillcolor="#e9ecef", fontname="Helvetica"]; subgraph cluster_encoder { label = "编码器 (下采样)"; bgcolor="#f8f9fa"; style=dashed; Input [label="输入图像\nH x W x 3", fillcolor="#a5d8ff"]; E1 [label="卷积/池化 1\nH/2 x W/2 x C1", fillcolor="#74c0fc"]; E2 [label="卷积/池化 2\nH/4 x W/4 x C2", fillcolor="#4dabf7"]; E3 [label="卷积/池化 3\nH/8 x W/8 x C3", fillcolor="#339af0"]; E4 [label="卷积/池化 4\nH/16 x W/16 x C4", fillcolor="#228be6"]; E5 [label="卷积/池化 5\nH/32 x W/32 x C5", fillcolor="#1c7ed6"]; Input -> E1 -> E2 -> E3 -> E4 -> E5; } subgraph cluster_decoder { label = "解码器 (上采样)"; bgcolor="#fff9db"; style=dashed; D5 [label="1x1 卷积 (类别)\nH/32 x W/32 x N", fillcolor="#ffec99"]; Up5 [label="上采样 (x2)\nH/16 x W/16 x N", fillcolor="#ffe066"]; Sum4 [label="求和 (+)", shape=circle, style=filled, fillcolor="#ced4da"]; Up4 [label="上采样 (x2)\nH/8 x W/8 x N", fillcolor="#ffd43b"]; Sum3 [label="求和 (+)", shape=circle, style=filled, fillcolor="#ced4da"]; Up3 [label="上采样 (xN)\n(例如,FCN-8s 为 x8)\nH x W x N", fillcolor="#fcc419"]; Output [label="分割图\nH x W x N_classes", fillcolor="#fab005"]; D5 -> Up5 -> Sum4 -> Up4 -> Sum3 -> Up3 -> Output; } E5 -> D5; // 跳跃连接 E4 -> Sum4 [label="跳跃", color="#868e96", style=dashed, fontcolor="#868e96"]; E3 -> Sum3 [label="跳跃", color="#868e96", style=dashed, fontcolor="#868e96"]; // FCN-8s 可能添加 E2 跳跃,但为了图表简洁,此处不添加 // E2 -> 某个中间点 -> Up3 [label="跳跃", color="#868e96", style=dashed, fontcolor="#868e96"] // 如果需要,调整排名以获得更好的布局 {rank=same; E1; } {rank=same; E2; } {rank=same; E3; Sum3;} {rank=same; E4; Sum4;} {rank=same; E5; D5; Up5;} {rank=same; Output; Up3;} }简化的FCN架构,展示了编码器如何降低分辨率,解码器如何通过上采样提高分辨率,以及跳跃连接如何结合不同阶段的特征。N表示分割类别的数量。FCN 变体:FCN-32s、FCN-16s、FCN-8s最初的FCN论文根据最终预测层的步幅和所使用的跳跃连接数量提出了几种变体:FCN-32s: 这是最简单的版本。它获取最终池化层的输出(相对于输入已下采样32倍),应用一个$1 \times 1$卷积来预测类别分数,然后使用步幅为32的转置卷积,在一步中将这个粗糙的图上采样回原始图像分辨率。不使用跳跃连接。结果通常非常粗糙。FCN-16s: 该版本在FCN-32s的基础上有所改进。它将步幅为32的预测图上采样2倍,并与前一个池化层(pool4,步幅16)的预测结果进行结合(逐元素相加)。这个组合后的图随后上采样16倍,以达到最终分辨率。FCN-8s: 这进一步完善了处理过程。它将步幅为32的预测(上采样2倍)与步幅为16的预测(pool4)结合,将结果上采样2倍,然后与更早层(pool3,步幅8)的预测结果结合。最后,这个组合后的图上采样8倍。每个后续变体(32s -> 16s -> 8s)都从更早的层引入了更精细的细节,使得分割边界逐渐变得更清晰、更准确。FCN的训练FCNs通常使用像素级损失函数进行端到端训练。最常见的选择是独立计算每个像素的平均交叉熵损失。对于单个像素$i$,损失为$L_i = -\sum_{c=1}^{N_{类别}} y_{i,c} \log(p_{i,c})$,其中如果像素$i$的真实类别是$c$,则$y_{i,c}$为1,否则为0;$p_{i,c}$是预测的像素$i$属于类别$c$的概率(通常在softmax激活后)。图像的总损失是所有像素$L_i$的平均值。重要性与局限FCNs在深度学习的语义分割方面取得了重大进展。它们表明卷积网络可以进行端到端训练以完成密集预测任务,并有效使用预训练的分类网络。它们还提出了将全连接层转换为卷积层以及使用跳跃连接来合并多层特征的有效思路。然而,FCNs仍然存在局限性:粗糙边界: 即使是FCN-8s,其生成的分割掩码也可能无法与物体边界完美对齐,部分原因是池化和上采样操作的固定特性。固定上采样: 使用简单的双线性插值或转置卷积进行上采样,并不总能有效捕获复杂的边界细节。无实例感知: FCNs执行语义分割。它们按类别('汽车'、'人物')对像素进行分类,但不能区分同一类别的不同实例('汽车 1'、'汽车 2')。这些局限促成了后续架构的发展,例如U-Net(它通过更广泛的跳跃连接改进了对称的编码器-解码器结构)和DeepLab(它引入了空洞卷积以不同方式处理空间分辨率),以及实例分割方法如Mask R-CNN,我们将在本章后面部分进行讨论。尽管如此,理解FCN对于掌握现代图像分割网络的核心原理来说非常重要。