[Pytorch]手写数字识别——真·手写!

这篇具有很好参考价值的文章主要介绍了[Pytorch]手写数字识别——真·手写!。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Github网址:https://github.com/diaoquesang/pytorchTutorials/tree/main

本教程创建于2023/7/31,几乎所有代码都有对应的注释,帮助初学者理解dataset、dataloader、transform的封装,初步体验调参的过程,初步掌握opencv、pandas、os等库的使用,😋纯手撸手写数字识别项目(为减少代码量简化了部分数据集相关操作),全流程跑通Pytorch!❤️❤️❤️
This tutorial was created on 2023/7/31. Almost all the code has corresponding comments, to help beginners understand dataset, dataloader, transform packaging, preliminary experience of the process of tuning the parameters, the initial grasp of the use of libraries such as opencv, pandas, os, etc., 😋 and get involved in this handwritten digit recognition project (we simplified some dataset-related operations in order to reduce the amount of code). Enjoy the whole process of running Pytorch!❤️❤️❤️

如果喜欢本项目的话,留下你的⭐吧!
Give me a ⭐ if you like this project!文章来源地址https://www.toymoban.com/news/detail-626226.html

一、train.py

import torch
import torchvision

from torch import nn
import torch.nn.functional as F
from torch.utils.data import Dataset, DataLoader
from torchvision import transforms

import os
import cv2 as cv
import pandas as pd


class myDataset(Dataset):  # 定义数据集类
    def __init__(self, annotations_file, img_dir, transform=None,
                 target_transform=None):  # 传入参数(标签路径,图像路径,图像预处理方式,标签预处理方式)
        self.img_labels = pd.read_csv(annotations_file, sep=" ", header=None)
        # 从标签路径中读取标签,sep为划分间隔符,header为列标题的行位置
        self.img_dir = img_dir  # 读取图像路径
        self.transform = transform  # 读取图像预处理方式
        self.target_transform = target_transform  # 读取标签预处理方式

    def __len__(self):
        return len(self.img_labels)  # 读取标签数量作为数据集长度

    def __getitem__(self, idx):  # 从数据集中取出数据
        img_path = os.path.join(self.img_dir, self.img_labels.iloc[
            idx, 0])
        # 从标签对象中取出第idx行第0列(第0列为图像位置所在列)的值(numberImages\5.bmp),并与图像路径(numberImages)进行拼接
        image = cv.imread(img_path)  # 用openCV的imread函数读取图像
        label = self.img_labels.iloc[idx, 1]  # 从标签对象中取出第idx行第1列(第1列为图像标签所在列)的值(5)
        if self.transform:
            image = self.transform(image)  # 图像预处理
        if self.target_transform:
            label = self.target_transform(label)  # 标签预处理
        return image, label  # 返回图像和标签


class myTransformMethod1():  # Python3默认继承object类
    def __call__(self, img):  # __call___,让类实例变成一个可以被调用的对象,像函数
        img = cv.resize(img, (28, 28))  # 改变图像大小
        img = cv.cvtColor(img, cv.COLOR_BGR2RGB)  # 将BGR(openCV默认读取为BGR)改为RGB
        return img  # 返回预处理后的图像

# 测试函数
# print(pd.read_csv("annotations.txt", sep=" ", header=None))
# print(os.path.join("numberImages", pd.read_csv("annotations.txt", sep=" ", header=None).iloc[5, 0]))
# print(pd.read_csv("annotations.txt", sep=" ", header=None).iloc[5, 1])
# cv.imshow("1",cv.imread(os.path.join("numberImages", pd.read_csv("annotations.txt", sep=" ", header=None).iloc[5, 0])))
# cv.waitKey(0)


class myNetwork(nn.Module):  # 定义神经网络
    def __init__(self):
        super().__init__()  # 继承nn.Module的构造器
        self.flatten = nn.Flatten(-3, -1)
        # 继承nn.Module的Flatten函数并改为flatten,考虑到推理时没有batch(CHW),若使用默认值(1,-1)会导致C没有被flatten,故使用(-3,-1)
        self.linear_relu_stack = nn.Sequential(  # 定义前向传播序列
            nn.Linear(3 * 28 * 28, 512),
            nn.ReLU(),
            nn.Linear(512, 512),
            nn.ReLU(),
            nn.Linear(512, 10),
        )

    def forward(self, x):  # 定义前向传播方法
        x = self.flatten(x)
        logits = self.linear_relu_stack(x)
        return logits


# 设置运行环境,默认为cuda,若cuda不可用则改为mps,若mps也不可用则改为cpu
device = (
    "cuda"
    if torch.cuda.is_available()
    else "mps"
    if torch.backends.mps.is_available()
    else "cpu"
)
print(f"Using {device} device")  # 输出运行环境

