深度学习入门项目:PyTorch实现MINST手写数字识别

简介: 深度学习入门项目:PyTorch实现MINST手写数字识别

一、MNIST数据集介绍及下载地址
MNIST手写数字识别可以说是机器学习入门的hello word了, MNIST数据集包含70000张手写数字图像:,其中60000张用于训练,10000张用于测试。
官网下载地址:yann.lecun.com/exdb/mnist/
MNIST数据集共有四个文件:
train-images-idx3-ubyte.gz:训练集图片,60000张。
train-labels-idx1-ubyte.gz:训练集图片对应的标签。
t10k-images-idx3-ubyte .gz:测试集图片,10000张。
t10k-labels-idx1-ubyte.gz:测试集图片对应的标签。
图片是0〜9的手写数字图片,共10类,标签是图片的实际数字。每张图片都是28x28的单通道灰度图,且数字居中以减少预处理和加快运行。
可以自己下载数据集并加载迭代器,也可以使用torchvision自带的下载函数进行在线下载。
二、代码结构

data:torchvision在线下载的数据集(程序用的是这个方法)
MNIST:自己下载的数据集(在程序里面没有用到)
save_model:用于存放保存的模型参数的pt文件
dataset.py:数据处理脚本
cnn.py:网络模型脚本
train:训练和测试脚本
eval:验证脚本
三、代码
dataset.py

日期:2021年07月17日

from torch.utils.data import DataLoader
from torchvision import datasets
from torchvision import transforms as tsf
import cv2

batch_size = 64
transform = tsf.Compose([tsf.ToTensor(), tsf.Normalize([0.1307], [0.3081])])

Normalize:正则化,降低模型复杂度,防止过拟合

下载数据集

torchvision已经预先实现了常用的Dataset,包括MINST。可以用datasets.MNIST直接从网上下载,并自动建立名为data的文件夹。

train_set=datasets.MNIST(root="data",train=True,download=True,transform=transform)
test_set=datasets.MNIST(root="data",train=False,download=True,transform=transform)

加载数据集,将数据集变成迭代器

def get_data_loader():

train_loader=DataLoader(dataset=train_set,batch_size=batch_size,shuffle=True)
test_loader=DataLoader(dataset=test_set,batch_size=batch_size,shuffle=True)
return train_loader,test_loader

显示数据集中的图片

with open("data/MNIST/raw/train-images-idx3-ubyte","rb") as f:

file=f.read()

image1=[int(str(item).encode('ascii'),16) for item in file[16:16+784]]

image1_np=np.array(image1,dtype=np.uint8).reshape(28,28,1)

cv2.imshow("image1_np",image1_np)

cv2.waitKey(0)

复制代码
cnn.py

日期:2021年07月17日

import torch.nn as nn
import torch.nn.functional as F

class CNN(nn.Module):

def __init__(self):
    super(CNN, self).__init__()
    self.conv1 = nn.Conv2d(in_channels=1, out_channels=10, kernel_size=(5,5))
    self.conv2 = nn.Conv2d(10, 20, kernel_size=(3,3))
    self.fc1 = nn.Linear(in_features=20*10*10, out_features=500)
    self.fc2 = nn.Linear(500, 10)

def forward(self, x):
    # x.shape = batch_size * channels( = 1) *28 * 28
    input_size=x.size(0)   # 获取batch_size

    x=self.conv1(x)
    # input:batch_size * 1 * 28 * 28   (in_channels=1, out_channels=10)
    # oouput:batch_size * 10 * 24 * 24  (24=28-5+1)

    x=F.relu(x)
    # 激活函数保持shape不变
    # 激活函数使神经网络变成非线性,解决线性模型所不能解决的问题。

    x=F.max_pool2d(x,kernel_size=2,stride=2)
    # input:batch_size * 10 * 24 * 24
    # output:batch_size * 10 * 12 * 12    (stride=2,因此尺寸减半)

    x=self.conv2(x)
    # input:batch_size * 10 * 12 * 12   (in_channels=1, out_channels=10)
    # output:batch_size * 20 * 10 * 10  (10=12-3+1)

    x=F.relu(x)

    x=x.view(input_size,-1)
    # view()中,当某一维是-1时,会根据给定维度自动计算它的大小
    # 因此-1表示的维度是: batch_size * 20 * 10 * 10 / batch_size = 20 * 10 * 10 =2000

    x=self.fc1(x)
    # input:batch_size * 2000
    # output:batch_size * 500

    x=F.relu(x)

    x=self.fc2(x)
    # input:batch_size * 500
    # output:batch_size * 10    变成十分类

    output=F.log_softmax(x,dim=1)
    # 计算x属于每个分类的概率
    # dim=1表示按行计算

    return output

复制代码
train.py

日期:2021年07月17日

import torch
import cnn
import torch.nn.functional as F
from dataset import get_data_loader
import torch.optim as optim

