共计 2097 个字符,预计需要花费 6 分钟才能阅读完成。
神经网络基础概念
BP 神经网络(Back Propagation Neural Network)是一种多层前馈神经网络,通过误差反向传播算法进行训练。其核心包含两个关键过程:正向传播(Forward Propagation)和反向传播(Back Propagation)。

正向传播
正向传播是指输入数据从输入层经过隐藏层到输出层的计算过程,最终得到预测输出。数学表达式为:
$$
z^{(l)} = W^{(l)}a^{(l-1)} + b^{(l)}
$$
$$
a^{(l)} = \sigma(z^{(l)})
$$
其中 $W^{(l)}$ 和 $b^{(l)}$ 分别是第 $l$ 层的权重和偏置,$\sigma$ 是激活函数。
反向传播
反向传播是根据输出误差来调整网络参数的过程,核心是链式法则。首先定义损失函数 $L$,然后计算损失对参数的梯度:
$$
\frac{\partial L}{\partial W^{(l)}} = \frac{\partial L}{\partial z^{(l)}} \cdot \frac{\partial z^{(l)}}{\partial W^{(l)}} = \delta^{(l)} \cdot a^{(l-1)T}
$$
其中 $\delta^{(l)} = \frac{\partial L}{\partial z^{(l)}}$ 是第 $l$ 层的误差项。
Python 实现
下面我们使用 NumPy 实现一个简单的三层 BP 神经网络。
import numpy as np
class NeuralNetwork:
def __init__(self, input_size, hidden_size, output_size):
# 初始化权重
self.W1 = np.random.randn(input_size, hidden_size) * 0.01
self.b1 = np.zeros((1, hidden_size))
self.W2 = np.random.randn(hidden_size, output_size) * 0.01
self.b2 = np.zeros((1, output_size))
def sigmoid(self, z):
return 1 / (1 + np.exp(-z))
def sigmoid_derivative(self, z):
return self.sigmoid(z) * (1 - self.sigmoid(z))
def forward(self, X):
# 正向传播
self.z1 = np.dot(X, self.W1) + self.b1
self.a1 = self.sigmoid(self.z1)
self.z2 = np.dot(self.a1, self.W2) + self.b2
self.a2 = self.sigmoid(self.z2)
return self.a2
def backward(self, X, y, learning_rate):
# 反向传播
m = X.shape[0]
# 输出层误差
delta2 = (self.a2 - y) * self.sigmoid_derivative(self.z2)
dW2 = np.dot(self.a1.T, delta2) / m
db2 = np.sum(delta2, axis=0, keepdims=True) / m
# 隐藏层误差
delta1 = np.dot(delta2, self.W2.T) * self.sigmoid_derivative(self.z1)
dW1 = np.dot(X.T, delta1) / m
db1 = np.sum(delta1, axis=0, keepdims=True) / m
# 更新参数
self.W1 -= learning_rate * dW1
self.b1 -= learning_rate * db1
self.W2 -= learning_rate * dW2
self.b2 -= learning_rate * db2
调优实践
学习率选择
学习率是影响训练效果的关键超参数。常见策略包括:
- 固定学习率:通常从 0.01 开始尝试
- 学习率衰减:随着训练轮次逐渐降低学习率
- 自适应学习率:如 Adam、RMSprop 等优化算法
梯度消失问题
梯度消失常发生在深层网络使用 sigmoid/tanh 激活函数时。解决方案:
- 使用 ReLU 及其变体作为激活函数
- 采用 Batch Normalization
- 使用残差连接
参数初始化
良好的初始化可以加速收敛:
- Xavier 初始化:适合 tanh 激活函数
- He 初始化:适合 ReLU 激活函数
- 随机初始化:小随机数避免对称性
常见错误排查
- 梯度爆炸:表现为 NaN 值,可尝试梯度裁剪
- 模型不收敛:检查学习率是否过大或过小
- 所有神经元输出相同:可能是初始化不当导致
- 训练损失波动大:减小 batch size 或降低学习率
- 验证集性能差:考虑添加正则化或早停
进一步探索
读者可以尝试以下扩展实验:
- 比较 Sigmoid、ReLU、LeakyReLU 等激活函数的训练效果
- 实现 Mini-batch 梯度下降,观察不同 batch size 的影响
- 添加 L2 正则化项防止过拟合
- 增加网络深度,观察梯度消失现象
通过本文的学习,你应该已经掌握了 BP 神经网络的核心原理和实现方法。建议从简单的分类问题开始实践,逐步增加网络复杂度,深入理解深度学习的基本机制。
