使用残差网络识别手写数字及MNIST 数据集介绍

MNIST 数据集已经是一个几乎每个初学者都会接触的数据集, 很多实验、很多模型都会以MNIST 数据集作为训练对象, 不过有些人可能对它还不是很了解, 那么今天我们一起来学习一下MNIST 数据集。

1.MNIST 介绍

MNIST 数据集来自美国国家标准与技术研究所, National Institute of Standards and Technology (NIST). 训练集 (training set) 由来自 250 个不同人手写的数字构成, 其中 50% 是高中学生, 50% 来自人口普查局 (the Census Bureau) 的工作人员. 测试集(test set) 也是同样比例的手写数字数据.

MNIST 数据集包含了四个部分:

  • Training set images: train-images-idx3-ubyte.gz (9.9 MB, 解压后 47 MB, 包含 60,000 个样本)
  • Training set labels: train-labels-idx1-ubyte.gz (29 KB, 解压后 60 KB, 包含 60,000 个标签)
  • Test set images: t10k-images-idx3-ubyte.gz (1.6 MB, 解压后 7.8 MB, 包含 10,000 个样本)
  • Test set labels: t10k-labels-idx1-ubyte.gz (5KB, 解压后 10 KB, 包含 10,000 个标签)

在这里插入图片描述

Size: 28×28 灰度手写数字图像
Num: 训练集 60000 和 测试集 10000,一共70000张图片
Classes: 0,1,2,3,4,5,6,7,8,9

在这里插入图片描述

2.数据集读取

2.1官网下载MNIST 数据集

MNIST 数据集可在 http://yann.lecun.com/exdb/mnist/ 获取
注意:不要直接点连接,复制连接粘贴到新的浏览器标签页搜索,就不需要账号密码了!!!

2.2 博主分享

同时:博主已将MNIST公开数据集上传至百度网盘,大家可以直接下载学习:
链接: https://pan.baidu.com/s/1-rurbkWdv_veQD8QcQWcRw 提取码: 0213

2.3 直接下载

如果数据集没有下载,修改参数:download=True,直接去下载数据集:

from torchvision import datasets, transforms

train_data = datasets.MNIST(root="./MNIST",
                            train=True,
                            transform=transforms.ToTensor(),
                            download=True)

test_data = datasets.MNIST(root="./MNIST",
                           train=False,
                           transform=transforms.ToTensor(),
                           download=True)

print(train_data)
print(test_data)

如果出现这种错误:

SyntaxError: Non-UTF-8 code starting with \xca in fileD:\PycharmProjects\model-fuxian\data set\MNIST t.py on line 2, but noencoding declared; see http://python.org/dev/peps/pep-0263/ fordetails

大概率是你没加:# coding:gbk,为什么呢?由于 Python 默认使用 ASCII 编码来解析源代码,因此如果源文件中包含了非 ASCII 编码的字符(比如中文字符),那么解释器就可能会抛出 SyntaxError 异常。加上# -- coding: gbk --这样的注释语句可以告诉解释器当前源文件的字符编码格式是 GBK,从而避免源文件中文字符被错误地解析。

如果成功运行会出现这种结果,表示已经开始下载了:

在这里插入图片描述
输出结果:

Dataset MNIST
Number of datapoints: 60000
Root location: ./MNIST
Split: Train
StandardTransform
Transform: ToTensor()
Dataset MNIST
Number of datapoints: 10000
Root location: ./MNIST
Split: Test
StandardTransform
Transform: ToTensor()

3.数据集可视化

import torchvision
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
import numpy as np
import matplotlib.pyplot as plt

train_data = datasets.MNIST(root="model-fuxian/data set/MNIST/MNIST/raw/MNIST",
                            train=True,
                            transform=transforms.ToTensor(),
                            download=False)

train_loader = DataLoader(dataset=train_data,
                          batch_size=64,
                          shuffle=True)

for num, (image, label) in enumerate(train_loader):
    image_batch = torchvision.utils.make_grid(image, padding=2)
    plt.imshow(np.transpose(image_batch.numpy(), (1, 2, 0)), vmin=0, vmax=255)
    plt.show()
    print(label)