if name == "__main__":

# 超参
batch_size=64
device=torch.device("cuda" if torch.cuda.is_available() else "cpu")
epoch = 5

# 选择模型
model=cnn.CNN().to(device)

# 定义优化器
optimizer=optim.Adam(model.parameters())

# 加载迭代器
train_loader, test_loader = get_data_loader()

# 训练
def train(epoch_i):
    model.train()   # 设置为训练模式
    for batch_i,(digit,label) in enumerate(train_loader):
        digit,label=digit.to(device),label.to(device)
        optimizer.zero_grad()    # 梯度初始化为0
        output=model(digit)     # 训练结果,output是概率
        loss=F.cross_entropy(output,label)     # 定义损失函数,交叉熵损失函数适用于多分类问题
        loss.backward()    # 反向传播
        optimizer.step()    # 更新参数

        if batch_i % 100 == 0:
            print("train    epoch_i: {}    batch_i: {}    loss: {: .8f}".format(epoch_i,batch_i,loss.item()))

# 测试
def test(epoch_i):
    model.eval()    # 设置为测试模式
    acc = 0.
    loss = 0.
    with torch.no_grad():
        for digit, label in test_loader:
            digit, lable = digit.to(device), label.to(device)
            output = model(digit)  # 模型输出
            loss += F.cross_entropy(output, lable).item()

            predict = output.max(dim=1, keepdim=True)[1]
            # 找到概率最大值的下标,1表示按行计算。
            # max()返回两个值,第一个是值,第二个是索引,所以取 max[1]

            acc += predict.eq(label.view_as(predict)).sum().item()
        accuracy = acc / len(test_loader.dataset) * 100
        test_loss = loss / len(test_loader.dataset)
        print("test     epoch_i: {}    loss: {: .8f}    accuracy: {: .4f}%".format(epoch_i,test_loss,accuracy))

# train && test
for epoch_i in range(1,epoch+1):
    train(epoch_i)
    test(epoch_i)

# 保存模型
torch.save(model,"save_model/model.pt")

复制代码
eval.py

日期:2021年07月17日

import torch
from dataset import get_data_loader

if name == "__main__":

_, eval_loader = get_data_loader()   # 因为没有验证集,所以将测试题作为验证集使用。
batch_size = 64
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = torch.load("save_model/model.pt")    # 加载模型
# model.eval()  # 设置为验证模式

acc = 0.  
with torch.no_grad():
    for digit, label in eval_loader:
        digit, lable = digit.to(device), label.to(device)
        output = model(digit)  # 模型输出
        predict = output.max(dim=1, keepdim=True)[1]
        # 找到概率最大值的下标,1表示按行计算。
        # max()返回两个值,第一个是值,第二个是索引,所以取 max[1]

        acc += predict.eq(label.view_as(predict)).sum().item()
    acceracy = acc/len(eval_loader.dataset) * 100
    print("eval accuracy: {: .4f}%".format(acceracy))

复制代码
四、代码运行命令及测试精度
训练:python train.py
验证:python eval.py
训练精度:
test epoch_i: 1 loss: 0.00083338 accuracy: 98.2700%
test epoch_i: 2 loss: 0.00053913 accuracy: 98.8400%
test epoch_i: 3 loss: 0.00059983 accuracy: 98.8800%
test epoch_i: 4 loss: 0.00063796 accuracy: 98.7200%
test epoch_i: 5 loss: 0.00056076 accuracy: 98.8800%
复制代码
验证精度:
eval accuracy: 98.8800%
复制代码
因为MNIST数据集没有单独的验证集,所以将测试集当做验证集使用。保存的模型是最后一个epoch的模型。因此eval accuracy与最后一个epoch的test accuracy相同。
这个程序只是为了熟悉pytorch深度学习的基本流程,训练集的选择和精度并不重要。

