基于Python实现的简单数字识别程序

 更新时间:2025年12月25日 08:54:51   作者:ufdf  
文章介绍了如何使用全连接神经网络(MLP)进行MNIST数字识别,包括代码模型定义、训练和测试的步骤,并解释了模型权重保存文件的内容,需要的朋友可以参考下

这里我们使用全连接神经网络(MLP) 实现的 MNIST 数字识别代码,结构更简单,仅包含几个线性层和激活函数。

简易代码

模型定义代码,model.py

import torch.nn as nn

# 定义一个简单的 CNN 模型
class SimpleModel(nn.Module):
    def __init__(self):
        super(SimpleModel, self).__init__()
        self.flatten = nn.Flatten()
        self.fc1 = nn.Linear(28 * 28, 128)
        self.fc2 = nn.Linear(128, 64)
        self.fc3 = nn.Linear(64, 10)
        self.relu = nn.ReLU()
        self.dropout = nn.Dropout(0.2)

    def forward(self, x):
        x = self.flatten(x)  # [B, 1, 28, 28] -> [B, 784]
        x = self.relu(self.fc1(x))
        x = self.dropout(x)
        x = self.relu(self.fc2(x))
        x = self.dropout(x)
        x = self.fc3(x)  # 输出层不加激活(CrossEntropyLoss 内部含 softmax)
        return x

然后训练代码,train.py

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
from model import SimpleModel  # 👈 从 model.py 导入

# 配置
batch_size = 64
learning_rate = 0.001
num_epochs = 10
model_save_path = 'mnist_mlp.pth'

# 数据
transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.1307,), (0.3081,))
])
train_dataset = torchvision.datasets.MNIST(root='./data', train=True, transform=transform, download=True)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True)

# 模型、损失、优化器
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = SimpleModel().to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=learning_rate)

# 训练
print(f"Training on {device}...")
model.train()
for epoch in range(num_epochs):
    total_loss = 0.0
    for images, labels in train_loader:
        images, labels = images.to(device), labels.to(device)
        optimizer.zero_grad()
        outputs = model(images)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        total_loss += loss.item()
    print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {total_loss/len(train_loader):.4f}')

# 保存
torch.save(model.state_dict(), model_save_path)
print(f"✅ Model saved to {model_save_path}")

训练

在训练之前我们需要安装下python依赖

pip install torch torchvision

然后我们就可以开始训练模型啦!执行命令python ./train.py,你会看到类似输出

Training on cpu...
Epoch [1/10], Loss: 0.3501
Epoch [2/10], Loss: 0.1702
Epoch [3/10], Loss: 0.1335
Epoch [4/10], Loss: 0.1141
Epoch [5/10], Loss: 0.1027
Epoch [6/10], Loss: 0.0915
Epoch [7/10], Loss: 0.0884
Epoch [8/10], Loss: 0.0801
Epoch [9/10], Loss: 0.0769
Epoch [10/10], Loss: 0.0715
✅ Model saved to mnist_mlp.pth

目录下会生成一个mnist_mlp.pthmnist_mlp.pth 是一个 PyTorch 模型权重保存文件,本质上是一个 序列化后的字典(state_dict),存储了神经网络中所有可学习参数(如权重和偏置)的数值。

测试模型

现在我们拿我们的模型去试试我们的数字图片了~
predict.py

# predict.py
import torch
import torchvision.transforms as transforms
from PIL import Image
from model import SimpleModel
import argparse
import os

