Skip to content
ParrotoolsPublic
forked from PiggyHanHan/MNIST

About

MNIST

Resources

Stars

0 stars

Watchers

0 watching

Forks

 
 

Repository files navigation

MNIST 手写数字识别项目总结

📌 项目概述

本项目实现了基于 PyTorch 的卷积神经网络(CNN)来识别 MNIST 手写数字数据集。通过完整的训练、评估和预测流程,展示了深度学习项目的典型步骤,包括环境配置、数据加载、模型定义、训练、测试、模型保存以及对手写图片的实时预测。
后续优化:为提升模型对真实手写风格的泛化能力,引入了 EMNIST 数据集 和 更强的数据增强,训练出增强版模型 mnist_cnn_enhanced.pth。

🚀 环境配置

1. 安装 Miniconda 与 PyCharm

2. 创建虚拟环境

在 PyCharm 中新建项目,选择 Conda 作为新环境,Python 版本选用 3.12(PyTorch 2.10 最高支持到 3.12,避免使用 3.13 导致兼容性问题)。
环境名称可设为 MNIST,位置可自定义(若想放在 E 盘,需在创建时指定 --prefix,或在后续通过导出重建方式迁移)。

3. 安装 PyTorch 及相关库

在 PyCharm 的 Terminal(确保环境激活)中执行以下命令(以 RTX 5060 显卡为例,需 CUDA 12.8 驱动 ≥570.00):

pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu128
pip install matplotlib pillow

注意:增强训练中使用了 transforms.ElasticTransform,要求 torchvision ≥ 0.8.0(一般与 PyTorch 2.x 配套的版本均满足)。

4. 验证 GPU 可用性

import torch
print(torch.cuda.is_available())          # 应输出 True
print(torch.cuda.get_device_name(0))      # 显示 GPU 型号

📂 数据准备

  • 原始 MNIST:通过 torchvision.datasets.MNIST 自动下载(6 万张训练图,1 万张测试图)。
  • 增强数据集 EMNIST(仅数字部分):通过 datasets.EMNIST(split='digits') 自动下载,包含 28 万张额外的手写数字图片,风格比 MNIST 更多样。
  • 训练时使用 ConcatDataset 将两者合并,总训练样本数约 34 万张。
  • 数据预处理:
    • 转为张量 (ToTensor)
    • 标准化 (Normalize):使用 MNIST 全局均值和标准差 (0.1307, 0.3081)
    • 训练集增强:随机旋转/平移/缩放、弹性变形、颜色反转(详见下文)

🧠 模型定义

采用简单的卷积神经网络 SimpleCNN,结构与初始版本完全一致:

  • 卷积层:Conv2d(1,32,3) + ReLU + MaxPool2d(2) → Conv2d(32,64,3) + ReLU + MaxPool2d(2)
  • 全连接层:Linear(64*7*7, 128) + ReLU → Linear(128, 10)

🏋️ 训练过程(增强版)

核心改进

  • 数据增强(训练集专用):
    transforms.RandomAffine(degrees=15, translate=(0.1,0.1), scale=(0.9,1.1))
    transforms.RandomApply([transforms.ElasticTransform(alpha=30.0)], p=0.3)
    transforms.RandomInvert(p=0.3)   # 随机颜色反转,同时适应黑底白字和白底黑字
    transforms.ToTensor()
    transforms.Normalize((0.1307,), (0.3081,))
    • 旋转/平移/缩放:模拟手写位置和倾斜变化
    • 弹性变形:模拟笔画抖动
    • 颜色反转:使模型对背景/前景颜色不敏感
  • 数据集合并:MNIST + EMNIST(数字部分),总训练样本约 34 万张
  • 训练轮次:从原来的 5 轮增加到 12 轮(数据量增大)
  • 损失函数:交叉熵损失 CrossEntropyLoss
  • 优化器:Adam (lr=0.001)
  • 批量大小:64

训练完成后保存增强版模型参数:

torch.save(model.state_dict(), 'mnist_cnn_enhanced.pth')

基础版训练

原版训练脚本(仅用 MNIST、无增强、5 个 epoch)仍保留,生成 mnist_cnn.pth,可用于对比效果。

📊 测试与评估

  • 增强版模型在原始 MNIST 测试集上准确率仍保持 99% 以上,同时对真实手写图片(尤其是个人风格)的识别鲁棒性显著提升。
  • 若仍有特定数字误判(如 6 与 5、9 与 4 混淆),可通过收集个人手写样本进行微调进一步优化。

✍️ 对手写数字图片进行预测

图片预处理关键点

由于训练集(特别是经过颜色反转增强后)已能同时处理黑底白字和白底黑字,预测时不再需要手动强制反转,只需保证图片尺寸和标准化一致即可。
预处理流程(与训练时测试集保持一致):

transform = transforms.Compose([
    transforms.Grayscale(),
    transforms.Resize((28, 28)),
    transforms.ToTensor(),
    transforms.Normalize((0.1307,), (0.3081,))
])

批量预测脚本

项目提供两个预测脚本:

  • batch_predict.py:加载原始模型 mnist_cnn.pth(适用于未增强训练的场景)。
  • batch_predict_enhanced.py:加载增强模型 mnist_cnn_enhanced.pth(推荐使用,效果更佳)。