model = myNetwork().to(device)  # 创建神经网络模型实例

# 设置超参数
learning_rate = 1e-5  # 学习率
batch_size = 8  # 每批数据数量
epochs = 3000  # 总轮数

img_path = "./numberImages"  # 设置图像路径
label_path = "./annotations.txt"  # 设置标签路径

myTransform = transforms.Compose([myTransformMethod1(), transforms.ToTensor()])
# 定义图像预处理组合,ToTensor()中Pytorch将HWC(openCV默认读取为height,width,channel)改为CHW,并将值[0,255]除以255进行归一化[0,1]

myDataset = myDataset(label_path, img_path, myTransform)  # 创建数据集实例

myDataLoader = DataLoader(myDataset, batch_size=batch_size,
                          shuffle=True)
# 创建数据读取器(可对训练集和测试集分别创建),batch_size为每批数据数量(一般为2的n次幂以提高运行速度),shuffle为随机打乱数据

def train():
    # 根据epochs(总轮数)训练
    for epoch in range(epochs):
        totalLoss = 0
        # 分批读取数据
        for batch, (images, labels) in enumerate(myDataLoader):
            # 数据转换到对应运行环境
            images = images.to(device)
            labels = labels.to(device)

            pred = model(images)  # 前向传播

            myLoss = nn.CrossEntropyLoss()  # 定义损失函数(交叉熵)
            optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)  # 定义优化器

            loss = myLoss(pred, labels)  # 计算损失函数

            totalLoss += loss  # 计入总损失函数

            loss.backward()  # 反向传播
            optimizer.step()  # 更新权重
            optimizer.zero_grad()  # 清空梯度

            if batch % 1 == 0:  # 每隔1个batch输出1次loss
                loss, current = loss.item(), min((batch + 1) * batch_size,len(myDataset))
                print(f"epoch: {epoch:>5d} loss: {loss:>7f}  [{current:>5d}/{len(myDataset):>5d}]")

        if epoch == 0:
            minTotalLoss = totalLoss
        if totalLoss < minTotalLoss:
            print("······························模型已保存······························")
            minTotalLoss = totalLoss
            torch.save(model, "./myModel.pth")  # 保存性能最好的模型


if __name__ == "__main__":
    model.train()  # 设置训练模式
    train()

二、eval.py

import torch
import torchvision

from torch import nn
import torch.nn.functional as F
from torch.utils.data import Dataset, DataLoader
from torchvision import transforms

import os
import cv2 as cv
import pandas as pd


class myTransformMethod1():  # Python3默认继承object类
    def __call__(self, img):  # __call___,让类实例变成一个可以被调用的对象,像函数
        img = cv.resize(img, (28, 28))  # 改变图像大小
        img = cv.cvtColor(img, cv.COLOR_BGR2RGB)  # 将BGR(openCV默认读取为BGR)改为RGB
        return img  # 返回预处理后的图像


class myNetwork(nn.Module):  # 定义神经网络
    def __init__(self):
        super().__init__()  # 继承nn.Module的构造器
        self.flatten = nn.Flatten(-3, -1)
        # 继承nn.Module的Flatten函数并改为flatten,考虑到推理时没有batch(CHW),若使用默认值(1,-1)会导致C没有被flatten,故使用(-3,-1)
        self.linear_relu_stack = nn.Sequential(  # 定义前向传播序列
            nn.Linear(3 * 28 * 28, 512),
            nn.ReLU(),
            nn.Linear(512, 512),
            nn.ReLU(),
            nn.Linear(512, 10),
        )

    def forward(self, x):  # 定义前向传播方法
        x = self.flatten(x)
        logits = self.linear_relu_stack(x)
        return logits


if __name__ == "__main__":
    model = torch.load("./myModel.pth").to("cuda")  # 载入模型
    model.eval()  # 设置推理模式
    myTransform = transforms.Compose([myTransformMethod1(), transforms.ToTensor()])
    # 定义图像预处理组合,ToTensor()中Pytorch将HWC(openCV默认读取为height,width,channel)改为CHW,并将值[0,255]除以255进行归一化[0,1]
    for i in range(10):
        img = cv.imread("./numberImages/"+str(i)+".bmp")  # 用openCV的imread函数读取图像
        img = myTransform(img).to("cuda")  # 图像预处理
        print(torch.argmax(model(img)))

三、其余资料详见Github

