BP神经网络手写数字识别实战:从零搭建到模型优化

1次阅读
没有评论

共计 1297 个字符,预计需要花费 4 分钟才能阅读完成。

image.webp

一、为什么选择 BP 神经网络?

传统图像识别方法(如模板匹配)需要人工设计特征,对数字形变、旋转非常敏感。而初学者用 BP 神经网络常遇到:

BP 神经网络手写数字识别实战:从零搭建到模型优化

  • 梯度消失:深层网络难以训练,误差无法有效回传
  • 过拟合:训练集表现好,测试集准确率骤降
  • 收敛慢:学习率设置不当导致训练震荡

二、全连接 vs 卷积网络

对比维度 全连接网络 卷积网络
参数量 较大(MNIST 约 50 万参数) 较小(LeNet 约 6 万参数)
平移不变性
实现难度 简单(适合教学) 中等(需理解卷积操作)

三、核心实现步骤

1. 数据预处理

# MNIST 数据加载(60000 张 28x28 训练图)def load_data():
    with np.load('mnist.npz') as f:
        X_train = f['x_train'].reshape(-1, 784) / 255.0  # 归一化到 [0,1]
        y_train = np.eye(10)[f['y_train']]  # one-hot 编码
        return X_train, y_train

2. 网络初始化

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(hidden_size)
        self.W2 = np.random.randn(hidden_size, output_size) * 0.01
        self.b2 = np.zeros(output_size)

3. 前向传播(含 ReLU 激活)

数学推导:
$$
\begin{aligned}
z_1 &= XW_1 + b_1 \
a_1 &= \text{ReLU}(z_1) \
z_2 &= a_1W_2 + b_2 \
\hat{y} &= \text{softmax}(z_2)
\end{aligned}
$$

四、优化技巧实战

1. 学习率衰减

lr = 0.1 * (0.95 ** (epoch//10))  # 每 10 轮衰减 5%

2. L2 正则化实现

损失函数增加权重惩罚项:
$$
L = -\sum y\log(\hat{y}) + \frac{\lambda}{2}(|W_1|^2 + |W_2|^2)
$$

3. 交叉熵 vs MSE

损失函数 优点 缺点
交叉熵 分类任务梯度更稳定 需配合 softmax 使用
MSE 回归任务表现好 容易梯度饱和

五、新手避坑指南

  1. 输入未归一化 :导致梯度爆炸
  2. 正确做法:像素值除以 255

  3. 权重初始化过大 :造成激活值饱和

  4. 推荐:Xavier 初始化 w = np.random.randn(fan_in, fan_out) * sqrt(2/fan_in)

  5. 忘记 shuffle 数据 :模型记住样本顺序

  6. 解决方法:np.random.permutation 打乱样本

六、性能对比

配置 测试准确率 训练时间
基础网络 (1 隐层) 92.3% 8min
+ 学习率衰减 93.7% 9min
+L2 正则化 (λ=0.01) 95.1% 10min

七、思考题

  1. 如何修改网络结构使准确率突破 98%?
  2. 尝试用动量法(Momentum)加速收敛
  3. 可视化第一层权重,观察学到了什么特征?

完整代码见 GitHub 仓库(伪代码示例,实际需补充完整实现)

正文完
 0
评论(没有评论)