从零实现bp神经网络与卷积神经网络分类MNIST数据集实验:原理对比与性能优化

1次阅读
没有评论

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

image.webp

MNIST 数据集与分类任务概述

MNIST 手写数字数据集包含 60,000 张训练图像和 10,000 张测试图像,每张为 28×28 像素的灰度图。作为计算机视觉领域的 ”Hello World”,其技术价值体现在:

从零实现 bp 神经网络与卷积神经网络分类 MNIST 数据集实验:原理对比与性能优化

  • 低维度输入(784 个特征)适合验证模型基础能力
  • 类别平衡(10 类均匀分布)简化了评估流程
  • 清晰的背景 - 前景对比降低了预处理难度

网络架构设计哲学对比

BP 神经网络(全连接网络)

  1. 结构特点:每个神经元与相邻层所有神经元相连
  2. 输入层:784 个神经元(对应图像展平向量)
  3. 隐藏层:典型配置为 256-128 神经元
  4. 输出层:10 个神经元(Softmax 激活)

  5. 参数量计算:
    $$
    P_{BP} = 784×256 + 256×128 + 128×10 = 235,520
    $$

  6. 计算复杂度:
    $$
    O(n^2) \text{(随神经元数量平方增长)}
    $$

卷积神经网络(CNN)

  1. 结构特点:局部连接 + 权重共享
  2. 卷积层:3×3 卷积核提取空间特征
  3. 池化层:2×2 最大池化降低维度
  4. 全连接层:最终分类决策

  5. 参数量计算(示例架构):
    $$
    P_{CNN} = (3×3×1×32) + (3×3×32×64) + 64×128 + 128×10 = 93,834
    $$

  6. 计算优势:
    $$
    O(k^2×C_{in}×C_{out}) \text{(k 为卷积核尺寸)}
    $$

PyTorch 实现详解

数据预处理

import torch
from torchvision import transforms

transform = transforms.Compose([transforms.ToTensor(),
    transforms.Normalize((0.1307,), (0.3081,))  # MNIST 均值标准差
])

BP 网络实现

class BPNet(torch.nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = torch.nn.Linear(784, 256)  # 特征展开层
        self.fc2 = torch.nn.Linear(256, 128) 
        self.out = torch.nn.Linear(128, 10)

    def forward(self, x):
        x = x.view(-1, 784)  # 展平图像
        x = torch.relu(self.fc1(x))
        x = torch.relu(self.fc2(x))
        return torch.log_softmax(self.out(x), dim=1)

CNN 实现

class CNN(torch.nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = torch.nn.Conv2d(1, 32, 3)  # 输入通道 / 输出通道 / 核大小
        self.conv2 = torch.nn.Conv2d(32, 64, 3)
        self.fc = torch.nn.Linear(1600, 10)  # 64*(28-4)/2^2=1600

    def forward(self, x):
        x = torch.max_pool2d(torch.relu(self.conv1(x)), 2)
        x = torch.max_pool2d(torch.relu(self.conv2(x)), 2)
        x = x.view(x.size(0), -1)
        return torch.log_softmax(self.fc(x), dim=1)

训练流程

def train(model, device, train_loader, optimizer, epoch):
    model.train()
    for batch_idx, (data, target) in enumerate(train_loader):
        data, target = data.to(device), target.to(device)
        optimizer.zero_grad()
        output = model(data)
        loss = torch.nn.functional.nll_loss(output, target)
        loss.backward()
        optimizer.step()

性能对比结果

指标 BP 网络(3 层) CNN(2 层)
最高测试准确率 97.8% 99.2%
训练时间 /epoch 45s 68s
GPU 显存占用 1.2GB 1.8GB

关键观察:
– CNN 准确率优势明显(+1.4%)
– BP 网络训练速度更快(约快 33%)
– 早期 epoch 阶段 CNN 收敛更显著

实战避坑指南

学习率设置

  • 初始建议值:BP 网络 0.01,CNN 0.001
  • 损失震荡时降低学习率:optimizer = torch.optim.SGD(model.parameters(), lr=0.1*momentum=0.9)

显存优化技巧

  1. 逐步增加 batch_size(从 64 开始测试)
  2. 使用 torch.utils.data.DataLoader 的 pin_memory 选项加速 CPU-GPU 传输
  3. 梯度累积:每 4 个 batch 更新一次参数

过拟合预防

  • Dropout 层(BP 网络推荐 p =0.5)
  • 早停机制(验证集 loss 连续 3 次不下降时终止)
  • 数据增强:随机旋转±15 度

延伸思考方向

  1. CNN 优势根源:
  2. 局部感受野契合图像空间相关性
  3. 权重共享大幅降低参数量
  4. 池化操作提供平移不变性

  5. 模型轻量化路径:

  6. 将全连接层替换为全局平均池化
  7. 使用深度可分离卷积(Depthwise Separable Convolution)
  8. 量化训练(8 位整型计算)

通过本实验可清晰观察到:虽然 BP 网络实现简单,但 CNN 通过其独特的结构设计,在图像分类任务中展现出更强的特征提取能力。后续优化可重点考虑模型压缩与推理加速技术。

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