共计 1789 个字符,预计需要花费 5 分钟才能阅读完成。
CNN 与反向传播背景介绍
卷积神经网络(CNN)是计算机视觉领域的基石,其核心优势在于能够自动提取图像的局部特征。而误差反向传播算法则是训练 CNN 的引擎,它通过链式法则将预测误差从输出层逐层传递回网络前端,指导参数更新。理解这一过程对掌握深度学习至关重要。

数学原理分步推导
卷积层误差反向传播
- 定义卷积层的输入为 $X$,卷积核为 $W$,输出为 $Z = X * W + b$
- 上层传来的梯度为 $\frac{\partial L}{\partial Z}$
- 根据链式法则,计算权重的梯度:
$$\frac{\partial L}{\partial W} = X \star \frac{\partial L}{\partial Z}$$
其中 $\star$ 表示互相关运算 - 偏置项的梯度为各元素梯度之和:
$$\frac{\partial L}{\partial b} = \sum_{i,j} \frac{\partial L}{\partial Z_{i,j}}$$
池化层梯度回传
最大池化
- 记录前向传播时每个池化窗口的最大值位置
- 回传时,梯度仅传递给原最大值位置,其他位置置零
平均池化
- 将梯度均匀分配到池化窗口的所有位置
- 若窗口大小为 $k\times k$,则每个位置获得 $\frac{1}{k^2}$ 的梯度
Python 代码实现与解析
import numpy as np
class ConvLayer:
def __init__(self, in_channels, out_channels, kernel_size):
# He 初始化卷积核
self.W = np.random.randn(out_channels, in_channels, kernel_size, kernel_size) * np.sqrt(2./in_channels)
self.b = np.zeros(out_channels)
def forward(self, X):
"""前向传播"""
self.X = X # 保存输入用于反向传播
# 实现带 padding 的卷积运算
# ...(详细实现代码)return Z
def backward(self, dZ):
"""反向传播"""
# 计算权重梯度
dW = np.zeros_like(self.W)
for i in range(self.W.shape[0]):
for j in range(self.W.shape[1]):
dW[i,j] = signal.correlate2d(self.X[j], dZ[i], mode='valid')
# 计算偏置梯度
db = np.sum(dZ, axis=(1,2))
# 计算输入梯度(传递给前一层的误差)dX = np.zeros_like(self.X)
# ...(完整实现)return dX, dW, db
数值梯度验证方法
通过微小扰动参数计算数值梯度,验证反向传播实现的正确性:
def numerical_gradient(f, x, eps=1e-4):
grad = np.zeros_like(x)
it = np.nditer(x, flags=['multi_index'])
while not it.finished:
idx = it.multi_index
tmp = x[idx]
x[idx] = tmp + eps
f1 = f(x)
x[idx] = tmp - eps
f2 = f(x)
grad[idx] = (f1 - f2) / (2*eps)
x[idx] = tmp
it.iternext()
return grad
训练注意事项与调优技巧
- 学习率设置 :
- 初始值通常设为 0.001-0.01
-
使用学习率衰减策略如 StepLR 或 CosineAnnealing
-
梯度问题处理 :
- 梯度爆炸:使用梯度裁剪(
np.clip(grad, -1, 1)) -
梯度消失:改用 ReLU 激活函数,合理初始化参数
-
卷积核初始化 :
- 推荐使用 He 初始化(
W = np.random.randn(...) * sqrt(2/n_input)) - 避免全零初始化导致对称性问题
总结与延伸思考
通过本文的实现,我们深入理解了 CNN 反向传播的数学原理和代码实现。作为延伸:
- 批量训练扩展 :
- 修改 forward/backward 支持 batch 维度
-
梯度计算时对 batch 求平均
-
自动微分 vs 手动实现 :
- 自动微分(如 PyTorch)更高效但隐藏细节
- 手动实现有助于深入理解原理
思考题:
– 如何处理可变输入尺寸的情况?
– 如何在池化层实现 stride>1 的反向传播?
理解这些基础原理将为后续学习更复杂的网络结构打下坚实基础。
正文完
发表至: 未分类
近两天内
