共计 1912 个字符,预计需要花费 5 分钟才能阅读完成。
从单层感知机到多层神经网络
单层感知机(Perceptron)是神经网络的最基础形式,但它存在一个致命缺陷:只能解决线性可分问题。这就像试图用一根直线来划分所有复杂形状的数据点——对于 XOR 这类简单非线性问题就无能为力。多层神经网络的提出解决了这个根本性限制,但随之而来的核心挑战就是:如何有效地训练隐藏层的权重?

反向传播的数学本质
反向传播算法的核心是链式求导法则。让我们从一个简单的 3 层网络(输入层 - 隐藏层 - 输出层)出发,拆解权重更新的数学推导过程:
- 前向传播计算 :
- 隐藏层输出:$h = \sigma(W_1x + b_1)$
-
输出层结果:$\hat{y} = \text{softmax}(W_2h + b_2)$
-
损失函数 (交叉熵损失):
$L = -\sum y\log(\hat{y})$ -
反向传播梯度计算 :
- 输出层梯度:$\frac{\partial L}{\partial W_2} = (\hat{y} – y)h^T$
- 隐藏层梯度:$\frac{\partial L}{\partial W_1} = (W_2^T(\hat{y} – y)) \odot \sigma'(z_1) x^T$
这个推导过程中,$\odot$ 表示逐元素相乘,$\sigma’$ 是激活函数的导数。理解这个链式求导过程是掌握反向传播的关键。
Python 完整实现
import numpy as np
from sklearn.datasets import fetch_openml
from sklearn.preprocessing import OneHotEncoder
# 数据加载与预处理
mnist = fetch_openml('mnist_784', version=1)
X = mnist.data.astype('float32') / 255.0
y = OneHotEncoder().fit_transform(mnist.target.reshape(-1,1)).toarray()
# 网络参数初始化
input_size = 784
hidden_size = 128
output_size = 10
lr = 0.01
W1 = np.random.randn(input_size, hidden_size) * 0.01
b1 = np.zeros(hidden_size)
W2 = np.random.randn(hidden_size, output_size) * 0.01
b2 = np.zeros(output_size)
def relu(x):
return np.maximum(0, x)
def relu_derivative(x):
return (x > 0).astype(float)
# 训练循环
for epoch in range(100):
# 前向传播
z1 = np.dot(X, W1) + b1
a1 = relu(z1)
z2 = np.dot(a1, W2) + b2
y_hat = np.exp(z2) / np.sum(np.exp(z2), axis=1, keepdims=True)
# 计算损失
loss = -np.sum(y * np.log(y_hat + 1e-10)) / len(X)
# 反向传播
dz2 = y_hat - y
dW2 = np.dot(a1.T, dz2)
db2 = np.sum(dz2, axis=0)
dz1 = np.dot(dz2, W2.T) * relu_derivative(z1)
dW1 = np.dot(X.T, dz1)
db1 = np.sum(dz1, axis=0)
# 参数更新
W1 -= lr * dW1
b1 -= lr * db1
W2 -= lr * dW2
b2 -= lr * db2
print(f'Epoch {epoch}, Loss: {loss:.4f}')
关键实践建议
- 学习率选择 :
- 从 0.01 开始尝试,观察损失曲线
- 如果损失震荡剧烈,适当减小学习率
-
如果下降过慢,可适度增大
-
批量大小影响 :
- 小批量(如 32/64)通常能带来更好的泛化性能
-
大批量训练更稳定但可能陷入局部最优
-
激活函数选择 :
- Sigmoid:易导致梯度消失,不推荐用于深层网络
- ReLU:计算高效,缓解梯度消失,推荐首选
- LeakyReLU:解决 ReLU 的 ” 神经元死亡 ” 问题
性能优化策略
- 迭代次数与准确率 :
- 绘制训练 / 验证集准确率曲线
-
当验证集准确率不再提升时停止训练(早停)
-
网络结构实验 :
- 尝试不同隐藏层数量(1- 3 层)
- 调整每层神经元数量(64-256 个)
- 添加 Dropout 层防止过拟合
拓展实验建议
- 可视化权重矩阵,观察网络学习到的特征
- 实现学习率衰减策略(如每 10 轮减半)
- 添加 L2 正则化项控制过拟合
- 用 TensorBoard 记录训练过程
通过这个完整实现,你应该已经掌握了 BP 神经网络的核心原理和实践方法。建议从修改网络结构开始,逐步添加更多高级特性,这将帮助你深入理解深度学习的运作机制。
正文完
