搞懂卷积神经网络(CNN)的核心运算

5 阅读1分钟

搞懂卷积神经网络(CNN)的核心运算

一、符号解读

1. 层级与超参数 (Hyperparameters)

  • l:这是上标,代表网络层数 (Layer Index)[l] 表示当前第 l 层,而 [l-1] 则表示它的前一层。这是理解数据流动方向的关键。
  • f [l]: 过滤器尺寸 (Filter Size)。这指的是卷积核(Kernel)的高度和宽度。通常假设卷积核是正方形,所以一个 f=3 的过滤器,其尺寸为 3x3
  • p [l]: 填充 (Padding)。在输入特征图的边界周围添加额外的像素(通常是0)。p=1 意味着在图像的上下左右各加一层像素。
  • s [l]: 步幅 (Stride)。卷积核在输入特征图上每次滑动的步长。s=1 表示逐像素滑动,s=2 表示每次跳过一个像素。

f, p, s 是构建 CNN 时需要我们手动设定的超参数,它们直接决定了网络的结构和性能。

2. 张量形状 (Tensor Shapes)

神经网络的运算本质上是多维数组(张量)的变换。张量的“形状”至关重要。

  • 输入 (Input): 形状为 nH[l1]×nW[l1]×nc[l1]n_H^{[l-1]} \times n_W^{[l-1]} \times n_c^{[l-1]}
    • nH[l1]n_H^{[l-1]}: 输入特征图的高度 (Height)
    • nW[l1]n_W^{[l-1]}: 输入特征图的宽度 (Width)
    • nc[l1]n_c^{[l-1]}: 输入特征图的通道数 (Channels)。例如,对于一张初始的 RGB 图片,通道数就是 3。
  • 输出 (Output): 形状为 nH[l]×nW[l]×nc[l]n_H^{[l]} \times n_W^{[l]} \times n_c^{[l]}
    • nH[l],nW[l]n_H^{[l]}, n_W^{[l]}: 经过卷积运算后,输出特征图的新高度和新宽度。
    • nc[l]n_c^{[l]}: 输出特征图的通道数。这个值非常关键,它等于当前层所使用的过滤器的数量

3. 核心参数与激活值 (Parameters & Activations)

  • nc[l]n_c^{[l]}: 过滤器的数量 (Number of filters)。这是第 l 层的核心参数之一。每个过滤器负责学习一种特定的视觉模式(如边缘、纹理、颜色块等)。
  • 每个过滤器 (Each filter): 其形状为 f[l]×f[l]×nc[l1]f^{[l]} \times f^{[l]} \times n_c^{[l-1]}
    • 这是一个至关重要的知识点!很多人会忽略第三个维度 nc[l1]n_c^{[l-1]}。这意味着每个过滤器的深度必须与输入数据的通道数完全相同。它需要同时“看”到前一层的所有通道,才能综合信息。
  • 权重 (Weights) W[l]W^{[l]}: 整个第 l 层的权重参数,是一个四维张量,形状为 f[l]×f[l]×nc[l1]×nc[l]f^{[l]} \times f^{[l]} \times n_c^{[l-1]} \times n_c^{[l]}
    • 它其实就是将 nc[l]n_c^{[l]} 个形状为 f[l]×f[l]×nc[l1]f^{[l]} \times f^{[l]} \times n_c^{[l-1]} 的过滤器“堆叠”在一起形成的。
  • 偏置 (bias) b[l]b^{[l]}: 偏置参数。每个过滤器对应一个偏置项,所以 b[l]b^{[l]} 是一个长度为 nc[l]n_c^{[l]} 的向量。
  • 激活值 (Activations) a[l]a^{[l]}: 指的是当前层输出的最终结果(通常是经过了 ReLU 等激活函数之后)。它的形状就是输出的形状 nH[l]×nW[l]×nc[l]n_H^{[l]} \times n_W^{[l]} \times n_c^{[l]}
    • 图中的 A[l]A^{[l]} 是指一个批次(mini-batch)的激活值,m 代表批次中的样本数量。所以 A[l]A^{[l]} 的形状是 m×nH[l]×nW[l]×nc[l]m \times n_H^{[l]} \times n_W^{[l]} \times n_c^{[l]}

二、卷积层的运算全过程

理解了符号,我们就可以一步步还原卷积运算的真实过程。