脚本功能:

  • 遍历指定文件夹(默认为 test_imgs/)中的所有常见图片格式(.png, .jpg, .jpeg, .bmp, .tiff)
  • 输出每个文件的预测数字及前两个候选概率,便于分析置信度
  • 支持异常处理,某张图片失败不影响后续处理

🧩 常见问题与解决方法

1. PyCharm Terminal 激活环境报错

  • 现象:打开 Terminal 显示红色错误 Import-Module: 未能加载指定的模块...
  • 原因:PowerShell 执行策略限制或 Conda 初始化未完成
  • 解决:以管理员身份运行 PowerShell,执行 Set-ExecutionPolicy RemoteSigned 和 conda init powershell,重启 PyCharm;或直接在 Terminal 中手动执行 conda activate MNIST

2. 颜色反转导致识别错误(已解决)

  • 增强版模型通过 RandomInvert 数据增强,已经学会同时适应两种颜色,预测时无需再手动反转。
  • 若仍遇到识别率低,请检查图片是否清晰、数字是否居中,或考虑补充个人手写样本进行微调。

3. 图片缩放与位置

  • 模型期望输入为 28×28 像素,数字居中且大小适中。若原始图片比例不当或数字偏斜,可能影响识别。
  • 建议直接在 28×28 画布上绘制,或确保数字位于中心且笔画较粗。

4. 模型对特定手写风格的误判

  • 尽管增强模型已大幅提升泛化能力,但若你的手写风格与训练集(美式手写)差异极大(如 9 的圆圈大、竖线短),仍可能误判。
  • 解决方法:收集自己的手写样本(几十张),用 ConcatDataset 加入训练集微调,可实现个性化优化。

5. 环境迁移

  • 若需将环境从 C 盘移至其他盘,推荐使用 conda env export > environment.yml 导出依赖,然后在新路径下用 conda env create -f environment.yml 重建。
  • 注意导出前需激活正确的环境,否则 yml 文件可能只包含 base 环境的基础包。

6. 服务端(Ubuntu等)可能遇到情况

  • 虽然我们不难通过命令启动这工程,但是会遇到两个问题,一为如何防止终端关闭后进程不终止,继续运行,二为如何切换剪裁模式
  • 这里提供两个命令
nohup env /root/MNIST/venv312/bin/uvicorn api_color:app --host 0.0.0.0 --port 8000 >uvicorn.log 2>&1 &
nohup env BIND_ADDR=:8080 PY_API_URL=http://127.0.0.1:8000/predict FRONTEND_DIR=/root/MNIST/FrontEnd ./mnist-backend >backend.log 2>&1 &
  • 对于第一个命令,nohup 可以让进程在终端关闭后继续运行,>uvicorn.log 2>&1 & 将输出重定向到日志文件并在后台运行。
  • 对于第二个命令,设置环境变量 BIND_ADDR 指定监听地址和端口,PY_API_URL 指定后端 API 的 URL,FRONTEND_DIR 指定前端文件目录,同样使用 nohup 和重定向日志的方式让进程在后台运行。
  • 第二个命令,参数修改为http://127.0.0.1:8000/predict?adaptive=true 可以开启自适应剪裁模式,适用于不同尺寸的输入图片。

📁 项目文件结构

MNIST/
├── train_mnist.py                # 基础训练脚本(MNIST 原版)
├── train_mnist_enhanced.py       # 增强训练脚本(MNIST+EMNIST+数据增强,生成增强模型)
├── batch_predict.py              # 批量预测脚本(加载 mnist_cnn.pth)
├── batch_predict_enhanced.py     # 批量预测脚本(加载 mnist_cnn_enhanced.pth)
├── mnist_cnn.pth                  # 基础训练模型参数
├── mnist_cnn_enhanced.pth         # 增强训练模型参数
├── test_imgs/                     # 存放待预测的手写数字图片(命名如 1.png, 2.png ...)
├── requirements.txt               # 依赖包列表(可选)
└── README.md                      # 本文件

🎯 总结

本项目从零搭建了一个完整的手写数字识别系统,并针对真实场景的泛化问题进行了优化。核心收获包括:

  • 掌握 PyTorch 基本操作和 CNN 模型构建
  • 学会使用数据增强和外部数据集(EMNIST)提升模型鲁棒性
  • 理解预处理与训练数据分布的一致性对预测的影响
  • 具备独立排查环境问题和迁移项目的能力

通过此项目,你已迈入深度学习实战的大门,后续可挑战更复杂的数据集(如 CIFAR-10、Fashion-MNIST)或尝试模型部署、模型可解释性等技术。


Happy Learning! 🚀


### 主要更新内容说明
1. **项目概述**:增加了“后续优化”部分,说明引入了 EMNIST 和更强的数据增强。
2. **环境配置**:补充了 `ElasticTransform` 对 torchvision 版本的提示。
3. **数据准备**:新增 EMNIST 数据集介绍及合并方式。
4. **训练过程**:新增“增强版”小节,详细描述数据增强、合并数据集、训练轮次等改进。
5. **模型保存**:说明两个模型文件(基础版与增强版)的用途。
6. **批量预测**:区分两个预测脚本,并强调预处理无需手动反转。
7. **文件结构**:更新了项目文件列表,新增增强版训练脚本和预测脚本。
8. **常见问题**:更新了颜色反转、手写风格误判等条目,与增强模型适配。

About

MNIST

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages