使用 PyTorch 构建 MNIST 手写数字识别模型

news2024/9/22 4:19:57
引言

MNIST 数据集是一个经典的机器学习数据集,包含了 70,000 张手写数字图像,其中 60,000 张用于训练,10,000 张用于测试。每张图像都是 28x28 像素的灰度图像,并且已经被居中处理以减少预处理步骤。本文将介绍如何使用 PyTorch 构建一个简单的神经网络来识别 MNIST 数据集中的手写数字。

环境准备

首先确保你已经安装了 PyTorch 库。可以通过以下命令安装:

pip install torch torchvision
数据加载与预处理
  1. 导入必要的库
    import torch
    from torch import nn
    from torch.utils.data import DataLoader
    from torchvision import datasets
    from torchvision.transforms import ToTensor
  2. 下载训练数据集
    training_data = datasets.MNIST(
        root="data",
        train=True,
        download=True,
        transform=ToTensor()
    )
  3. 下载测试数据集
    test_data = datasets.MNIST(
        root="data",
        train=False,
        download=True,
        transform=ToTensor()
    )

    解释:

    • 使用 datasets.MNIST 下载 MNIST 数据集,并将其保存在 "data" 目录下。
    • train=True 表示下载训练集,train=False 表示下载测试集。
    • download=True 表示如果数据集不存在,则下载数据集。
    • transform=ToTensor() 将图像数据转换为 PyTorch 张量。
  4. 展示部分手写数字图像

    from matplotlib import pyplot as plt
    
    figure = plt.figure()
    for i in range(9):
        img, label = training_data[i + 59000]
        figure.add_subplot(3, 3, i + 1)
        plt.title(label)
        plt.axis("off")
        plt.imshow(img.squeeze(), cmap="gray")
    plt.show()

    解释:

    • 使用 matplotlib 库展示一些手写数字图像。
数据加载器
  1. 创建数据加载器
    train_dataloader = DataLoader(training_data, batch_size=64)
    test_dataloader = DataLoader(test_data, batch_size=64)

    解释:

    • 使用 DataLoader 将数据打包成批次,batch_size=64 表示每次迭代返回 64 个样本。
  2. 检查数据形状
    for X, y in test_dataloader:
        print(f"Shape of X [N,C,H,W]: {X.shape}")
        print(f"Shape of y: {y.shape} {y.dtype}")
        break

    解释:

    • 查看数据的形状,确保数据已经被正确打包。
模型定义
  1. 定义神经网络模型
    class NeuralNetwork(nn.Module):
        def __init__(self):
            super().__init__()
            self.flatten = nn.Flatten()
            self.hidden1 = nn.Linear(28 * 28, 128)
            self.hidden2 = nn.Linear(128, 256)
            self.hidden3 = nn.Linear(256, 128)
            self.hidden4 = nn.Linear(128, 256)
            self.hidden5 = nn.Linear(256, 128)
            self.out = nn.Linear(128, 10)
    
        def forward(self, x):
            x = self.flatten(x)
            x = self.hidden1(x)
            x = torch.sigmoid(x)
            x = self.hidden2(x)
            x = torch.sigmoid(x)
            x = self.hidden3(x)
            x = torch.sigmoid(x)
            x = self.hidden4(x)
            x = torch.sigmoid(x)
            x = self.hidden5(x)
            x = torch.sigmoid(x)
            x = self.out(x)
            return x

    解释:

    • 定义一个简单的多层感知器模型。
    • 使用 nn.Flatten 展平输入图像。
    • 多个全连接层 (nn.Linear) 和激活函数 (torch.sigmoid)。
  2. 实例化模型并移动到 GPU
    device = "cuda" if torch.cuda.is_available() else "mps" if torch.backends.mps.is_available() else 'cpu'
    print(f"Using {device} device")
    
    model = NeuralNetwork().to(device)
    print(model)

    解释:

    • 检查是否有可用的 GPU 并将模型移动到 GPU 上。
训练与测试
  1. 定义损失函数和优化器
    loss_fn = nn.CrossEntropyLoss()
    optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
  2. 定义训练函数
    def train(dataloader, model, loss_fn, optimizer):
        model.train()
        batch_size_num = 1
        for X, y in dataloader:
            X, y = X.to(device), y.to(device)
            pred = model(X)
            loss = loss_fn(pred, y)
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            loss_value = loss.item()
            if batch_size_num % 100 == 0:
                print(f"loss: {loss_value:>7f} [number: {batch_size_num}]")
            batch_size_num += 1

    解释:

    • 训练模型并计算损失。
    • 使用梯度下降更新权重。
  3. 定义测试函数

    def test(dataloader, model, loss_fn):
        size = len(dataloader.dataset)
        num_batches = len(dataloader)
        model.eval()
        test_loss, correct = 0, 0
        with torch.no_grad():
            for X, y in dataloader:
                X, y = X.to(device), y.to(device)
                pred = model(X)
                test_loss += loss_fn(pred, y).item()
                correct += (pred.argmax(1) == y).type(torch.float).sum().item()
            test_loss /= num_batches
            correct /= size
            print(f"Test result: \n Accuracy: {(100 * correct):>0.1f}%, Avg loss: {test_loss:>8f}")

    解释:

    • 测试模型并计算准确率和平均损失。
  4. 训练和测试模型
    epochs = 10
    for t in range(epochs):
        print(f"Epoch {t + 1}\n--------------------------")
        train(train_dataloader, model, loss_fn, optimizer)
    print("Done!")
    test(test_dataloader, model, loss_fn)

    解释:

    • 进行多次训练周期(epoch)。
    • 最后测试模型。
  5. 结果







总结

通过上述步骤,我们构建了一个简单的神经网络模型来识别 MNIST 数据集中的手写数字。使用 PyTorch 可以轻松地处理数据、定义模型、训练和测试模型。这个项目不仅展示了如何使用 PyTorch 进行图像识别,还介绍了如何利用 GPU 加速训练过程。希望这篇博客对你有所帮助!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2135211.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

剪辑必备,6个可白嫖的视频素材网站。

找视频素材就上这6个网站,免费下载,赶紧收藏好! 1、菜鸟图库 视频素材下载_mp4视频大全 - 菜鸟图库 菜鸟图库网素材非常丰富,网站主要以设计类素材为主,高清视频素材也很多,像风景、植物、动物、人物、科技…

Redis(主从复制、哨兵模式、集群)概述及部署测试

目录 一、Redis 主从复制 1.1、Redis 主从复制概念 1.2、主从复制的作用 1.3、主从复制流程 1.4、搭建Redis 主从复制 二、Redis 哨兵模式 2.1、Redis 哨兵模式概念 2.2、哨兵模式原理 2.3、哨兵模式的作用 2.4、哨兵模式的结构 2.5、故障转移机制 2.6、主节点的选…

性能诊断的方法(四):自下而上的资源诊断方法和发散的异常信息诊断方法

关于性能诊断的方法,我们可以按照“问题现象—直接原因—问题根源”这样一个思路去归纳。我们先从问题的现象去入手,包括时间的分析、资源的分析和异常信息的分析。接下来再去分析产生问题现象的直接原因是什么,这里我们归纳了自上而下的资源…

从安装ffmpeg开始,把一个视频按照每秒30帧fps剪切为图片

ffmpeg -i demo.mp4 -vf fps1 -start_number 0 %5d.jpg没有ffmpeg 的去官网下载, ffmpeg.org/download.html 下载好之后,解压进入bin文件夹 复制当前路径,下一步 配置环境 进入本机环境变量,把地址添加到path中 之后进入anacond…

Vue - 详细介绍vue-qr在线生成二维码组件(Vue2 Vue3)

Vue - 详细介绍vue-qr在线生成二维码组件(Vue2 & Vue3) 在对于二维码生成中有许多组件,下面介绍关于自定义比较高的vue-qr组件,能自定义设置背景颜色、背景图片、背景Gif图、实点和空白区的颜色、中心Logo的图片和边距。 一…

为什么企业可以通过数据产品实现商业价值

管理者们通常希望可以通过数据洞悉更精准的商业趋势。 根据 Gartner 2023 年的调查显示,有69%的数据分析师或数据管理者们,仍在努力通过数据分析,希望实现可衡量的投资回报率,而数据产品是实现这一难题的重要解决方案之一。 什么…

USBCANFD卡在新能源BMS上位机的应用

使用简明教程:插入一个视频 USBCANFD-401是一款高性能的USB转双路CANFD/LIN的CANFD盒,支持单路CNA(FD)和LIN转USB通信。 通过USB接口快速接入CANFD或LIN通道,使接入CAN/CANFD/LIN网络变得轻松便捷。该设备采用金升阳电源模块和信号隔离芯片&…

GAMES101(2~3作业)

作业2 基础题目: 栅格化:在屏幕绘制一个实心三角形,函数 rasterize_triangle(const Triangle& t),需要找出当前三角形的边界框,然后遍历像素,查找当前像素是否在三角形内static bool insideTriangle(…

ESP32开发 -- 初识

一、ESP32官网 ESP32官网 二、文档下载 用的是ESP32-S3-MINI-1,官网查看相关文档 相关文档 三、技术规格书 四、开发板 参看:ESP32-S3 系列开发板 ESP32-S3-MINI-1 相关开发板的示例代码,后续可以参考。 Espressif Systems esp-dev-…

9天也能养成ins账号!超详细操作指南

Instagram,作为全球最受欢迎的社交媒体平台之一,为跨境电商卖家们提供了一个展示产品、吸引潜在客户的绝佳舞台。然而,受限于ins的规则,要想在这个平台上进行产品的宣传并非易事。 这就是为什么我们需要精心培养一个ins账号&#…

Linux(4)--CentOS8虚拟机下联网

文章目录 1. 背景2. VmWare配置3. 电脑网络配置4. 配置虚拟机网络5. 重启联网 1. 背景 安装CentOS后,尚不能联网,没有网络就不好上网,所以先解决上网问题。 2. VmWare配置 打开VmWare,点击编辑-虚拟网络编辑器,选择…

PyCharm使用ipynb文件交互式绘图

PyCharm配置 Jupyter Notebook 这个文章很全 PyCharm配置 Jupyter Notebook plotly方法 终端安装: pip install plotlyimport plotly.graph_objects as go import numpy as np# 示例数据 X np.linspace(-5, 5, 100) Y np.linspace(-5, 5, 100) X, Y np.meshg…

GNSS的数据样例

武汉大学的数据地址: ftp://igs.gnsswhu.cn/pub/whu/phasebias obit 文件夹下存放的是卫星相关的文件 姿态: 、精密轨道 ERP CLK bias 文件 观测量域的偏差

RWKV作者对OpenAI 发布 o1 系列模型的看法,很深刻

知乎:PENG Bo 链接:https://www.zhihu.com/question/666991594/answer/3624168868 大家都知道长期CoT可以提升性能,而且很快我们会看到其它家的例子,这是最后的low-hanging fruit,因为只需合成大量训练数据&#xff0…

DDR3AXI4接口读写仿真

前文已经介绍了DDR3和AXI4总线的相关知识,我们知道MIG ip核除了可以生成native接口还能生成AXI4接口,今天就练习一下将AXI4接口的DDR3打包成FIFO。首先我们生成一个AXI4接口的MIG ip核,其余步骤与Native接口的ip核相同,如果我们勾…

力扣: 翻转字符串里的单词

文章目录 需求分析代码结尾 需求 给你一个字符串 s ,请你反转字符串中 单词 的顺序。 单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。 返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。 注意:输入字符…

03_Python数据类型_字符串

Python的基础数据类型 数值类型:整数、浮点数、复数、布尔字符串容器类型:列表、元祖、字典、集合 字符串 在Python中,字符串(String)是一种非常重要的数据类型,用于表示文本数据。字符串是不可变的&…

算子级血缘在金融数据环境的实践应用

在企业的数据管理领域,算子级血缘极大优化了脚本内部字段口径的理解与追踪。面对几十、几百乃至几千行代码的复杂脚本,并且有着各种函数调用、数据转换等复杂的加工逻辑,如果通过传统的 ETL 工作模式,开发人员就不得不采用“盲人摸…

SpringBoot整合WebSocket实现消息推送或聊天功能示例

最近在做一个功能&#xff0c;就是需要实时给用户推送消息&#xff0c;所以就需要用到 websocket springboot 接入 websocket 非常简单&#xff0c;只需要下面几个配置即可 pom 文件 <!-- spring-boot-web启动器 --><dependency><groupId>org.springframewo…

深度学习驱动超材料设计领域发展

深度学习在超材料设计领域的应用是一个令人兴奋的研究方向。超材料&#xff08;Metamaterials&#xff09;是一类具有自然界中不存在的特殊性质的人工材料&#xff0c;它们通过精确设计微结构来获得独特的电磁、光学或声学特性。这些特性使得超材料在各个领域都有广泛的应用前景…