共计 1798 个字符,预计需要花费 5 分钟才能阅读完成。
BP(反向传播)算法是深度学习训练神经网络的基石,它通过高效计算梯度来优化网络参数。没有 BP 算法,现代深度学习的辉煌成就将无从谈起。理解 BP 不仅是为了使用框架,更是为了掌握模型训练的底层逻辑。

数学基础:前向传播与损失计算
以一个单隐层网络为例,输入层有 2 个神经元,隐层 3 个神经元,输出层 1 个神经元。前向传播过程如下:
-
输入层到隐层 :
$$h = \sigma(W_1^T x + b_1)$$
其中 $W_1$ 是 2×3 权重矩阵,$b_1$ 是 3 维偏置向量,$\sigma$ 是 sigmoid 函数。 -
隐层到输出层 :
$$\hat{y} = \sigma(W_2^T h + b_2)$$
$W_2$ 是 3×1 矩阵,$b_2$ 是标量。 -
损失计算 (采用均方误差):
$$L = \frac{1}{2}(y – \hat{y})^2$$
反向传播四步拆解
-
输出层梯度 :
$$\frac{\partial L}{\partial \hat{y}} = -(y – \hat{y})$$
$$\frac{\partial \hat{y}}{\partial z_2} = \sigma'(z_2) = \hat{y}(1-\hat{y})$$
组合得:
$$\delta_2 = (\hat{y} – y) \odot \sigma'(z_2)$$ -
隐层梯度 :
$$\delta_1 = (W_2 \delta_2) \odot \sigma'(z_1)$$ -
权重更新 :
$$\Delta W_2 = h \delta_2^T$$
$$\Delta W_1 = x \delta_1^T$$ -
偏置更新 :
$$\Delta b_2 = \delta_2$$
$$\Delta b_1 = \delta_1$$
Python 实现代码
import numpy as np
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def sigmoid_derivative(x):
return x * (1 - x)
# 网络参数
input_size = 2
hidden_size = 3
output_size = 1
# 初始化权重(注意:这里用较小随机值)W1 = np.random.randn(input_size, hidden_size) * 0.01
b1 = np.zeros((1, hidden_size))
W2 = np.random.randn(hidden_size, output_size) * 0.01
b2 = np.zeros((1, output_size))
# 前向传播
def forward(x):
z1 = np.dot(x, W1) + b1
h = sigmoid(z1)
z2 = np.dot(h, W2) + b2
y_hat = sigmoid(z2)
return y_hat, h
# 反向传播
def backward(x, y, y_hat, h, learning_rate=0.1):
# 输出层梯度
dL_dyhat = -(y - y_hat)
dyhat_dz2 = sigmoid_derivative(y_hat)
delta2 = dL_dyhat * dyhat_dz2
# 隐层梯度
dz2_dh = W2
dh_dz1 = sigmoid_derivative(h)
delta1 = np.dot(delta2, dz2_dh.T) * dh_dz1
# 参数更新
global W1, W2, b1, b2
W2 -= learning_rate * np.dot(h.T, delta2)
b2 -= learning_rate * np.sum(delta2, axis=0, keepdims=True)
W1 -= learning_rate * np.dot(x.T, delta1)
b1 -= learning_rate * np.sum(delta1, axis=0, keepdims=True)
避坑指南
- 梯度消失识别 :当网络深层权重更新量级小于 1e- 5 时需警惕
- 学习率设置 :从 0.01 开始尝试,观察损失曲线震荡情况
- 权重初始化 :避免全零初始化,推荐 Xavier 初始化(
np.random.randn(fan_in, fan_out) * np.sqrt(1/fan_in))
思考题
- 增加网络深度时,如何保证梯度有效传递到浅层?
- 如果用 ReLU 替代 sigmoid,反向传播公式需要做哪些调整?
- 当训练数据量很大时,为什么批量训练比单样本训练更稳定?
通过这个简单的单隐层网络示例,我们已经走完了 BP 算法的完整流程。建议读者在 Jupyter Notebook 中逐行运行代码,观察中间变量的变化规律,这对理解神经网络的工作原理大有裨益。