相关文章
|
2月前
|
机器学习/深度学习 人工智能 PyTorch
PyTorch深度学习 ? 带你从入门到精通!!!
🌟 蒋星熠Jaxonic,深度学习探索者。三年深耕PyTorch,从基础到部署,分享模型构建、GPU加速、TorchScript优化及PyTorch 2.0新特性,助力AI开发者高效进阶。
PyTorch深度学习 ? 带你从入门到精通!!!
|
3月前
|
机器学习/深度学习 存储 PyTorch
Neural ODE原理与PyTorch实现:深度学习模型的自适应深度调节
Neural ODE将神经网络与微分方程结合,用连续思维建模数据演化,突破传统离散层的限制,实现自适应深度与高效连续学习。
200 3
Neural ODE原理与PyTorch实现:深度学习模型的自适应深度调节
|
5月前
|
机器学习/深度学习 存储 监控
基于深度学习YOLO框架的城市道路损伤检测与评估项目系统【附完整源码+数据集】
本项目基于深度学习的YOLO框架,成功实现了城市道路损伤的自动检测与评估。通过YOLOv8模型,我们能够高效地识别和分类路面裂缝、井盖移位、坑洼路面等常见的道路损伤类型。系统的核心优势在于其高效性和实时性,能够实时监控城市道路,自动标注损伤类型,并生成损伤评估报告。
295 0
基于深度学习YOLO框架的城市道路损伤检测与评估项目系统【附完整源码+数据集】
|
5月前
|
机器学习/深度学习 自动驾驶 算法
基于深度学习的YOLO框架的7种交通场景识别项目系统【附完整源码+数据集】
在智慧交通和智能驾驶日益普及的今天,准确识别复杂交通场景中的关键元素已成为自动驾驶系统的核心能力之一。传统的图像处理技术难以适应高动态、复杂天气、多目标密集的交通环境,而基于深度学习的目标检测算法,尤其是YOLO(You Only Look Once)系列,因其检测速度快、精度高、可部署性强等特点,在交通场景识别中占据了重要地位。
638 0
基于深度学习的YOLO框架的7种交通场景识别项目系统【附完整源码+数据集】
|
6月前
|
机器学习/深度学习 存储 PyTorch
PyTorch + MLFlow 实战:从零构建可追踪的深度学习模型训练系统
本文通过使用 Kaggle 数据集训练情感分析模型的实例,详细演示了如何将 PyTorch 与 MLFlow 进行深度集成,实现完整的实验跟踪、模型记录和结果可复现性管理。文章将系统性地介绍训练代码的核心组件,展示指标和工件的记录方法,并提供 MLFlow UI 的详细界面截图。
290 2
PyTorch + MLFlow 实战:从零构建可追踪的深度学习模型训练系统
|
10月前
|
机器学习/深度学习 数据可视化 算法
PyTorch生态系统中的连续深度学习:使用Torchdyn实现连续时间神经网络
神经常微分方程(Neural ODEs)是深度学习领域的创新模型,将神经网络的离散变换扩展为连续时间动力系统。本文基于Torchdyn库介绍Neural ODE的实现与训练方法,涵盖数据集构建、模型构建、基于PyTorch Lightning的训练及实验结果可视化等内容。Torchdyn支持多种数值求解算法和高级特性,适用于生成模型、时间序列分析等领域。
532 77
PyTorch生态系统中的连续深度学习:使用Torchdyn实现连续时间神经网络
|
10月前
|
机器学习/深度学习 人工智能 自然语言处理
ModelScope深度学习项目低代码开发
低代码开发平台通过丰富的预训练模型库、高度灵活的预训练模型和强大的微调训练功能,简化深度学习项目开发。以阿里魔搭为例,提供大量预训练模型,支持快速迭代与实时反馈,减少从头训练的时间和资源消耗。开发者可轻松调整模型参数,适应特定任务和数据集,提升模型性能。ModelScope平台进一步增强这些功能,提供模型搜索、体验、管理与部署、丰富的模型和数据资源、多模态任务推理及社区协作,助力高效、环保的AI开发。
545 65
|
9月前
|
机器学习/深度学习 自然语言处理 算法
PyTorch PINN实战:用深度学习求解微分方程
物理信息神经网络(PINN)是一种将深度学习与物理定律结合的创新方法,特别适用于微分方程求解。传统神经网络依赖大规模标记数据,而PINN通过将微分方程约束嵌入损失函数,显著提高数据效率。它能在流体动力学、量子力学等领域实现高效建模,弥补了传统数值方法在高维复杂问题上的不足。尽管计算成本较高且对超参数敏感,PINN仍展现出强大的泛化能力和鲁棒性,为科学计算提供了新路径。文章详细介绍了PINN的工作原理、技术优势及局限性,并通过Python代码演示了其在微分方程求解中的应用,验证了其与解析解的高度一致性。
2869 5
PyTorch PINN实战:用深度学习求解微分方程
|
10月前
|
机器学习/深度学习 PyTorch TensorFlow
深度学习工具和框架详细指南:PyTorch、TensorFlow、Keras
在深度学习的世界中,PyTorch、TensorFlow和Keras是最受欢迎的工具和框架,它们为研究者和开发者提供了强大且易于使用的接口。在本文中,我们将深入探索这三个框架,涵盖如何用它们实现经典深度学习模型,并通过代码实例详细讲解这些工具的使用方法。
|
机器学习/深度学习 人工智能 算法
深度学习入门:用Python构建你的第一个神经网络
在人工智能的海洋中,深度学习是那艘能够带你远航的船。本文将作为你的航标,引导你搭建第一个神经网络模型,让你领略深度学习的魅力。通过简单直观的语言和实例,我们将一起探索隐藏在数据背后的模式,体验从零开始创造智能系统的快感。准备好了吗?让我们启航吧!
342 3

推荐镜像

更多