由 Kunihiko Fukushima 提出,Neocognitron 是最早模拟人类视觉皮层结构的人工神经网络架构。它具备层级结构与局部连接机制,可以实现位置不变性的图像识别,是现代 CNN 的雏形。
Yann LeCun 等人提出了 LeNet-5,这是第一个完整定义了现代 CNN 架构的网络,包含以下核心结构:
LeNet 使用反向传播算法进行训练,成功地应用于手写数字识别(如 MNIST)。但由于模型规模较小,难以应对更复杂的数据,如自然图像和视频。
在 MNIST 数据集上,主流方法的错误率如下:
方法类型 | 错误率范围 |
---|---|
线性分类器 | 8% ~ 12% |
K 近邻(KNN) | 1.x% ~ 5% |
支持向量机(SVM) | 0.6% ~ 1.4% |
多层神经网络 | 1% ~ 5% |
这些结果表明,尽管传统方法在小规模图像上有竞争力,但在泛化能力和深层次语义理解方面存在局限。
AlexNet 是深度学习在图像领域广泛流行的转折点。由 Krizhevsky、Sutskever 和 Hinton 提出,首次在 ImageNet 2012 大规模视觉识别竞赛中获得显著胜利:
AlexNet 的成功充分展示了深层 CNN 模型在大数据 + 高计算资源条件下的强大表达能力。
在这里插入图片描述
随着计算能力和数据规模的增长,CNN 在多个视觉任务中得到了广泛应用:
近年来的代表性研究工作包括:
卷积神经网络主要由以下三类结构组成:
这些组件层层堆叠,共同构成完整的深度神经网络结构。
一个通用的 CNN 网络结构通常如下所示:
这种结构可以不断提取从低级边缘特征到高级语义特征的信息。
可参考项目示例:
在 PyTorch 中,卷积层由 nn.Conv2d
实现,常用参数如下:
in_channels
:输入通道数(例如灰度图为 1,RGB 图为 3)out_channels
:输出特征图数量(即卷积核数量)kernel_size
:卷积核大小,如 (3, 3)
表示 3x3 核stride
:步长,控制卷积核的滑动幅度padding
:是否在边缘补零以控制输出尺寸bias
:是否包含偏置项示例代码如下:
import torch.nn as nn
conv = nn.Conv2d(in_channels=1, out_channels=10, kernel_size=5, stride=1, padding=2)
我们以灰度图像为例说明卷积过程:
输入图像为 6×6:
1 2 0 1 0 1
2 1 1 0 0 1
1 0 0 2 1 0
2 0 0 0 2 1
0 1 1 2 0 2
1 0 1 0 1 1
卷积核为 3×3:
1 0 -1
-1 0 0
0 0 1
第一步,提取输入图像左上角 3×3 区域,与卷积核逐元素相乘后求和:
输入局部区域:
1 2 0
2 1 1
1 0 0
乘积计算:
1×1 + 2×0 + 0×(-1)
+ 2×(-1) + 1×0 + 1×0
+ 1×0 + 0×0 + 0×1
= 1 - 2 = -1
这个 -1 就是输出特征图中对应位置的值。这个卷积窗口会按步长向右、向下滑动,覆盖整张图像,形成输出特征图。
步长决定了卷积核每次滑动时跳过的像素数:
步长的选择会影响特征图的大小、感受野扩展速度及模型计算量。
当我们希望输出特征图与输入图像尺寸一致,或保留边缘信息时,可使用“零填充”。
示意图像的周围用 0 填充:
0 0 0 0 0 0 0 0
0 1 2 0 1 0 1 0
0 2 1 1 0 0 1 0
...
这种处理方式保证了卷积核可以覆盖到图像边界,从而保留边缘特征。
设:
输出尺寸为:
O u t p u t S i z e = ( N + 2 P − K ) S + 1 Output Size = \frac{(N + 2P - K)}{S} + 1 OutputSize=S(N+2P−K)+1
这个公式适用于每一维度(宽度或高度)分别计算。
例如:
则输出大小为:
Output Size = floor((6 + 2×1 - 3)/1) + 1 = floor(6) + 1 = 6
实际中,我们通常不只使用一个卷积核,而是使用多个不同的滤波器(filters)来提取不同的图像特征:
例如:
不同的卷积核可以学习不同的结构模式,比如:
这些卷积核参数都是通过反向传播自动学习得到的。
在之前的示例中,我们只考虑了灰度图(单通道输入)。但现实中大多数图像为 RGB 彩色图,具有 3 个通道。此时的卷积操作需要处理输入深度。
设输入张量尺寸为:
输入图像:W × H × D
卷积核:K × K × D
输出特征图:W' × H'
其中:
每个卷积核的深度必须与输入通道一致,卷积核将在每个通道分别滑动、乘积,再将所有通道的结果加总,得到一个输出值。
如果使用多个卷积核,则每个卷积核都执行同样操作,最终输出为多个通道的特征图。
示例:
我们可以通过组合 stride 和 padding 来控制输出特征图的空间大小。
设:
输出尺寸计算为:
W_out = floor((W + 2P - K) / S) + 1
H_out = floor((H + 2P - K) / S) + 1
输出通道数由卷积核数量决定。
卷积操作本质上是局部加权求和,可以将其转换为稀疏矩阵与向量的乘法形式。这样可以更直观地理解其线性结构与反向传播机制。
设输入张量展开为向量 x \mathbf{x} x,输出为向量 y \mathbf{y} y,卷积过程可表达为:
y = C × x
其中 C 是一个稀疏矩阵(每一行对应一个卷积窗口展开),其非零元素就是卷积核的权重。如下是一个 3×3 卷积核在输入大小为 4×4 时对应的稀疏矩阵结构(仅示意):
C = [
w1 w2 w3 0 w4 w5 w6 0 ...
0 w1 w2 w3 0 w4 w5 w6 ...
...
]
这种方式有助于理解:
卷积层支持端到端训练,关键在于反向传播算法的实现。
设:
整体卷积操作可表示为:
X l = C l − 1 ⋅ X l − 1 X^l = C^{l-1} \cdot X^{l-1} Xl=Cl−1⋅Xl−1
反向传播需要计算两部分梯度:
卷积核中每个参数 w m , n w_{m,n} wm,n 的梯度计算为:
∂ Loss ∂ w m , n = ∑ h , k ∂ Loss ∂ x h , k l ⋅ ∂ x h , k l ∂ w m , n \frac{\partial \text{Loss}}{\partial w_{m,n}} = \sum_{h,k} \frac{\partial \text{Loss}}{\partial x^l_{h,k}} \cdot \frac{\partial x^l_{h,k}}{\partial w_{m,n}} ∂wm,n∂Loss=h,k∑∂xh,kl∂Loss⋅∂wm,n∂xh,kl
其中,输出 x h , k l x^l_{h,k} xh,kl 对卷积核参数 w m , n w_{m,n} wm,n 的偏导为:
∂ x h , k l ∂ w m , n = x h + m − 1 , k + n − 1 l − 1 \frac{\partial x^l_{h,k}}{\partial w_{m,n}} = x^{l-1}_{h + m - 1,\, k + n - 1} ∂wm,n∂xh,kl=xh+m−1,k+n−1l−1
也就是说,对某个卷积核权重 w m , n w_{m,n} wm,n,它对损失函数的影响由所有使用它的输出像素贡献相加。
反向传播还需将误差向前传播,即计算:
∂ Loss ∂ x h , k l = ∑ j ∂ Loss ∂ x j l + 1 ⋅ ∂ x j l + 1 ∂ x h , k l \frac{\partial \text{Loss}}{\partial x^l_{h,k}} = \sum_j \frac{\partial \text{Loss}}{\partial x^{l+1}_j} \cdot \frac{\partial x^{l+1}_j}{\partial x^l_{h,k}} ∂xh,kl∂Loss=j∑∂xjl+1∂Loss⋅∂xh,kl∂xjl+1
由矩阵表示法 X l = C X l − 1 X^l = C X^{l-1} Xl=CXl−1 可知,其反向传播为:
∂ Loss ∂ X l − 1 = C ⊤ ⋅ ∂ Loss ∂ X l \frac{\partial \text{Loss}}{\partial X^{l-1}} = C^\top \cdot \frac{\partial \text{Loss}}{\partial X^l} ∂Xl−1∂Loss=C⊤⋅∂Xl∂Loss
即误差通过卷积矩阵的转置进行传播。对于单个元素,可以展开写为:
∂ Loss ∂ x i l − 1 = ∑ j ∂ Loss ∂ x j l ⋅ C j , i \frac{\partial \text{Loss}}{\partial x_i^{l-1}} = \sum_j \frac{\partial \text{Loss}}{\partial x_j^l} \cdot C_{j,i} ∂xil−1∂Loss=j∑∂xjl∂Loss⋅Cj,i
即第 i i i 个输入位置的梯度由所有包含它的卷积窗口反向贡献加总。
注意:公式中的 x i l x^l_i xil 表示 X l X^l Xl 展平后的第 i i i 个元素,若原始二维索引为 ( h , k ) (h,k) (h,k),则有:
i = ( h − 1 ) ⋅ H + k i = (h - 1) \cdot H + k i=(h−1)⋅H+k
这个编号方式是矩阵向量化(flatten)后常用的顺序,用于矩阵乘法形式统一表示。
感受野是 CNN 中的重要概念,用于描述某一神经元在输入图像上所能“看到”的区域大小。即:
某个卷积层中神经元的输出值,最终是由输入图像中哪一块区域影响的?
假设使用以下参数配置:
此时,每多加一层卷积,感受野会变大,但由于存在步长,增长速度为指数级。
我们可递归计算感受野 r l r_l rl 第 l l l 层的大小:
r l = r l − 1 + ( k l − 1 ) ⋅ ∏ i = 1 l − 1 s i r_l = r_{l-1} + (k_l - 1) \cdot \prod_{i=1}^{l-1} s_i rl=rl−1+(kl−1)⋅i=1∏l−1si
其中:
通过该公式,可以准确估算某一深层神经元最终能感知输入图像的多大区域。
图像左边:
图像右边:
这种可视化策略广泛用于模型解释与感知分析。
膨胀卷积(也叫 Atrous Convolution)是一种修改版的卷积操作,其核心思想是在卷积核内部引入空洞,扩大感受野的同时不增加参数量。
膨胀卷积的参数 Dilation Rate(膨胀率)记作 d d d:
设输入序列为 x [ i ] x[i] x[i],卷积核为 w [ k ] w[k] w[k],膨胀率为 d d d,则:
y [ i ] = ∑ k = 1 K w [ k ] ⋅ x [ i + d ⋅ k ] y[i] = \sum_{k=1}^{K} w[k] \cdot x[i + d \cdot k] y[i]=k=1∑Kw[k]⋅x[i+d⋅k]
使用 3 × 3 3 \times 3 3×3 卷积核时:
通过调节 d d d,模型可以在保持特征图尺寸不变的前提下获取更大的上下文信息。
膨胀卷积广泛应用于:
(参考:Yu et al., 2015)
池化层是一种下采样机制,通常用于:
池化操作在卷积层之后应用,不引入可训练参数。
常见池化类型包括:
最大池化选取滑动窗口中的最大值作为输出:
输入特征图:
-1 2 0 0
0 1 3 -2
0 0 -1 4
3 -1 -2 -2
应用 ( 2 × 2 ) (2×2) (2×2) 的最大池化窗口后输出为:
2 3
3 4
每个输出位置是对应窗口中的最大值。
最大池化具有选择性保留最强激活的作用,常用于分类模型中提取局部最强信号。
平均池化计算窗口中所有像素的平均值:
输入特征图:
-1 4 1 2
0 1 3 -2
1 5 -2 6
3 -1 -2 -2
最大池化结果:
4 3
5 6
平均池化结果:
1 1
2 0
相比最大池化,平均池化更加平滑,适合用于特征压缩、图像重建等任务。
L2 池化是一种加权平均的方式,使用高斯核或其他权重模板对局部区域进行加权汇总:
设池化窗口为 2 × 2 2 \times 2 2×2,对应像素为 x i , j x_{i,j} xi,j,权重为 w i , j w_{i,j} wi,j,输出为:
y = ∑ i , j w i , j ⋅ x i , j 2 y = \sqrt{\sum_{i,j} w_{i,j} \cdot x_{i,j}^2} y=i,j∑wi,j⋅xi,j2
这种方式对图像中的小幅变化更为敏感,可用于精细建模。
除了标准的 Max 和 Average 池化,还有多种增强池化策略,常用于应对特定场景问题。
定义如下:
y = ( ∑ i w i ⋅ x i p ) 1 / p y = \left( \sum_i w_i \cdot x_i^p \right)^{1/p} y=(i∑wi⋅xip)1/p
通过选择不同的 p p p 值调节池化策略的平滑程度。当 p = 1 p=1 p=1 为平均池化, p → ∞ p \rightarrow \infty p→∞ 时趋近于最大池化。
为缓解最大池化容易过拟合的问题,可将最大值与平均值进行加权融合:
y = a ⋅ max ( x 1 , . . . , x n ) + ( 1 − a ) ⋅ mean ( x 1 , . . . , x n ) y = a \cdot \max(x_1, ..., x_n) + (1 - a) \cdot \text{mean}(x_1, ..., x_n) y=a⋅max(x1,...,xn)+(1−a)⋅mean(x1,...,xn)
其中 a ∈ [ 0 , 1 ] a \in [0,1] a∈[0,1] 是超参数,可设定或学习。
不使用固定规则选择池化输出,而是基于激活概率随机选择:
y = x l where l ∼ P ( p 1 , . . . , p n ) , p i = e x i ∑ j e x j y = x_l \quad \text{where } l \sim P(p_1, ..., p_n), \quad p_i = \frac{e^{x_i}}{\sum_j e^{x_j}} y=xlwhere l∼P(p1,...,pn),pi=∑jexjexi
具有正则化作用,常用于大型 CNN 中防止过拟合。
将特征图转换到频域,截断高频部分再转换回来,从而实现尺寸压缩:
y = F − 1 ( F ( x ) [ : k , : k ] ) \mathbf{y} = \mathcal{F}^{-1}(\mathcal{F}(\mathbf{x})[:k, :k]) y=F−1(F(x)[:k,:k])
比空间域池化保留更多图像信息。
这些高级池化策略在视觉任务中逐步得到广泛应用,例如语义分割、目标检测和图像生成任务中。
在传统的全连接神经网络中,每个神经元与上一层的所有节点相连,导致:
例如,对于 1000 × 1000 1000 \times 1000 1000×1000 的图像,若使用全连接层处理,每个神经元都需要处理 10 6 10^6 106 个输入,这在计算和存储上都是巨大的负担。
CNN 借鉴了生物视觉系统的结构,采用局部连接策略:
优点:
这种机制让神经元只关注邻域范围内的信息,形成层层抽象的特征。
虽然局部连接可以捕捉小范围特征,但仍然存在问题:
Ranzato (CVPR 2013) 指出,深层堆叠卷积可以将局部特征组合成更复杂的、抽象的、高级语义特征。
CNN 的另一核心思想是权重共享:
一个卷积核在图像的所有位置上滑动使用,同一组权重参数共享。
相比全连接的 10 6 10^6 106 参数,卷积显得极为紧凑高效。
CNN 中每一层卷积通常不只使用一个卷积核,而是使用多个并行卷积核(filters):
相比全连接层的 10 8 10^8 108 级别参数,仍然大大降低。
不同卷积核可学习图像中的不同模式,以下是直观示例:
通过组合多个卷积核输出的特征图,CNN 构建出层层递进的图像理解路径。
这些机制共同成就了 CNN 在图像识别、视频分析、语音建模等任务中的强大表现力。
卷积神经网络虽然结构清晰,但其内部处理过程仍较难直接理解。特征可视化技术的提出,旨在揭示:
深层 CNN 每一层到底“看到了什么”?
网络为什么能正确分类、定位图像内容?
CNN 通过层层堆叠的卷积和非线性操作(如 ReLU、MaxPooling)形成逐层抽象的表示结构:
直接将中间层卷积后的特征图(activation map)可视化:
由 Zeiler 和 Fergus(2014)提出,通过反向传播中间层的激活值到输入空间,重构“神经元看到的输入”。
步骤如下:
优点:
通过可视化我们可以发现:
这些信息对于理解模型行为、调试网络结构、发现训练问题都非常有帮助。
参考论文:Zeiler & Fergus, “Visualizing and Understanding Convolutional Networks”, ECCV 2014.