共计 1845 个字符,预计需要花费 5 分钟才能阅读完成。
背景介绍
手写数字识别是计算机视觉领域最经典的入门任务之一,广泛应用于银行支票处理、邮政分拣等场景。MNIST 数据集包含 60000 张 28×28 像素的手写数字图片,是验证机器学习算法的标准测试平台。传统方法依赖特征工程,而神经网络通过自动学习特征显著提升了识别准确率。

神经网络基本原理
BP 神经网络由输入层、隐藏层和输出层组成,核心是通过前向传播计算预测值,再通过反向传播调整权重。我们用数学公式描述这个过程:
- 前向传播:
- 隐藏层输出:$h = \sigma(W_1x + b_1)$
-
输出层结果:$y = \text{softmax}(W_2h + b_2)$
-
反向传播:
- 输出层梯度:$\delta_2 = y – \text{true_label}$
- 隐藏层梯度:$\delta_1 = (W_2^T \delta_2) \odot \sigma'(z_1)$
- 参数更新:$W \leftarrow W – \eta \delta x^T$
Python 实现详解
import numpy as np
from sklearn.datasets import fetch_openml
# 数据加载与预处理
mnist = fetch_openml('mnist_784', version=1)
X = mnist.data / 255.0 # 归一化
y = np.eye(10)[mnist.target.astype(int)] # one-hot 编码
# 网络参数初始化
input_size = 784
hidden_size = 128
output_size = 10
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 sigmoid(x):
return 1 / (1 + np.exp(-x))
def sigmoid_derivative(x):
return x * (1 - x)
# 训练过程
learning_rate = 0.1
epochs = 50
batch_size = 64
for epoch in range(epochs):
for i in range(0, len(X), batch_size):
# 前向传播
X_batch = X[i:i+batch_size]
h = sigmoid(np.dot(X_batch, W1) + b1)
y_pred = np.dot(h, W2) + b2
# 计算损失(交叉熵)loss = -np.mean(y[i:i+batch_size] * np.log(y_pred))
# 反向传播
dy = y_pred - y[i:i+batch_size]
dW2 = np.dot(h.T, dy)
db2 = np.sum(dy, axis=0)
dh = np.dot(dy, W2.T) * sigmoid_derivative(h)
dW1 = np.dot(X_batch.T, dh)
db1 = np.sum(dh, axis=0)
# 参数更新
W1 -= learning_rate * dW1
b1 -= learning_rate * db1
W2 -= learning_rate * dW2
b2 -= learning_rate * db2
模型训练实践
- 数据准备:
- 像素值归一化到 [0,1] 范围
- 标签转换为 one-hot 编码
-
建议保留 10% 数据作为验证集
-
超参数设置:
- 初始学习率:0.1-0.01
- 批量大小:32-128
- 隐藏层节点数:64-256
-
训练轮次:20-50
-
训练监控:
- 每 5 个 epoch 输出训练集 / 验证集准确率
- 使用 tqdm 显示进度条
性能优化技巧
- 学习率调整:
- 初始阶段使用较大学习率快速下降
- 后期逐步降低学习率(如乘以 0.95)
-
尝试余弦退火等动态调整策略
-
正则化方法:
- L2 正则化防止过拟合
- Dropout 随机屏蔽部分神经元
- Early Stopping 根据验证集表现提前终止
常见问题解决
- 梯度消失:
- 现象:深层网络训练停滞
-
方案:改用 ReLU 激活函数
-
过拟合:
- 现象:训练准确率高但测试差
-
方案:增加数据增强 / 正则化
-
训练震荡:
- 现象:loss 剧烈波动
- 方案:减小批量大小 / 降低学习率
扩展方向
- 增加网络深度(3- 5 层)
- 尝试卷积神经网络(CNN)
- 使用 PyTorch/TensorFlow 框架
- 在 CIFAR-10 等更复杂数据集测试
经过完整训练后,基础 BP 网络在 MNIST 测试集上可达 95%+ 准确率。建议读者先理解本文基础实现,再逐步尝试更复杂的改进方案。记住调参过程要有耐心,通常需要多次实验才能找到最优组合。
正文完
