共计 1935 个字符,预计需要花费 5 分钟才能阅读完成。
背景与应用价值
BP 神经网络是深度学习的基础架构,广泛应用于图像分类(如 MNIST 手写数字识别)、金融预测等领域。其核心价值在于通过多层非线性变换,自动学习数据的高阶特征表示。以图像识别为例,浅层神经元可捕捉边缘纹理,而深层神经元能组合出更复杂的视觉模式。

数学原理详解
前向传播
设网络含输入层($x$)、隐层($h$)和输出层($\hat{y}$),权重矩阵分别为 $W_1$,$W_2$,偏置为 $b_1$,$b_2$:
$$
h = \sigma(W_1 x + b_1) \
\hat{y} = \text{softmax}(W_2 h + b_2)
$$
其中 $\sigma$ 为 Sigmoid 函数:$\sigma(z) = 1/(1+e^{-z})$
反向传播推导
采用交叉熵损失函数 $L = -\sum y_i \log(\hat{y}_i)$,输出层梯度:
$$
\frac{\partial L}{\partial W_2} = (\hat{y} – y) \cdot h^T \
\frac{\partial L}{\partial b_2} = \hat{y} – y
$$
隐层梯度(链式法则):
$$
\delta_h = W_2^T (\hat{y}-y) \odot \sigma'(z_1) \
\frac{\partial L}{\partial W_1} = \delta_h \cdot x^T \
\frac{\partial L}{\partial b_1} = \delta_h
$$
Python 实现(NumPy)
import numpy as np
class BPNetwork:
def __init__(self, input_size, hidden_size):
# Xavier 初始化防止梯度消失
self.W1 = np.random.randn(input_size, hidden_size) * np.sqrt(2/input_size)
self.b1 = np.zeros(hidden_size)
self.W2 = np.random.randn(hidden_size, 10) * np.sqrt(2/hidden_size)
self.b2 = np.zeros(10)
def relu(self, x):
return np.maximum(0, x)
def softmax(self, x):
exps = np.exp(x - np.max(x))
return exps / np.sum(exps, axis=1, keepdims=True)
def forward(self, x):
self.z1 = np.dot(x, self.W1) + self.b1
self.h = self.relu(self.z1)
self.z2 = np.dot(self.h, self.W2) + self.b2
return self.softmax(self.z2)
def train(self, x, y, lr=0.01):
# 前向传播
y_pred = self.forward(x)
# 反向传播
grad_z2 = y_pred - y
grad_W2 = np.dot(self.h.T, grad_z2)
grad_b2 = np.sum(grad_z2, axis=0)
grad_h = np.dot(grad_z2, self.W2.T)
grad_z1 = grad_h * (self.z1 > 0) # ReLU 导数
grad_W1 = np.dot(x.T, grad_z1)
grad_b1 = np.sum(grad_z1, axis=0)
# 参数更新(带学习率衰减)self.W1 -= lr * grad_W1 / np.sqrt(x.shape[0]) # batch 标准化
self.b1 -= lr * grad_b1 / np.sqrt(x.shape[0])
self.W2 -= lr * grad_W2 / np.sqrt(x.shape[0])
self.b2 -= lr * grad_b2 / np.sqrt(x.shape[0])
实战避坑指南
- 梯度爆炸 :当梯度范数超过 1e5 时,可采用梯度裁剪(
np.clip(grad, -1, 1)) - 参数初始化 :ReLU 网络推荐 He 初始化(arXiv:1502.01852),Sigmoid 推荐 Xavier 初始化
- Batch Size 选择 :
- 小批量(32-256)适合 GPU 并行
- 极大 batch 需配合学习率升温(arXiv:1706.02677)
延伸思考
- 如何通过 Dropout 层(arXiv:1207.0580)抑制过拟合?
- 批量归一化(BN 层)为什么能加速训练(arXiv:1502.03167)?
- 当网络层数加深时,残差连接如何解决退化问题(arXiv:1512.03385)?
通过这个基础实现,读者可进一步尝试调整网络深度、激活函数类型(如 LeakyReLU)等改进方向,建议配合 PyTorch 等框架进行更高效的模型实验。
