共计 1582 个字符,预计需要花费 4 分钟才能阅读完成。
反向传播 (Backpropagation) 算法是深度学习训练神经网络的基石。它通过高效的梯度计算,让多层神经网络能够自动学习特征表示。理解 BP 原理是掌握现代深度学习框架的关键前置知识。

数学推导:拆解链式求导
- 计算图视角
- 假设网络结构为:输入层→隐层(sigmoid)→输出层(softmax),损失函数为交叉熵
- 计算图示例:
x → W1 → z1 → σ → a1 → W2 → z2 → softmax → L -
根据链式法则,输出层梯度:
$$\frac{\partial L}{\partial W_2} = \frac{\partial L}{\partial z_2}\frac{\partial z_2}{\partial W_2}$$ -
sigmoid 梯度推导
- 已知 $\sigma(z) = \frac{1}{1+e^{-z}}$
- 其导数为:
$$\sigma'(z) = \sigma(z)(1-\sigma(z))$$ -
这在反向传播时会作为中间梯度项参与计算
-
权重更新矩阵表示
- 对于全连接层,权重梯度可表示为:
$$\nabla W = \frac{1}{m}X^T \cdot \delta_{out}$$ - 其中 $m$ 为 batch 大小,$\delta_{out}$ 为上层传递的误差信号
Python 实现详解
import numpy as np
# 前向传播
def forward(X, W1, b1, W2, b2):
z1 = X.dot(W1) + b1 # 第一层线性变换
a1 = 1/(1+np.exp(-z1)) # sigmoid 激活
z2 = a1.dot(W2) + b2
exp_scores = np.exp(z2)
probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True) # softmax
return a1, probs
# 反向传播
def backward(X, y, a1, probs, W2):
m = X.shape[0]
dz2 = probs
dz2[range(m), y] -= 1 # softmax 梯度
dW2 = (a1.T).dot(dz2)
db2 = np.sum(dz2, axis=0)
dz1 = dz2.dot(W2.T) * (a1 * (1-a1)) # sigmoid 梯度
dW1 = np.dot(X.T, dz1)
db1 = np.sum(dz1, axis=0)
return dW1, db1, dW2, db2
# 学习率衰减实现
initial_lr = 0.1
for epoch in range(100):
lr = initial_lr * (0.95 ** epoch) # 指数衰减
# ... 权重更新代码...
实战避坑指南
- 梯度裁剪
-
防止梯度爆炸的代码实现:
max_grad_norm = 5 grad_norm = np.linalg.norm(gradients) if grad_norm > max_grad_norm: gradients = gradients * max_grad_norm / grad_norm -
参数初始化
- 隐层权重建议采用 Xavier 初始化:
W = np.random.randn(fan_in, fan_out) / np.sqrt(fan_in) -
输出层可缩小初始化范围
-
batch 与学习率
- 经验公式:当 batch 扩大 k 倍时,学习率可增加 $\sqrt{k}$ 倍
- 大批量需要更大学习率来保持相同的收敛速度
延伸思考
-
动量法 (Momentum) 通过累积历史梯度方向,可以加速收敛并减少震荡。如何修改现有代码加入动量项?
-
ReLU 激活函数在正区间的梯度恒为 1,能有效缓解 sigmoid 带来的梯度消失问题。这对深层网络训练意味着什么?
-
虽然二阶优化器 (如 L -BFGS) 收敛更快,但在深度学习中面临海量参数时,其计算 Hessian 矩阵的代价过高。有哪些折中方案?
通过这个完整的实现案例,我们不仅理解了 BP 算法的数学本质,还掌握了工程实现的诸多细节。建议读者尝试用不同激活函数和优化器进行对比实验,这会大大加深对梯度传播机制的理解。
正文完
