共计 1760 个字符,预计需要花费 5 分钟才能阅读完成。
反向传播算法是神经网络训练的引擎,它通过误差的逆向传递高效计算各层参数的梯度。理解其数学本质和实现细节,是掌握深度学习核心技术的必经之路。本文将以二分类问题为例,拆解从理论推导到代码实现的全过程。

网络结构与计算图
考虑一个包含输入层(2 个节点)、隐藏层(3 个节点,Sigmoid 激活)、输出层(1 个节点,Sigmoid 激活)的简单网络,计算图如下:
输入层(x1,x2) → 隐藏层(h1,h2,h3) → 输出层(ŷ)
W1 W2
数学推导步骤
1. 前向传播过程
设输入样本为 X =[x1,x2],权重矩阵和偏置为:
- W1(2×3), b1(1×3)
- W2(3×1), b2(1×1)
计算流程:
- 隐藏层输入:Z1 = X·W1 + b1
- 隐藏层输出:A1 = σ(Z1)
- 输出层输入:Z2 = A1·W2 + b2
- 最终输出:A2 = σ(Z2)
其中 σ 表示 Sigmoid 函数:σ(z)=1/(1+e^{-z})
2. 损失函数梯度
采用交叉熵损失函数:
L = -[y·log(A2) + (1-y)·log(1-A2)]
对输出层权重 W2 的偏导计算(链式法则):
- ∂L/∂A2 = (A2-y)/(A2(1-A2))
- ∂A2/∂Z2 = A2(1-A2)
- ∂Z2/∂W2 = A1.T
最终梯度:∂L/∂W2 = A1.T · (A2-y)
3. 隐藏层梯度计算
继续反向传播到隐藏层权重 W1:
- ∂L/∂A1 = (A2-y) · W2.T
- ∂A1/∂Z1 = A1⊙(1-A1)(⊙表示逐元素乘)
- ∂Z1/∂W1 = X.T
最终梯度:∂L/∂W1 = X.T · [(A2-y)·W2.T ⊙ A1⊙(1-A1)]
Python 实现关键代码
import numpy as np
class TwoLayerNet:
def __init__(self, input_size, hidden_size):
# 初始化建议:Xavier 初始化
self.W1 = np.random.randn(input_size, hidden_size) * np.sqrt(1/input_size)
self.W2 = np.random.randn(hidden_size, 1) * np.sqrt(1/hidden_size)
def sigmoid(self, z):
return 1 / (1 + np.exp(-z))
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, lr):
m = X.shape[0]
# 输出层梯度
dZ2 = self.A2 - y
dW2 = np.dot(self.A1.T, dZ2) / m
# 隐藏层梯度
dA1 = np.dot(dZ2, self.W2.T)
dZ1 = dA1 * self.A1 * (1 - self.A1)
dW1 = np.dot(X.T, dZ1) / m
# 梯度裁剪(防止爆炸)for grad in [dW1, dW2]:
np.clip(grad, -1, 1, out=grad)
# 参数更新
self.W1 -= lr * dW1
self.W2 -= lr * dW2
避坑指南
梯度消失处理
当使用 Sigmoid 激活时,若权重初始化过大易导致梯度消失:
- 监控隐藏层梯度范数:
np.linalg.norm(dZ1) - 解决方案:改用 ReLU 激活或残差连接
权重初始化实践
- 隐藏层建议 Xavier 初始化:
scale * np.random.randn(n_in, n_out) - 输出层可尝试 He 初始化:
scale = np.sqrt(2/n_in)
学习率设置
- 初始值通常取 0.01~0.1
- 实施指数衰减:
lr = lr * (0.95 ** epoch)
思考题延伸
- 批量梯度下降改造:
- 在
backward()中累加多个样本的梯度后求平均 -
使用
np.mean(dW, axis=0)替代逐样本更新 -
ReLU 的影响分析:
- 正向传播:
A1 = np.maximum(0, Z1) - 反向传播:
dZ1 = dA1 * (Z1 > 0) - 需注意 ” 死亡 ReLU” 问题(可换用 LeakyReLU)
通过这个完整案例,我们不仅理解了反向传播的数学本质,还掌握了实际编码中的关键技巧。建议读者尝试用不同激活函数和优化策略扩展本例,这是深入理解神经网络运作机制的最佳实践路径。
正文完
