共计 1629 个字符,预计需要花费 5 分钟才能阅读完成。
反向传播算法的基础原理
反向传播(Backpropagation, BP)是训练神经网络的核心算法,其核心思想是通过链式法则计算损失函数对网络参数的梯度,进而用梯度下降法更新权重。整个过程分为前向传播和反向传播两个阶段:

- 前向传播 :输入数据通过网络层层计算,得到预测输出
- 反向传播 :从输出层开始,逐层计算误差并传播回输入层
链式法则的数学解释
反向传播的本质是多元微积分中的链式法则。对于复合函数 f(g(x)),其导数为 f'(g(x))·g'(x)。在神经网络中,每个神经元的输出都是上一层输出的加权和经过激活函数的结果,因此误差梯度可以层层反向传递。
以一个简单的三层网络为例:
- 输入层:x
- 隐藏层:h = σ(W₁x + b₁)
- 输出层:ŷ = σ(W₂h + b₂)
- 损失函数:L = 1/2(y – ŷ)²
根据链式法则,损失对 W₁的梯度为:∂L/∂W₁ = (∂L/∂ŷ)(∂ŷ/∂h)(∂h/∂W₁)
Python 实现反向传播
下面我们实现一个包含单个隐藏层的全连接网络:
import numpy as np
# Sigmoid 激活函数及其导数
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def sigmoid_derivative(x):
return x * (1 - x)
# 网络参数
input_size = 3
hidden_size = 4
output_size = 1
learning_rate = 0.1
# 初始化权重
W1 = np.random.randn(input_size, hidden_size)
W2 = np.random.randn(hidden_size, output_size)
# 前向传播
def forward(x):
h = sigmoid(np.dot(x, W1))
y_pred = sigmoid(np.dot(h, W2))
return h, y_pred
# 反向传播
def backward(x, y, h, y_pred):
# 输出层误差
error = y - y_pred
output_delta = error * sigmoid_derivative(y_pred)
# 隐藏层误差
hidden_error = np.dot(output_delta, W2.T)
hidden_delta = hidden_error * sigmoid_derivative(h)
# 更新权重
W2 += learning_rate * np.dot(h.T, output_delta)
W1 += learning_rate * np.dot(x.T, hidden_delta)
梯度消失与爆炸问题
在深层网络中,反向传播时梯度可能指数级缩小(消失)或增大(爆炸),主要原因有:
- 激活函数选择 :sigmoid/tanh 的导数在两端接近于 0,容易导致梯度消失
- 权重初始化 :初始值过大或过小会影响梯度传播
- 网络深度 :层数越多,梯度连乘效应越明显
解决方案包括:
- 使用 ReLU 等改进的激活函数
- 采用 Xavier/He 等更好的初始化方法
- 添加 Batch Normalization 层
- 使用残差连接(ResNet)
超参数调优实践
学习率选择
学习率太大容易震荡不收敛,太小则训练缓慢。建议:
- 初始尝试 0.1、0.01 等常用值
- 使用学习率衰减策略
- 考虑自适应优化器(Adam 等)
批量大小影响
- 大批量:训练稳定但内存占用高
- 小批量:噪声大但可能找到更好极小值
通常选择 32-256 之间的值,需根据硬件条件调整。
训练调试技巧
- 监控指标 :不仅看损失值,还要跟踪准确率等业务指标
- 可视化 :绘制损失曲线、权重分布等
- 梯度检查 :比较解析梯度与数值梯度验证实现正确性
- 正则化 :添加 L2 正则或 Dropout 防止过拟合
实践建议
理解反向传播的最好方式就是动手实现。建议读者:
- 在 MNIST 等标准数据集上测试上述代码
- 尝试增加网络深度观察梯度变化
- 比较不同激活函数的效果
- 实现一个完整的训练循环,包括验证集评估
通过实践,你会对神经网络如何学习有更直观的认识。当你能手动实现并调通一个简单的 BP 网络时,使用 TensorFlow/PyTorch 等框架时会更加得心应手。
正文完
