卷积神经网络#

卷积神经网络(Convolutional Neural Network, CNN)是一种专门为处理具有类似网格结构的数据(如图像)而设计的深度学习模型。它在计算机视觉领域取得了巨大的成功,并深刻影响了现代深度学习的发展。

对于图像数据,如果使用标准的全连接神经网络,会面临两个主要问题:

  1. 参数爆炸:一张 256x256 的彩色图片,其输入维度为 256x256x3 = 196,608。如果第一个隐藏层有 1000 个神经元,那么仅这一层就会有超过 1.9 亿个参数,在计算上是难以承受的。

  2. 空间结构丢失:全连接网络将输入图像展平成一个向量,破坏了像素之间的空间邻近关系。然而,图像中的信息(如边缘、形状)正是由像素的空间排列决定的。

CNN 通过引入局部连接参数共享等思想,巧妙地解决了这些问题。

CNN 的核心组件#

1. 卷积层 (Convolutional Layer)#

卷积层是 CNN 的核心。它通过一个称为 卷积核(Kernel)滤波器(Filter) 的小窗口在输入数据上滑动,来提取局部特征。

  • 卷积核 (Kernel):一个尺寸较小(如 3x3 或 5x5)的权重矩阵。这个卷积核就是模型要学习的参数。

  • 卷积操作:卷积核在输入图像上从左到右、从上到下滑动。在每个位置,卷积核与其覆盖的图像区域进行逐元素相乘然后求和,得到一个输出值。

  • 特征图 (Feature Map):卷积核滑动完整个图像后,形成的所有输出值构成一个新的二维矩阵,称为特征图。特征图代表了输入图像在经过特定卷积核处理后提取出的特征。例如,一个卷积核可能学会了检测垂直边缘,另一个则可能学会检测绿色斑块。

填充 (Padding) 与 步幅 (Stride)#

填充和步幅是卷积层的超参数,它们共同决定了输出特征图的空间尺寸。

  • 填充 (Padding):在输入图像的边界周围添加额外的行/列(通常填充 0)。其主要作用是控制输出形状的减少量。若不加填充,深层网络中的特征图会迅速缩小,并且图像边缘的信息容易丢失。

  • 步幅 (Stride):指卷积核在输入上滑动的步长。当步幅大于 1 时(如 2),可以成倍地减少输出形状,这是一种比池化层更直接的下采样方式,能快速降低特征图的分辨率和计算量。

通过参数共享(一个卷积核在整个图像上共享同一套权重),CNN 极大地减少了模型的参数量。一个卷积层通常会学习多个不同的卷积核,从而可以同时提取多种局部特征。

卷积层的主要特性#

卷积操作赋予了 CNN 两个非常重要的特性,使其在处理图像等网格状数据时极为高效和强大。

  • 局部连接性 (Locality / Local Connectivity):与全连接层中每个神经元都连接到前一层所有神经元不同,卷积层中的每个神经元只与输入的一个局部区域相连接(这个区域的大小就是卷积核的大小)。这个设计基于一个合理的假设:在图像中,像素间的空间关系是局部的,我们只需通过观察一个小的局部窗口就能发现边缘、角点、纹理等基础特征。这极大地减少了模型的参数数量,降低了计算复杂度。

  • 平移不变性 (Translation Invariance):这是由 参数共享 (Parameter Sharing) 带来的关键特性。在卷积操作中,同一个卷积核(滤波器)会在整个输入图像上滑动并计算,这意味着它在图像的所有位置上都在寻找同一种特征。因此,无论一个目标(例如一只猫的眼睛)出现在图像的左上角还是右下角,卷积核都能以相同的方式检测到它,并在输出的特征图(Feature Map)上激活。这种“一招鲜,吃遍天”的模式使得 CNN 对目标的位置不敏感,大大提升了模型的泛化能力。

    严格来说,卷积层本身具有的是“平移等变性 (Translation Equivariance)”(输入平移,输出的特征图也相应平移),而后续的池化层(Pooling)则会进一步将这种等变性转换成更强的“平移不变性”,即无论目标在哪,最终的分类结果都保持不变。

