共计 1796 个字符,预计需要花费 5 分钟才能阅读完成。
反向传播算法是神经网络训练的基石,它通过高效计算每个参数的梯度,指导网络权重的迭代更新。理解其数学本质对掌握深度学习至关重要。

原理推导
网络结构与符号定义
假设一个单隐藏层网络结构如下:
- 输入层:$\mathbf{x} = [x_1,…,x_n]^T$
- 隐藏层:$\mathbf{h} = sigmoid(\mathbf{W}_1\mathbf{x}+\mathbf{b}_1)$
- 输出层:$\mathbf{\hat{y}} = softmax(\mathbf{W}_2\mathbf{h}+\mathbf{b}_2)$
- 损失函数:交叉熵 $L=-\sum y_i\log\hat{y}_i$
链式求导过程
- 输出层梯度计算:
$$\frac{\partial L}{\partial \mathbf{W}_2} = \frac{\partial L}{\partial \mathbf{\hat{y}}}\n\frac{\partial \mathbf{\hat{y}}}{\partial \mathbf{z}_2}\n\frac{\partial \mathbf{z}_2}{\partial \mathbf{W}_2} = (\mathbf{\hat{y}}-\mathbf{y})\mathbf{h}^T$$
- 隐藏层梯度传播:
$$\frac{\partial L}{\partial \mathbf{W}_1} = \frac{\partial L}{\partial \mathbf{h}}\n\frac{\partial \mathbf{h}}{\partial \mathbf{z}_1}\n\frac{\partial \mathbf{z}_1}{\partial \mathbf{W}_1} = \mathbf{W}_2^T(\mathbf{\hat{y}}-\mathbf{y}) \odot \mathbf{h} \odot (1-\mathbf{h}) \mathbf{x}^T$$
其中 $\odot$ 表示逐元素相乘,sigmoid 导数特性被巧妙利用。
代码实现
import numpy as np
def sigmoid(x):
return 1/(1+np.exp(-x))
# 前向传播
h = sigmoid(np.dot(W1, x) + b1)
y_hat = softmax(np.dot(W2, h) + b2)
# 反向传播
def backward(x, y, h, y_hat, W2):
# 输出层梯度
grad_z2 = y_hat - y
grad_W2 = np.outer(grad_z2, h) # 向量外积替代矩阵乘法
# 隐藏层梯度
grad_h = np.dot(W2.T, grad_z2)
grad_z1 = grad_h * h * (1-h) # 激活函数导数
grad_W1 = np.outer(grad_z1, x)
return grad_W1, grad_W2
关键实现技巧:
- 使用
np.outer实现向量外积 - 利用广播机制避免显式循环
- 保持矩阵维度一致性检查
调试技巧
学习率选择
- 初始建议值:0.001-0.1 范围尝试
- 观察损失曲线:震荡需调小,下降过慢需调大
- 自适应方法:AdaGrad/RMSProp 自动调整
梯度检验
def grad_check(x, y, W, f):
eps = 1e-5
numeric_grad = np.zeros_like(W)
for i in range(W.size):
old_val = W.flat[i]
W.flat[i] = old_val + eps
fxh1 = f(x, y)
W.flat[i] = old_val - eps
fxh2 = f(x, y)
numeric_grad.flat[i] = (fxh1 - fxh2) / (2*eps)
return numeric_grad
批量训练实现
batch_grad_W1 = np.zeros_like(W1)
for x_batch, y_batch in dataloader:
grad_W1, _ = backward(x_batch, y_batch)
batch_grad_W1 += grad_W1
batch_grad_W1 /= batch_size
总结与思考
通过本文的公式推导和代码实现,我们揭示了反向传播如何通过链式法则将误差从输出层传递到隐藏层。建议尝试以下改进:
- 添加 ReLU 激活函数版本
- 实现带动量的梯度下降
- 扩展为多层隐藏层结构
思考题答案提示:动量更新需要维护历史梯度变量:
v = beta*v + (1-beta)*grad
W -= lr*v
