共计 2052 个字符,预计需要花费 6 分钟才能阅读完成。
核心概念解析
BP 神经网络(Backpropagation Neural Network)是一种通过误差反向传播算法训练的多层前馈网络。其核心在于通过链式法则计算梯度,并利用梯度下降更新权重。

前向传播
给定输入 $X$,隐藏层输出计算为:
$$H = \sigma(W_1 X + b_1)$$
输出层结果为:
$$\hat{Y} = \sigma(W_2 H + b_2)$$
其中 $\sigma$ 为 sigmoid 激活函数:
$$\sigma(z) = \frac{1}{1+e^{-z}}$$
反向传播
- 计算输出层误差:
$$\delta_2 = (Y – \hat{Y}) \odot \sigma'(Z_2)$$ - 隐藏层误差:
$$\delta_1 = (W_2^T \delta_2) \odot \sigma'(Z_1)$$ - 权重更新:
$$\Delta W_2 = \eta \delta_2 H^T$$
$$\Delta W_1 = \eta \delta_1 X^T$$
Python 实现详解
网络初始化
import numpy as np
class NeuralNetwork:
def __init__(self, input_size, hidden_size):
# 使用 He 初始化
self.W1 = np.random.randn(hidden_size, input_size) * np.sqrt(2./input_size)
self.b1 = np.zeros((hidden_size, 1))
self.W2 = np.random.randn(1, hidden_size) * np.sqrt(2./hidden_size)
self.b2 = np.zeros((1, 1))
激活函数实现
def sigmoid(self, z):
return 1 / (1 + np.exp(-z))
def sigmoid_derivative(self, z):
s = self.sigmoid(z)
return s * (1 - s)
训练流程
- 前向传播计算预测值
- 计算损失(MSE):
$$L = \frac{1}{2m}\sum(y-\hat{y})^2$$ - 反向传播计算梯度
- 更新权重参数
完整训练代码示例:
def train(self, X, Y, epochs=1000, lr=0.1):
for _ in range(epochs):
# 前向传播
Z1 = np.dot(self.W1, X) + self.b1
A1 = self.sigmoid(Z1)
Z2 = np.dot(self.W2, A1) + self.b2
A2 = self.sigmoid(Z2)
# 反向传播
dZ2 = A2 - Y
dW2 = np.dot(dZ2, A1.T) / m
db2 = np.sum(dZ2, axis=1, keepdims=True) / m
dA1 = np.dot(self.W2.T, dZ2)
dZ1 = dA1 * self.sigmoid_derivative(Z1)
dW1 = np.dot(dZ1, X.T) / m
db1 = np.sum(dZ1, axis=1, keepdims=True) / m
# 参数更新
self.W2 -= lr * dW2
self.b2 -= lr * db2
self.W1 -= lr * dW1
self.b1 -= lr * db1
实战建议
学习率选择
- 常用范围:0.01~0.1
- 可采用学习率衰减策略:
$$\eta_t = \frac{\eta_0}{1+kt}$$
隐藏层设置
- 常见经验公式:
$$N_h = \frac{N_i + N_o}{2} + \sqrt{m}$$
其中 $m$ 为训练样本数
数据预处理
- 必须进行归一化(Normalization):
$$X_{norm} = \frac{X – \mu}{\sigma}$$
常见问题解决方案
梯度消失
- 使用 ReLU 激活函数
- 采用 Batch Normalization
- 使用残差连接
过拟合处理
- L2 正则化:
$$L = L_0 + \frac{\lambda}{2}(||W_1||^2 + ||W_2||^2)$$ - 早停法(Early Stopping)
- Dropout 技术
训练震荡
- 增加 Batch Size
- 使用 Momentum 优化:
$$v_t = \gamma v_{t-1} + \eta \nabla_\theta J(\theta)$$
$$\theta = \theta – v_t$$
进阶挑战
尝试用实现的网络解决 XOR 问题:
# XOR 问题数据
X = np.array([[0,0], [0,1], [1,0], [1,1]]).T
y = np.array([[0,1,1,0]])
# 训练网络
nn = NeuralNetwork(input_size=2, hidden_size=4)
nn.train(X, y, epochs=10000)
观察发现:
– 单层感知机无法解决 XOR 问题
– 加入隐藏层后网络可以学习非线性决策边界
总结
本文从理论基础到代码实现完整讲解了 BP 神经网络的构建过程。建议读者:
1. 先理解数学推导过程
2. 手动实现代码(避免直接复制)
3. 尝试不同超参数组合
4. 扩展到更复杂数据集
通过实践发现,神经网络对参数初始化和学习率非常敏感,需要耐心调试。下一步可以尝试实现更多优化算法(如 Adam)和网络结构(如深层网络)。
正文完