得到图片:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这是标签:

tensor([2, 1, 7, 7, 2, 4, 2, 2, 0, 1, 7, 1, 5, 7, 9, 0, 2, 7, 4, 7, 0, 2, 7, 1,
        6, 9, 1, 1, 1, 5, 4, 3, 8, 0, 1, 0, 1, 3, 8, 0, 1, 4, 5, 1, 8, 4, 7, 3,
        8, 3, 2, 2, 0, 0, 4, 0, 2, 9, 7, 1, 8, 3, 2, 3])
tensor([6, 6, 7, 2, 5, 4, 0, 3, 4, 6, 1, 4, 1, 9, 2, 2, 8, 7, 5, 7, 9, 6, 6, 7,
        1, 9, 9, 5, 5, 6, 9, 6, 8, 5, 5, 7, 8, 9, 8, 3, 1, 0, 1, 4, 6, 1, 8, 6,
        1, 4, 6, 7, 1, 9, 5, 4, 3, 4, 6, 1, 7, 3, 7, 6])
tensor([7, 1, 5, 1, 4, 0, 9, 2, 2, 0, 1, 5, 2, 3, 6, 4, 6, 9, 3, 3, 2, 8, 1, 5,
        8, 0, 1, 4, 5, 6, 2, 6, 4, 9, 2, 0, 7, 2, 0, 1, 2, 4, 4, 6, 5, 9, 1, 2,
        5, 3, 3, 8, 8, 3, 4, 5, 2, 6, 0, 0, 8, 7, 1, 7])

4.使用残差网络RESNET识别手写数字

没有GPU的可以使用CPU,不过速度会大打折扣:DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu"),最好是可以使用GPU,这样速度会快很多: torch.device("cuda")#使用GPU

# coding=gbk
# 1.加载必要的库
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets,transforms
import argparse

# 2.超参数
BATCH_SIZE = 32#每批处理的数据 一次性多少个
DEVICE  = torch.device("cuda")#使用GPU
# DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")#使用GPU
EPOCHS =4 #训练数据集的轮次
# 3.图像处理
pipeline = transforms.Compose([transforms.ToTensor(), #将图片转换为Tensor
                               ])

# 4.下载,加载数据
from torch.utils.data import DataLoader
 #下载
train_set = datasets.MNIST("data",train=True,download=True,transform=pipeline)
test_set = datasets.MNIST("data",train=False,download=True,transform=pipeline)
 #加载 一次性加载BATCH_SIZE个打乱顺序的数据
train_loader = DataLoader(train_set,batch_size=BATCH_SIZE,shuffle=True)
test_loader = DataLoader(test_set,batch_size=BATCH_SIZE,shuffle=True)


# 5.构建网络模型
class ResBlk(nn.Module):  # 定义Resnet Block模块
    """
    resnet block
    """

    def __init__(self, ch_in, ch_out, stride=1):  # 进入网络前先得知道传入层数和传出层数的设定
        """
        :param ch_in:
        :param ch_out:
        """
        super(ResBlk, self).__init__()  # 初始化

        # we add stride support for resbok, which is distinct from tutorials.
        # 根据resnet网络结构构建2个(block)块结构 第一层卷积 卷积核大小3*3,步长为1,边缘加1
        self.conv1 = nn.Conv2d(ch_in, ch_out, kernel_size=3, stride=stride, padding=1)
        # 将第一层卷积处理的信息通过BatchNorm2d
        self.bn1 = nn.BatchNorm2d(ch_out)
        # 第二块卷积接收第一块的输出,操作一样
        self.conv2 = nn.Conv2d(ch_out, ch_out, kernel_size=3, stride=1, padding=1)
        self.bn2 = nn.BatchNorm2d(ch_out)

        # 确保输入维度等于输出维度
        self.extra = nn.Sequential()  # 先建一个空的extra
        if ch_out != ch_in:
            # [b, ch_in, h, w] => [b, ch_out, h, w]
            self.extra = nn.Sequential(
                nn.Conv2d(ch_in, ch_out, kernel_size=1, stride=stride),
                nn.BatchNorm2d(ch_out)
            )

    def forward(self, x):  # 定义局部向前传播函数
        out = F.relu(self.bn1(self.conv1(x)))  # 对第一块卷积后的数据再经过relu操作
        out = self.bn2(self.conv2(out))  # 第二块卷积后的数据输出
        out = self.extra(x) + out  # 将x传入extra经过2块(block)输出后与原始值进行相加
        out = F.relu(out)  # 调用relu
        return out


