共计 2247 个字符,预计需要花费 6 分钟才能阅读完成。
背景:前馈神经网络的训练困境
在 1986 年之前,单层感知机(如 Rosenblatt 感知机)已被证明无法解决非线性可分问题(如 XOR 问题)。虽然多层网络结构的理论潜力被广泛认可,但缺乏有效的训练方法。主要障碍包括:

- 梯度计算缺失 :没有系统方法计算隐藏层权重的误差梯度
- 局部极小值陷阱 :随机初始化易使网络收敛到次优解
- 计算资源限制 :当时的计算机性能难以支持复杂迭代运算
数学原理:反向传播的链式法则
核心思想是通过链式法则将输出层误差反向传播到各层。以两层网络为例:
-
前向传播 :
$$
z^{(2)} = W^{(2)}a^{(1)} + b^{(2)}, \quad a^{(2)} = \sigma(z^{(2)})
$$
$$
z^{(1)} = W^{(1)}x + b^{(1)}, \quad a^{(1)} = \sigma(z^{(1)})
$$ -
误差反向传播 (以 MSE 损失为例):
$$
\frac{\partial L}{\partial W^{(2)}} = \frac{\partial L}{\partial a^{(2)}}\frac{\partial a^{(2)}}{\partial z^{(2)}}\frac{\partial z^{(2)}}{\partial W^{(2)}} = (a^{(2)}-y) \odot \sigma'(z^{(2)}) a^{(1)T}
$$
$$
\frac{\partial L}{\partial W^{(1)}} = \frac{\partial L}{\partial a^{(2)}}\frac{\partial a^{(2)}}{\partial z^{(2)}}\frac{\partial z^{(2)}}{\partial a^{(1)}}\frac{\partial a^{(1)}}{\partial z^{(1)}}\frac{\partial z^{(1)}}{\partial W^{(1)}}
$$
Python 实现(带注释)
import numpy as np
class TwoLayerMLP:
def __init__(self, input_size, hidden_size, output_size):
self.W1 = np.random.randn(input_size, hidden_size) * 0.01
self.b1 = np.zeros((1, hidden_size))
self.W2 = np.random.randn(hidden_size, output_size) * 0.01
self.b2 = np.zeros((1, output_size))
def sigmoid(self, x):
return 1 / (1 + np.exp(-x))
def forward(self, X):
self.z1 = np.dot(X, self.W1) + self.b1
self.a1 = self.sigmoid(self.z1)
self.z2 = np.dot(self.a1, self.W2) + self.b2
self.a2 = self.sigmoid(self.z2)
return self.a2
def backward(self, X, y, learning_rate=0.1):
m = X.shape[0]
# 输出层梯度
da2 = (self.a2 - y) / m
dz2 = da2 * self.a2 * (1 - self.a2)
dW2 = np.dot(self.a1.T, dz2)
db2 = np.sum(dz2, axis=0, keepdims=True)
# 隐藏层梯度
da1 = np.dot(dz2, self.W2.T)
dz1 = da1 * self.a1 * (1 - self.a1)
dW1 = np.dot(X.T, dz1)
db1 = np.sum(dz1, axis=0, keepdims=True)
# 参数更新
self.W2 -= learning_rate * dW2
self.b2 -= learning_rate * db2
self.W1 -= learning_rate * dW1
self.b1 -= learning_rate * db1
# 示例用法
X = np.array([[0,0], [0,1], [1,0], [1,1]]) # XOR 输入
y = np.array([[0], [1], [1], [0]]) # XOR 输出
model = TwoLayerMLP(2, 4, 1)
for epoch in range(10000):
pred = model.forward(X)
model.backward(X, y)
现代框架中的演进
- 自动微分 :PyTorch/TensorFlow 通过计算图自动完成梯度计算
- 优化器改进 :SGD → Adam 等自适应学习率算法
- 并行计算 :GPU 加速矩阵运算
- 正则化技术 :Dropout、BatchNorm 等提升泛化能力
避坑指南
- 梯度消失 :使用 ReLU 等非饱和激活函数
- 数值溢出 :对 softmax 使用 log-sum-exp 技巧
- 初始化策略 :He/Kaiming 初始化保持各层方差一致
- 学习率选择 :配合学习率衰减策略
思考题实践
尝试修改上述代码实现三层网络(输入→隐藏 1→隐藏 2→输出),观察:
- 隐藏层梯度幅值随深度衰减的现象
- 使用 tanh 激活函数时梯度消失更明显
- 尝试加入残差连接(skip connection)改善梯度流动
结语
Rumelhart 和 Hinton 的这项奠基性工作,不仅解决了多层网络训练的核心算法问题,更开创了通过误差反向传播调整网络参数的范式。当今所有深度学习框架的自动微分机制,本质上都是这一思想的工程化实现。理解这一基础算法,对于掌握现代神经网络的运作机理至关重要。