到了这里,关于[Pytorch]手写数字识别——真·手写!的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • AI学习(4): PyTorch实战-手写数字识别

    在之前的文章中介绍了 PyTorch 的环境安装,和张量( tensor )的基本使用,为防止陷入枯燥的理论学习中,在这篇文章,我们将进行项目实战学习,项目主要内容: 基于 MNIST 数据集,实现一个手写数字识别的神经网络模型; @说明: 通过具体项目实战,我们可以初步了解:使用

    2024年02月21日
    浏览(47)
  • 【神经网络手写数字识别-最全源码(pytorch)】

    Torch安装的方法 学习方法 1.边用边学,torch只是一个工具,真正用,查的过程才是学习的过程 2.直接就上案例就行,先来跑,遇到什么来解决什么 Mnist分类任务: 网络基本构建与训练方法,常用函数解析 torch.nn.functional模块 nn.Module模块 读取Mnist数据集 会自动进行下载 784是m

    2024年02月14日
    浏览(39)
  • pytorch 入门 (三)案例一:mnist手写数字识别

    本文为🔗小白入门Pytorch内部限免文章 🍨 本文为🔗小白入门Pytorch中的学习记录博客 🍦 参考文章:【小白入门Pytorch】mnist手写数字识别 🍖 原作者:K同学啊 ​ 如果设备上支持GPU就使用GPU,否则使用CPU 使用dataset下载MNIST数据集,并划分好训练集与测试集 使用dataloader加载数

    2024年02月07日
    浏览(49)
  • 用PyTorch实现MNIST手写数字识别(最新,非常详细)

    本文基于 PyTorch 框架,采用 CNN卷积神经网络 实现 MNIST 手写数字识别,仅在 CPU 上运行。 已分别实现使用Linear纯线性层、CNN卷积神经网络、Inception网络、和Residual残差网络四种结构对MNIST数据集进行手写数字识别,并对其识别准确率进行比较分析。(另外三种还未发布) 看完

    2024年02月06日
    浏览(37)
  • PyTorch训练RNN, GRU, LSTM:手写数字识别

    数据集:MNIST 该数据集的内容是手写数字识别,其分为两部分,分别含有60000张训练图片和10000张测试图片 图片来源:https://tensornews.cn/mnist_intro/ 神经网络:RNN, GRU, LSTM 【1】https://www.youtube.com/watch?v=Gl2WXLIMvKAlist=PLhhyoLH6IjfxeoooqP9rhU3HJIAVAJ3Vzindex=5

    2024年02月15日
    浏览(42)
  • pytorch集智-5手写数字识别器-卷积神经网络

    简称:CNN,convolutional neural network 应用场景:图像识别与分类(CNN),看图说话(CNN+RNN)等 优越性:和多层感知机相比,cnn可以识别独特的模式,可以自动从数据中提取特征。一般机器学习需要特征工程,cnn可以自动识别,极大代替或取代了特征工程 和多层感知机原理不同

    2024年01月19日
    浏览(43)
  • PyTorch训练简单的全连接神经网络:手写数字识别

    数据集:MNIST 该数据集的内容是手写数字识别,其分为两部分,分别含有60000张训练图片和10000张测试图片 神经网络:全连接网络 【1】https://www.youtube.com/watch?v=Jy4wM2X21u0list=PLhhyoLH6IjfxeoooqP9rhU3HJIAVAJ3Vzindex=3

    2024年02月16日
    浏览(36)
  • [深度学习实战]基于PyTorch的深度学习实战(下)[Mnist手写数字图像识别]

    PyTorch——开源的Python机器学习库   首先感谢所有点开本文的朋友们!基于PyTorch的深度学习实战可能要告一段落了。本想着再写几篇关于 PyTorch神经网络深度学习 的文章来着,可无奈项目时间紧任务重,要求 短时间内出图并做好参数拟合 。所以只得转战 Matlab 编程,框架旧

    2024年02月16日
    浏览(55)
  • 真的不能再详细了,2W字保姆级带你一步步用Pytorch搭建卷积神经网络实现MNIST手写数字识别

    目录 一、引言(环境)  二、正文 1. 代码基本情况介绍 2. MNIST数据集介绍         3. 代码输出结果介绍 数据集取样: 训练信息输出: 前三次训练成果以及预测: 八次训练的结果:  4. 代码拆解讲解 基本的参数设定 MNIST数据集下载、保存与加载 神经网络模型 训练前的准

    2023年04月20日
    浏览(38)
  • 在树莓派上实现numpy的LSTM长短期记忆神经网络做图像分类,加载pytorch的模型参数,推理mnist手写数字识别

    这几天又在玩树莓派,先是搞了个物联网,又在尝试在树莓派上搞一些简单的神经网络,这次搞得是LSTM识别mnist手写数字识别 训练代码在电脑上,cpu就能训练,很快的: 然后需要自己在dataset里导出一些图片:我保存在了mnist_pi文件夹下,“_”后面的是标签,主要是在pc端导出

    2024年02月07日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包