共计 1966 个字符,预计需要花费 5 分钟才能阅读完成。
背景介绍
反向传播算法是深度学习中最核心的训练技术之一。它通过计算损失函数对网络参数的梯度,指导参数更新方向,使神经网络能够逐步改进预测性能。3Blue1Brown 的视频用直观的几何视角展示了这一过程,本文将结合数学推导与代码实现,带您彻底理解这一关键算法。
数学原理
反向传播本质上是链式法则的巧妙应用。考虑一个简单三层网络(输入层、隐藏层、输出层),其计算流程可分为三个阶段:
- 前向传播 :数据从输入层流向输出层,每层计算为 $z=Wx+b$ 和 $a=\sigma(z)$,其中 $\sigma$ 是激活函数
- 损失计算 :输出层结果与真实标签比较,如用均方误差 $L=\frac{1}{2}(y_{pred}-y_{true})^2$
- 反向传播 :从输出层开始,逐层计算梯度并更新参数
关键公式推导:
- 输出层梯度:$\frac{\partial L}{\partial W_2} = (a_2-y) \cdot \sigma'(z_2) \cdot a_1^T$
- 隐藏层梯度:$\frac{\partial L}{\partial W_1} = (\delta_2 W_2) \cdot \sigma'(z_1) \cdot x^T$
其中 $\delta$ 表示误差项,通过链式法则从后向前传递。

图:梯度在网络中的反向传播路径
代码实现
import numpy as np
class NeuralNetwork:
def __init__(self, input_size, hidden_size, output_size):
# 初始化权重(Xavier 初始化)self.W1 = np.random.randn(input_size, hidden_size) * np.sqrt(1./input_size)
self.W2 = np.random.randn(hidden_size, output_size) * np.sqrt(1./hidden_size)
def sigmoid(self, x, derivative=False):
if derivative:
return x * (1 - x)
return 1 / (1 + np.exp(-x))
def forward(self, X):
self.z1 = np.dot(X, self.W1)
self.a1 = self.sigmoid(self.z1)
self.z2 = np.dot(self.a1, self.W2)
self.a2 = self.sigmoid(self.z2)
return self.a2
def backward(self, X, y, output):
# 输出层误差
self.error = output - y
self.delta2 = self.error * self.sigmoid(self.a2, derivative=True)
# 隐藏层误差
self.error_hidden = self.delta2.dot(self.W2.T)
self.delta1 = self.error_hidden * self.sigmoid(self.a1, derivative=True)
# 参数更新(加入 L2 正则化)l2_lambda = 0.01
self.W2 -= learning_rate * (self.a1.T.dot(self.delta2) + l2_lambda*self.W2)
self.W1 -= learning_rate * (X.T.dot(self.delta1) + l2_lambda*self.W1)
def train(self, X, y, epochs=1000, lr=0.1):
for i in range(epochs):
output = self.forward(X)
self.backward(X, y, output)
性能优化
实际工程中需要考虑以下优化策略:
- 矩阵运算优化 :
- 使用批处理(batch processing)减少循环次数
-
采用 BLAS 加速库如 OpenBLAS
-
学习率调整 :
- 自适应方法:Adam、RMSprop
-
学习率衰减:$\eta_t = \eta_0 / (1 + decay\cdot t)$
-
梯度处理 :
- 梯度裁剪:
grad = np.clip(grad, -1, 1) - 动量加速:$v_t = \gamma v_{t-1} + \eta\nabla_\theta J(\theta)$
常见问题
- 梯度消失 :深层网络中较早层的梯度变得极小
-
解决方案:使用 ReLU 激活函数、残差连接
-
梯度爆炸 :梯度值超过浮点表示范围
-
解决方案:梯度裁剪、权重正则化
-
局部最优 :模型陷入非全局最优解
- 解决方案:随机初始化、增加噪声
延伸思考
- 如何将反向传播扩展到卷积神经网络(CNN)中?
- 二阶优化方法(如牛顿法)为何在深度学习中较少使用?
- 对比自动微分与符号微分的实现差异
通过本文的数学推导和代码实践,您应该对反向传播有了更深入的理解。建议尝试修改网络结构或损失函数,观察训练过程的变化,这是掌握算法的最佳方式。
正文完
发表至: 未分类
近一天内