2. 池化层 (Pooling Layer)#

在卷积层之后,通常会接一个池化层,它的主要作用是缓解卷积层对位置的敏感性,并对特征图进行**下采样(Down-sampling)**来减小其空间尺寸。这带来了几个好处:

  1. 增强平移不变性:通过对区域进行概括(取最大或平均值),使得特征检测对位置的微小变化不那么敏感。

  2. 降低计算开销:减小特征图尺寸,从而减少后续网络层的参数和计算量。

与卷积层类似,池化层也包含窗口大小、填充和步幅等超参数。

池化操作的类型#

  • 最大池化 (Max Pooling):这是最常见的池化操作。它从滑动窗口覆盖的区域中取出最大值作为输出。在 PyTorch 中通过 nn.MaxPool2d 实现。

  • 平均池化 (Average Pooling):计算滑动窗口覆盖区域内所有值的平均值作为输出。

现代 CNN 中的趋势#

值得注意的是,在许多现代的 CNN 架构中,池化层的使用正在减少。设计者们发现,可以直接使用步幅大于 1 的卷积层来达到同样甚至更好的下采样效果。这样做不仅能缩小特征图尺寸,还能在下采样的同时进行特征提取,避免了池化操作可能带来的信息损失。

3. 全连接层 (Fully-Connected Layer)#

在一系列卷积和池化层之后,最终得到的特征图会被“展平”成一个一维向量。这个向量随后被送入一个或多个标准的全连接层(就像普通神经网络一样),进行最终的分类或回归任务。

一个典型的 CNN 架构看起来像这样: 输入 -> [卷积层 -> 激活层 -> 池化层] * N -> 全连接层 -> 输出

著名的 CNN 模型#

LeNet-5 (1998)#

LeNet-5 由 Yann LeCun 在 20 世纪 80 年代末期提出,是现代卷积神经网络的“鼻祖”,被成功应用于银行支票的手写数字识别系统中,是 CNN 早期商业化应用的典范。

它的核心思想是先用卷积层和池化层来学习图片的空间信息,然后使用全连接层来将提取到的特征转换到类别空间进行分类

LeNet-5 的经典架构通常由 7 层构成(不含输入),其顺序为:

输入 -> 卷积层 -> 池化层 -> 卷积层 -> 池化层 -> 全连接层 -> 全连接层 -> 输出层

这个“卷积/池化堆叠 + 全连接分类”的模式成为了后来几十年 CNN 设计的蓝图,并验证了通过参数共享的卷积核来提取全图特征的有效性。

下面的 PyTorch 代码片段展示了 LeNet 架构如何逐步改变数据形状:

# 假设 net 是一个 LeNet-5 模型实例
X = torch.rand(size=(1, 1, 28, 28), dtype=torch.float32)
for layer in net:
    X = layer(X)
    print(f'{layer.__class__.__name__:<15} output shape: \t{X.shape}')

# 可能的输出:
# Conv2d          output shape:   torch.Size([1, 6, 28, 28])
# Sigmoid         output shape:   torch.Size([1, 6, 28, 28])
# AvgPool2d       output shape:   torch.Size([1, 6, 14, 14])
# Conv2d          output shape:   torch.Size([1, 16, 10, 10])
# Sigmoid         output shape:   torch.Size([1, 16, 10, 10])
# AvgPool2d       output shape:   torch.Size([1, 16, 5, 5])
# Flatten         output shape:   torch.Size([1, 400])
# Linear          output shape:   torch.Size([1, 120])
# Sigmoid         output shape:   torch.Size([1, 120])
# Linear          output shape:   torch.Size([1, 84])
# Sigmoid         output shape:   torch.Size([1, 84])
# Linear          output shape:   torch.Size([1, 10])

可视化推荐:想要直观地理解 CNN 每一层具体在做什么,可以访问这个交互式网站:CNN Explainer

AlexNet (2012)#

AlexNet赢了2012年ImageNet竞赛,本质上是更大更深的LeNet。