def predict_image(image_path, model_path='mnist_mlp.pth', device='cpu'):
    # 1. 加载模型
    model = SimpleModel()
    model.load_state_dict(torch.load(model_path, map_location=device))
    model.eval()  # 推理模式

    # 2. 图像预处理(必须和训练时一致!)
    transform = transforms.Compose([
        transforms.Grayscale(num_output_channels=1),  # 转灰度
        transforms.Resize((28, 28)),                   # 调整为 28x28
        transforms.ToTensor(),                         # 转为 Tensor [0,1]
        transforms.Normalize((0.1307,), (0.3081,))    # 用 MNIST 的均值/标准差
    ])

    # 3. 加载并预处理图像
    image = Image.open(image_path).convert('L')  # 强制灰度(兼容 RGB 输入)
    input_tensor = transform(image)              # shape: [1, 28, 28]
    input_batch = input_tensor.unsqueeze(0)      # 增加 batch 维度 → [1, 1, 28, 28]

    # 4. 推理
    with torch.no_grad():
        output = model(input_batch)
        probabilities = torch.softmax(output, dim=1)
        predicted_class = torch.argmax(probabilities, dim=1).item()
        confidence = probabilities[0][predicted_class].item()

    return predicted_class, confidence

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Predict digit in an image using trained MLP')
    parser.add_argument('image_path', type=str, help='Path to the input image (e.g., digit.png)')
    args = parser.parse_args()

    if not os.path.exists(args.image_path):
        print(f"❌ Error: Image file '{args.image_path}' not found!")
        exit(1)

    device = 'cuda' if torch.cuda.is_available() else 'cpu'
    digit, conf = predict_image(args.image_path, device=device)

    print(f"✅ Predicted digit: {digit}")
    print(f"📊 Confidence: {conf:.4f} ({conf*100:.2f}%)")

我们可以python .\predict.py .\data\digit.png来看看预测的结果如何。

到此这篇关于基于Python实现的简单数字识别程序的文章就介绍到这了,更多相关Python数字识别程序内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python抛出引发异常(raise)知识点总结

    Python抛出引发异常(raise)知识点总结

    在本篇文章里小编给大家整理了关于Python抛出引发异常(raise)知识点总结内容,有需要的朋友们可以学习参考下。
    2021-06-06
  • Python streamlit库快速构建交互式Web应用

    Python streamlit库快速构建交互式Web应用

    Streamlit 是一个专为数据科学家和机器学习工程师设计的Python库,它可以快速构建交互式Web应用,下面就来详细的介绍一下streamlit库的使用,感兴趣的可以了解一下
    2025-12-12
  • 手把手教你Python yLab的绘制折线图的画法

    手把手教你Python yLab的绘制折线图的画法

    这篇文章主要介绍了手把手教你Python yLab的绘制折线图的画法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-10-10
  • pandas DataFrame 根据多列的值做判断,生成新的列值实例

    pandas DataFrame 根据多列的值做判断,生成新的列值实例

    今天小编就为大家分享一篇pandas DataFrame 根据多列的值做判断,生成新的列值实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-05-05
  • Python入门教程(二十三)Python的继承

    Python入门教程(二十三)Python的继承

    这篇文章主要介绍了Python入门教程(二十三)Python的继承,Python是一门非常强大好用的语言,也有着易上手的特性,本文为入门教程,需要的朋友可以参考下
    2023-04-04
  • 浅谈Python3中打开文件的方式(With open)

    浅谈Python3中打开文件的方式(With open)

    本文主要介绍了浅谈Python3中打开文件的方式(With open),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • 详解Python中的四种队列

    详解Python中的四种队列

    队列是一种只允许在一端进行插入操作,而在另一端进行删除操作的线性表。这篇文章主要介绍了Python中的四种队列,需要的朋友可以参考下
    2018-05-05
  • PyQt转换路径中的斜杠(斜杠(/)与反斜杠(\)转换)

    PyQt转换路径中的斜杠(斜杠(/)与反斜杠(\)转换)

    本文主要介绍了PyQt转换路径中的斜杠(斜杠(/)与反斜杠(\)转换),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • 超全面python常见报错以及解决方案梳理必收藏

    超全面python常见报错以及解决方案梳理必收藏

    使用python难免会出现各种各样的报错,以下是Python常见的报错以及解决方法(持续更新),快进入收藏吃灰吧
    2022-03-03
  • 基于Python实现温度单位转换器(新手版)

    基于Python实现温度单位转换器(新手版)

    这篇文章主要为大家详细介绍了如何基于Python实现温度单位转换器,主要是将摄氏温度(C)和华氏温度(F)相互转换,下面小编就来和大家简单介绍一下吧
    2025-08-08

最新评论