共计 2267 个字符,预计需要花费 6 分钟才能阅读完成。
背景介绍
反向传播(Backpropagation)是训练神经网络的核心算法,它通过计算损失函数对网络参数的梯度,利用梯度下降法不断调整权重和偏置,使网络的预测结果逐渐接近真实值。理解反向传播的数学原理,不仅能帮助我们更好地调试模型,还能为设计新的网络结构打下基础。

数学推导
1. 前向传播基础
假设一个简单的三层神经网络(输入层、隐藏层、输出层),隐藏层和输出层的激活函数为 σ 和 φ。前向传播过程如下:
- 隐藏层输出:$h_j = \sigma(\sum_i w_{ji}x_i + b_j)$
- 输出层结果:$y_k = \phi(\sum_j w_{kj}h_j + b_k)$
2. 损失函数与梯度
定义均方误差损失函数:
$L = \frac{1}{2}\sum_k (t_k – y_k)^2$
通过链式法则,我们可以计算损失对各层参数的梯度:
-
输出层权重梯度:
$\frac{\partial L}{\partial w_{kj}} = \frac{\partial L}{\partial y_k} \cdot \frac{\partial y_k}{\partial w_{kj}} = -(t_k-y_k)\phi'(\cdot)h_j$ -
隐藏层权重梯度:
$\frac{\partial L}{\partial w_{ji}} = \frac{\partial L}{\partial h_j} \cdot \frac{\partial h_j}{\partial w_{ji}} = [\sum_k \frac{\partial L}{\partial y_k}\frac{\partial y_k}{\partial h_j}] \cdot \sigma'(\cdot)x_i$
3. 反向传播公式
定义误差项:
– 输出层误差:$\delta_k = (t_k-y_k)\phi'(\cdot)$
– 隐藏层误差:$\delta_j = [\sum_k \delta_k w_{kj}] \sigma'(\cdot)$
最终梯度计算简化为:
– $\Delta w_{kj} = \eta \delta_k h_j$
– $\Delta w_{ji} = \eta \delta_j x_i$
代码实现
import numpy as np
class NeuralNetwork:
def __init__(self, input_size, hidden_size, output_size):
# 初始化权重
self.W1 = np.random.randn(input_size, hidden_size)
self.W2 = np.random.randn(hidden_size, output_size)
def sigmoid(self, x):
return 1/(1+np.exp(-x))
def sigmoid_deriv(self, x):
return x*(1-x)
def forward(self, X):
self.hidden = self.sigmoid(np.dot(X, self.W1))
self.output = self.sigmoid(np.dot(self.hidden, self.W2))
return self.output
def backward(self, X, y, lr=0.1):
# 计算输出层误差
output_error = y - self.output
output_delta = output_error * self.sigmoid_deriv(self.output)
# 计算隐藏层误差
hidden_error = output_delta.dot(self.W2.T)
hidden_delta = hidden_error * self.sigmoid_deriv(self.hidden)
# 更新权重
self.W2 += lr * self.hidden.T.dot(output_delta)
self.W1 += lr * X.T.dot(hidden_delta)
常见问题
梯度消失 / 爆炸问题
当网络层数较深时,梯度在反向传播过程中会不断连乘:
- 如果权重初始化过大,梯度可能指数级增长(爆炸)
- 如果权重初始化过小或使用 sigmoid/tanh 等饱和激活函数,梯度可能指数级衰减(消失)
解决方案:
- 使用 ReLU 等非饱和激活函数
- 采用 Xavier/He 权重初始化方法
- 引入残差连接(ResNet)
- 使用批量归一化(BatchNorm)
性能优化
学习率选择
- 初始学习率通常设置在 0.01-0.1 之间
- 可以使用学习率衰减策略(如指数衰减)
- 更先进的优化器(Adam、RMSprop)能自动调整学习率
批量归一化
在每层激活函数前加入:
$\hat{x} = \frac{x – \mu}{\sqrt{\sigma^2 + \epsilon}}$
$y = \gamma \hat{x} + \beta$
这能缓解内部协变量偏移问题,使网络训练更稳定。
避坑指南
- 数据未归一化:输入特征应缩放至相似范围(如 [0,1] 或标准正态分布)
- 全零初始化:导致所有神经元学习相同特征
- 过小的批量大小:可能使训练不稳定
- 忘记关闭梯度计算(如测试时仍保持 train 模式)
- 不检查梯度:实现后应通过数值梯度验证反向传播的正确性
思考与建议
理解反向传播的最好方式就是动手实现一个简单的神经网络。建议尝试:
1. 修改网络结构(增加层数 / 改变激活函数)观察训练效果
2. 实现不同的优化算法(SGD、Momentum、Adam)比较收敛速度
3. 在 MNIST 等标准数据集上测试你的实现
反向传播是深度学习的基石,掌握其原理将大大提升你调试和优化模型的能力。在实际项目中,虽然框架已自动处理了梯度计算,但理解背后的数学原理能帮助你在遇到问题时更快找到解决方案。