class ResNet18(nn.Module):  # 构建resnet18层

    def __init__(self):
        super(ResNet18, self).__init__()

        self.conv1 = nn.Sequential(  # 首先定义一个卷积层
            nn.Conv2d(1, 32, kernel_size=3, stride=3, padding=0),
            nn.BatchNorm2d(32)
        )
        # followed 4 blocks 调用4次resnet网络结构,输出都是输入的2倍
        self.blk1 = ResBlk(32, 64, stride=1)
        self.blk2 = ResBlk(64, 128, stride=1)
        self.blk3 = ResBlk(128, 256, stride=1)
        self.blk4 = ResBlk(256, 256, stride=1)
        self.outlayer = nn.Linear(256 * 1 * 1, 10)  # 最后是全连接层

    def forward(self, x):  # 定义整个向前传播

        x = F.relu(self.conv1(x))  # 先经过第一层卷积

        x = self.blk1(x)  # 然后通过4次resnet网络结构
        x = self.blk2(x)
        x = self.blk3(x)
        x = self.blk4(x)

        x = F.adaptive_avg_pool2d(x, [1, 1])
        # print('after pool:', x.shape)
        x = x.view(x.size(0), -1)  # 平铺一维值
        x = self.outlayer(x)  # 全连接层

        return x
# 6.定义优化器
model = ResNet18().to(DEVICE)#创建模型并将模型加载到指定设备上

optimizer = optim.Adam(model.parameters(),lr=0.001)#优化函数

criterion = nn.CrossEntropyLoss()
# 7.训练
def train_model(model,device,train_loader,optimizer,epoch):
    # Training settings
    parser = argparse.ArgumentParser(description='PyTorch MNIST Example')
    parser.add_argument('--batch-size', type=int, default=64, metavar='N',
                        help='input batch size for training (default: 64)')
    parser.add_argument('--test-batch-size', type=int, default=1000, metavar='N',
                        help='input batch size for testing (default: 1000)')
    parser.add_argument('--epochs', type=int, default=14, metavar='N',
                        help='number of epochs to train (default: 14)')
    parser.add_argument('--lr', type=float, default=1.0, metavar='LR',
                        help='learning rate (default: 1.0)')
    parser.add_argument('--gamma', type=float, default=0.7, metavar='M',
                        help='Learning rate step gamma (default: 0.7)')
    parser.add_argument('--no-cuda', action='store_true', default=False,
                        help='disables CUDA training')
    parser.add_argument('--dry-run', action='store_true', default=False,
                        help='quickly check a single pass')
    parser.add_argument('--seed', type=int, default=1, metavar='S',
                        help='random seed (default: 1)')
    parser.add_argument('--log-interval', type=int, default=10, metavar='N',
                        help='how many batches to wait before logging training status')
    parser.add_argument('--save-model', action='store_true', default=False,
                        help='For Saving the current Model')
    args = parser.parse_args()


    model.train()#模型训练
    for batch_index,(data ,target) in enumerate(train_loader):
        data,target = data.to(device),target.to(device)#部署到DEVICE上去
        optimizer.zero_grad()#梯度初始化为0
        output = model(data)#训练后的结果
        loss = criterion(output,target)#多分类计算损失
        loss.backward()#反向传播 得到参数的梯度值
        optimizer.step()#参数优化
        if batch_index % args.log_interval == 0:
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                epoch, batch_index * len(data), len(train_loader.dataset),
                       100. * batch_index / len(train_loader), loss.item()))
            if args.dry_run:
                break