目标:将输入 a[l1]a^{[l-1]} (形状 nH[l1]×nW[l1]×nc[l1]n_H^{[l-1]} \times n_W^{[l-1]} \times n_c^{[l-1]}) 变换为输出 a[l]a^{[l]} (形状 nH[l]×nW[l]×nc[l]n_H^{[l]} \times n_W^{[l]} \times n_c^{[l]})。

第1步:输入预处理 - 填充 (Padding)

在运算开始前,我们先根据超参数 p 在输入的四周填充像素。如果输入是 5×55 \times 5p=1,那么填充后的大小变为 (5+2×1)×(5+2×1)=7×7(5+2 \times 1) \times (5+2 \times 1) = 7 \times 7

为什么需要填充?

  1. 保持边界信息:若无填充,角落和边缘的像素被卷积核扫过的次数远少于中心像素,导致边界信息丢失。
  2. 控制输出尺寸:填充可以减缓特征图尺寸的缩小速度,从而构建更深的网络。

第2步:单个过滤器的“卷积”操作 (Convolution)

这是核心中的核心。我们先看一个过滤器(Filter 1,形状为 f×f×nc[l1]f \times f \times n_c^{[l-1]})是如何生成一个输出通道的。

  1. 对齐与覆盖:将这个过滤器放置在填充后输入的左上角。它的 f×ff \times f 窗口覆盖了输入图像的一个区域,同时它的深度 nc[l1]n_c^{[l-1]} 与输入的通道数完全对齐。
  2. 逐元素相乘再求和:将过滤器和它所覆盖的输入区域进行逐元素 (element-wise) 相乘,然后将所有乘积相加。这个操作在数学上称为“点积”或“内积”。这是一个 f×f×nc[l1]f \times f \times n_c^{[l-1]} 体量的数据块,经过计算后浓缩成了一个单独的数值
  3. 加上偏置:为这个数值加上该过滤器对应的偏置项 b1b_1
  4. 激活函数:将结果送入一个非线性激活函数(如 ReLU,max(0, x))。最终得到的这个值,就是输出特征图(Output Channel 1)左上角的第一个像素值
  5. 滑动窗口 (Sliding Window):将过滤器按照步幅 s 向右移动,重复步骤 2-4,计算出输出通道 1 的第一行。当移动到行尾,过滤器回到下一行的最左边,继续滑动,直到遍历完所有可能的区域。

最终,一个过滤器就完整地生成了一张新的二维特征图(一个输出通道)。

第3步:多过滤器生成多通道输出

一个过滤器提取一种特征。为了提取多种特征,我们需要多个过滤器。

假设我们设置了 nc[l]n_c^{[l]} 个过滤器。那么我们就重复第2步nc[l]n_c^{[l]} 次。每个过滤器(Filter 1, Filter 2, ..., Filter nc[l]n_c^{[l]})都独立地对相同的输入进行卷积,并各自加上自己的偏置项,最终生成一张独一无二的特征图。

最后,将这 nc[l]n_c^{[l]} 张二维特征图在“通道”维度上堆叠起来,就构成了我们最终的输出 a[l]a^{[l]},其形状为 nH[l]×nW[l]×nc[l]n_H^{[l]} \times n_W^{[l]} \times n_c^{[l]}

第4步:输出尺寸的计算

输出特征图的高度和宽度由以下公式精确确定:

nH[l]=nH[l1]+2p[l]f[l]s[l]+1n_H^{[l]} = \lfloor \frac{n_H^{[l-1]} + 2p^{[l]} - f^{[l]}}{s^{[l]}} \rfloor + 1 nW[l]=nW[l1]+2p[l]f[l]s[l]+1n_W^{[l]} = \lfloor \frac{n_W^{[l-1]} + 2p^{[l]} - f^{[l]}}{s^{[l]}} \rfloor + 1

其中 \lfloor \cdot \rfloor 是向下取整符号,确保尺寸为整数。这个公式完美地编码了我们前面描述的滑动窗口过程。

总结

  • 输入是一个三维的数据体。
  • 权重 W[l]W^{[l]} 是一组(共 nc[l]n_c^{[l]} 个)三维的“探测器”(过滤器),每个探测器的深度必须能“看透”输入的整个深度。
  • 运算是一个“滑动-点积-求和”的过程,将高维局部信息压缩成一个标量。
  • 输出是另一组新的、被提炼过的三维数据体,其深度(通道数)代表了我们提取了多少种不同的特征。