它比 LeNet-5 更深,并首次成功应用了 ReLU 激活函数和 Dropout 等技术,主要改进有:丢弃法、ReLU(减缓梯度消失)、MaxPooling,和数据增强(对输入数据进行变换生成更多的输入)。

NiN (Network in Network) (2013)#

NiN 是一个在 AlexNet 和 VGGNet 之间提出的、思想非常超前且影响深远的模型。它针对传统 CNN 的两个主要问题——卷积核的线性表达能力不足、以及网络末端全连接层参数量巨大易导致过拟合——提出了两大创新。

  • 核心创新 1:NiN 块 与 1x1 卷积

    • 为了增强卷积层的非线性能力,NiN 设计了 NiN 块:在一个标准的卷积层之后,紧跟两个 1x1 的卷积层

    • 这里的 1x1 卷积层起到了“跨通道的全连接”作用,它在不改变特征图宽高的情况下,对每个像素位置上的不同通道信息进行复杂的非线性组合(通过激活函数),极大地提升了网络的特征提取能力。这个设计也是 1x1 卷积 这一重要工具的早期成功应用。

  • 核心创新 2:全局平均池化 (Global Average Pooling, GAP)

    • 为了彻底取代参数量巨大的全连接层,NiN 创新性地在网络的最后使用了 GAP 层

    • 具体做法是,将网络最后一层的每个特征图(Feature Map)的所有像素值求平均,得到一个值。如果最后一层有 10 个特征图,GAP 之后就会得到一个长度为 10 的向量,然后将这个向量直接送入 Softmax 层进行分类。

    • 优点:GAP 几乎没有参数,极大地减少了模型的总参数量,有效防止了过拟合,并且加强了特征图与最终类别之间的对应关系。这一思想后来被 GoogLeNet、ResNet 等模型广泛采纳。

VGGNet (2014)#

VGG使用可重复使用的卷积块来构建深度卷积神经网络。不同的卷积块个数和超参数可以得到不同的复杂度的变种。

探索了网络深度的影响。其特点是结构非常简洁,完全由 3x3 的小卷积核和 2x2 的池化层堆叠而成。证明了增加网络深度可以显著提升性能。

GoogLeNet (Inception v1) (2014)#

GoogLeNet 是 2014 年 ImageNet 挑战赛的冠军。与 VGGNet 追求纯粹的深度不同,GoogLeNet 在加深网络的同时,也极其注重计算效率,其主要优点是模型参数量小、计算复杂度低。它一共使用了 9 个 Inception 块,是早期达到上百层(这里的“层”也计入了模块内的并行分支)的复杂网络。

  • 核心创新:Inception 模块:Inception 模块是 GoogLeNet 的灵魂。它没有选择单一尺寸的卷积核,而是将不同尺度的处理路径并行化,其核心思想是:

    1. 并行多尺度处理:在一个模块内,通过 4 个并行的路径(使用 1x1、3x3、5x5 的卷积核以及池化操作)从不同层面抽取信息。

    2. 1x1 卷积降维:为了避免计算量爆炸,模块在 3x3 和 5x5 卷积之前,以及在池化之后,都巧妙地使用了一个 1x1 的卷积层来降低特征图的深度(通道数),这被称为“瓶颈层 (Bottleneck Layer)”。

    3. 结果拼接:最后将 4 个路径的输出特征图在深度(通道)维度上拼接(concatenate)起来,形成一个信息更丰富的组合特征。

  • 意义与后续演进:GoogLeNet 证明了,通过精心设计的、非线性的网络拓扑结构(“网络中的网络”),可以在提升性能的同时,比 VGGNet 等模型更节省计算资源。Inception 架构也衍生出了一系列后续变种,例如:

    • Inception-v2/v3:引入了批量归一化(Batch Normalization)并进一步优化了模块结构。

    • Inception-v4:将 Inception 模块与 ResNet 的残差连接思想相结合。

ResNet (Residual Network) (2015)#

是计算机视觉领域最具影响力的架构之一。它通过引入残差连接,巧妙地解决了超深网络(超过 100 层甚至 1000 层)中的梯度消失问题,使得训练前所未有的深度模型成为可能。