# 8.测试
def test_model(model,device,text_loader):
    model.eval()#模型验证
    correct = 0.0#正确率
    global Accuracy
    text_loss = 0.0
    with torch.no_grad():#不会计算梯度,也不会进行反向传播
        for data,target in text_loader:
            data,target = data.to(device),target.to(device)#部署到device上
            output = model(data)#处理后的结果
            text_loss += criterion(output,target).item()#计算测试损失
            pred = output.argmax(dim=1)#找到概率最大的下标
            correct += pred.eq(target.view_as(pred)).sum().item()#累计正确的值
        text_loss /= len(test_loader.dataset)#损失和/加载的数据集的总数
        Accuracy = 100.0*correct / len(text_loader.dataset)
        print("Test__Average loss: {:4f},Accuracy: {:.3f}\n".format(text_loss,Accuracy))
# 9.调用

for epoch in range(1,EPOCHS+1):
    train_model(model,DEVICE,train_loader,optimizer,epoch)
    test_model(model,DEVICE,test_loader)

torch.save(model.state_dict(),'model.ckpt')

在这里插入图片描述

精确度

Test__Average loss: 0.000808,Accuracy: 99.150
最后可以发现准确度达到了99%还高,可以看出来残差网络识别手写数字的准确性还是很高的。
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring MVC+mybatis项目入门:旅游网(四)用户注册——mybatis的配置与使用以及Spring MVC重定向

