共计 1558 个字符,预计需要花费 4 分钟才能阅读完成。
BP 算法是深度学习的基石,它通过误差反向传播实现神经网络的参数优化。理解反向传播过程能帮助我们诊断梯度消失 / 爆炸等常见问题。掌握其原理是进行模型调优和算法改进的前提。

数学原理与示意图解析
-
链式法则的应用
反向传播的核心是链式法则:
$$\frac{\partial L}{\partial w^{(l)}} = \frac{\partial L}{\partial z^{(l)}} \cdot \frac{\partial z^{(l)}}{\partial w^{(l)}}$$
其中 $z^{(l)}$ 表示第 $l$ 层的加权输入,$w^{(l)}$ 为参数矩阵。 -
误差反向传播流程
- 输出层计算损失函数梯度
- 逐层回传误差信号($\delta^{(l)} = (w^{(l+1)})^T \delta^{(l+1)} \odot \sigma'(z^{(l)})$)
- 根据局部梯度更新参数
graph LR
输出层误差 -->| 乘以权重 | 隐藏层 2 误差 -->| 乘以权重 | 隐藏层 1 误差
隐藏层 1 误差 -->| 计算梯度 | 参数更新
- 激活函数对比
- Sigmoid:梯度范围 (0,0.25),易引发梯度消失
- ReLU:正区间梯度恒为 1,缓解消失但可能引发神经元死亡
Python 实现(NumPy 版)
import numpy as np
class NeuralNetwork:
def __init__(self, layers):
self.weights = [np.random.randn(y, x)*0.01
for x,y in zip(layers[:-1], layers[1:])]
def forward(self, X):
self.z = [] # 记录各层加权输入
self.a = [X] # 记录各层激活值
for w in self.weights:
self.z.append(self.a[-1] @ w.T)
self.a.append(np.maximum(0, self.z[-1])) # ReLU
return self.a[-1]
def backward(self, X, y, lr=0.01):
m = len(X)
delta = (self.a[-1] - y) / m # 输出层误差
for i in reversed(range(len(self.weights))):
grad = delta.T @ self.a[i] # 计算梯度
print(f'Layer {i} gradient norm:', np.linalg.norm(grad))
self.weights[i] -= lr * grad # 参数更新
if i > 0: # 传播到前一层
delta = (delta @ self.weights[i]) * (self.z[i-1] > 0)
工程实践要点
- 梯度问题应对
- 消失现象:各层梯度范数指数级衰减 → 改用 ReLU/LeakyReLU
-
爆炸现象:梯度值溢出 → 梯度裁剪(
np.clip(grad, -1, 1)) -
Xavier 初始化
保证输入输出方差一致:
$$W_{ij} \sim U\left(-\sqrt{\frac{6}{n_{in}+n_{out}}}, \sqrt{\frac{6}{n_{in}+n_{out}}}\right)$$# 替换初始化代码 scale = np.sqrt(2/(layers[i-1]+layers[i])) self.weights = [np.random.randn(y, x)*scale ...] -
L2 正则化影响
反向传播时增加权重衰减项:
$$\frac{\partial L}{\partial w} += \lambda w$$
需要在参数更新步骤添加:grad += reg_lambda * self.weights[i]
延伸思考
- 梯度检查(Gradient Checking)通过数值近似验证实现正确性
- BatchNorm 在反向传播时引入额外的尺度变换项
- 二阶优化需要 Hessian 矩阵信息,需调整梯度计算方式
正文完