个人博客:Spring MVCmybatis项目入门:旅游网(四)用户注册2-持久化 | iwtss blog 先看这个! 这是18年的文章,回收站里恢复的,现阶段看基本是没有参考意义的,技术老旧脱离时代(2024年…

MiniMax 悄咪咪上线的这款 AI 产品,好用到爆炸!

大模型太卷了!上周国外某款多模态大模型的出现,立刻掀起了 AI 领域对话式多模态交互的热潮。不管是文字、语音,还是图片,都能与你进行实时交互。随后,谷歌也推出了类似的 Astra。 然而,国外的交互式大模型…

线性回归模型之套索回归

概述 本案例是基于之前的岭回归的案例的。之前案例的完整代码如下: import numpy as np import matplotlib.pyplot as plt from sklearn.linear_model import Ridge, LinearRegression from sklearn.datasets import make_regression from sklearn.model_selectio…

2024年弘连网络FIC大会竞赛题线下决赛题

总结: FIC决赛的时候,很多小问题没发现,在pve平台做题确实很方便。 这套题目复盘完,服务器这块的知识确实收获了很多,对pve集群平台和网络拓扑也有了一定的认识,感谢各位大佬悉心指导。 接下来&#xff0…

【数据结构】哈希表的原理及其实现

文章目录 哈希表的概念哈希函数的设计常见的哈希函数 哈希冲突1. 闭散列代码实现 2. 开散列拉链法的优点 针对开散列哈希的扩展基于开散列拉链法封装哈希表MyHash.h 基于哈希表实现unordered_map类Myunordered_map.h 基于哈希表实现unordered_set类Myunordered_map.h 哈希表的概…

ROCm上运行Transformer

10.7. Transformer — 动手学深度学习 2.0.0 documentation (d2l.ai) 代码 import math import pandas as pd import torch from torch import nn from d2l import torch as d2l#save class PositionWiseFFN(nn.Module):"""基于位置的前馈网络""&qu…

解决Error: error:0308010C:digital envelope routines::unsupported的四种解决方案

问题描述: 报错:Error: error:0308010C:digital envelope routines::unsupported 报错原因: 主要是因为 nodeJs V17 版本发布了 OpenSSL3.0 对算法和秘钥大小增加了更为严格的限制,nodeJs v17 之前版本没影响&am…

Rust后台管理系统Salvo-admin源码编译

1.克隆salvo-admin后台管理系统源码: https://github.com/lyqgit/salvo-admin.git 2.编译 编译成功 3.创建mysql数据库与执行sql脚本 输入名称ry-vue 执行sql脚本 全部执行上面3个sql 修改数据库用户名与密码: 清理及重新编译 cargo clean cargo build 4.运行并测试 cargo…

基于JAVA GUI体育馆管理系统的会员功能

Java GUI即Java图形用户界面,是一种使用图形化元素(如窗口、按钮、文本框等)来构建用户界面的技术。它基于Java的Swing框架,可以用于创建各种复杂的用户界面,包括窗口、对话框、菜单、按钮、文本框、复选框、下拉列表等…

仅需一块 4GB 的 GPU ,就能运行开源大语言模型:Llama3 70B

最强的开源大语言模型 Llama3 已经发布一段时间了,一些盆友资源有限,私信询问是否可以使用 4GB 的 VRAM 在本地运行 Llama3 70B。 与 GPT-4 相比,Llama3 的性能如何?Llama3 使用了哪些关键的前沿技术使其变得如此强大&#xff1f…

Oracle 并行和 session 数量的

这也就是为什么我们指定parallel为4,而实际并行度为8的原因。 insert create index,发现并行数都是加倍的 Indexes seem always created with parallel degree 1 during import as seen from a sqlfile. The sql file shows content like: CREATE INDE…

SwiftUI中List的样式及使用详解(添加、移动、删除、自定义滑动)

SwiftUI中的List可是个好东西,它用于显示可滚动列表的视图容器,类似于UITableView。在List中可以显示静态或动态的数据,并支持垂直滚动。List是一个数据驱动的视图,当数据发生变化时,列表会自动更新。 针对List&#x…

windows 7 10 11快捷键到启动页面

1.快速打开用户启动文件夹 shell:startup 方式2:快速打开系统启动文件夹 shell:Common Startup shell:Common Startup

燃数科技前端25-40K*14薪一面超简单,下周二面啦

​​​​​​​ 文章末尾扫描二维码领取地址 一面 1、自我介绍 2、低代码如何设计的 3、react路由原理 4、react生命周期 5、什么是回调地狱,如何解决 6、jwt和session有什么区别 7、js文件相互引用有什么问题?如何解决 8、一个很大的json文件…

腾讯TDSQL-C灰度发布列存索引; Azure Copilot集成支持Azure上各种托管数据库;

重要更新 1. Copilot for Azure新增了对Azure SQL、 Azure Database for MySQL的支持([8] [14])。Copilot for Azure是微软云提供的基于大模型技术的助手工具,主要能力包括了:该大模型可以获得最新的文档,以及客户的Azure资源情况&#xff0c…

每日百万交易的支付系统,如何设置JVM堆内存大小?

每日百万交易的支付系统,如何设置JVM堆内存大小? 1、支付背景的引入2、支付的核心业务流程3、每日百万交易支付系统的压力在哪里?4、支付系统每秒钟需要处理多少笔支付单5、每个支付订单处理需要耗时多久6、每个支付订单大概需要多大的内存空间7、每秒发起的支付请求对内存的…

9.3 Go语言入门(变量声明和函数调用)

Go语言入门(变量声明和函数调用) 目录二、变量声明和函数调用1. 变量声明1.1 使用 var 关键字声明1.2 简短声明1.3 零值1.4 常量 2. 函数调用2.1 函数定义2.2 多个返回值2.3 命名返回值2.4 可变参数2.5 匿名函数和闭包 目录 Go 语言(Golang&a…

按月爬取天气数据可视化展示

从天气网分析,可以查询每个月的天气情况,这里按照url规则,传入年月,获取数据,最后进行可视化展示,最终效果: 下面是获取过程: 第一步: import requestsdef get_weather(month):url = f"https://lishi.tianqi.com/nanning/{month}.html"response = reques…

最新:windows下安装pcl点云库

📚博客主页:knighthood2001 ✨公众号:认知up吧 (目前正在带领大家一起提升认知,感兴趣可以来围观一下) 🎃知识星球:【认知up吧|成长|副业】介绍 ❤️如遇文章付费,可先看…

日志的介绍及简单实现

个人主页:Lei宝啊 愿所有美好如期而遇 目录 日志是什么? 为什么需要日志? 实现一个简单日志 时间戳 clock_gettime time & localtime 可变模板参数(使用C语言),va_start & va_end & vsprintf 宏 __LINE__…