深度学习理论基础(三)封装数据集及手写数字识别

目录

  • 前期准备
  • 一、制作数据集
    • 1. excel表格数据
    • 2. 代码
  • 二、手写数字识别
    • 1. 下载数据集
    • 2. 搭建模型
    • 3. 训练网络
    • 4. 测试网络
    • 5. 保存训练模型
    • 6. 导入已经训练好的模型文件
    • 7. 完整代码

前期准备

必须使用 3 个 PyTorch 内置的实用工具(utils):
⚫ DataSet 用于封装数据集;
⚫ DataLoader 用于加载数据不同的批次;
⚫ random_split 用于划分训练集与测试集。
  

一、制作数据集

  在封装我们的数据集时,必须继承实用工具(utils)中的 DataSet 的类,这个过程需要重写__init__和__getitem__、__len__三个方法,分别是为了加载数据集、获取数据索引、获取数据总量。我们通过代码读取excel表格里面的数据作为数据集。

1. excel表格数据

在这里插入图片描述

2. 代码

为了简单演示,我们将表格的第0列作为输入特征,第1列作为输出特征。

import numpy as np
import pandas as pd
import torch
import torch.nn as nn
from torch.utils.data import Dataset
from torch.utils.data import DataLoader
from torch.utils.data import random_split
import matplotlib.pyplot as plt# 制作数据集
class MyData(Dataset):      """继承 Dataset 类"""def __init__(self, filepath):super().__init__()df = pd.read_excel(filepath).values       """ 读取excel数据"""arr = df.astype(np.int32)      """转为 int32 类型数组"""ts = torch.tensor(arr)      """数组转为张量"""ts = ts.to('cuda')      """把训练集搬到 cuda 上"""self.X = ts[:, :1]      """获取第0列的所有行做为输入特征"""self.Y = ts[:, 1:2]      """获取第1列的所有行为输出特征"""self.len = ts.shape[0]    """样本的总数"""  def __getitem__(self, index):return self.X[index], self.Y[index]def __len__(self):return self.lenif __name__ == '__main__':		"""获取数据集"""Data = MyData('label.xlsx')print(Data.X[0])       """输出为:tensor([1020741172], device='cuda:0', dtype=torch.int32)"""print(Data.Y[0])       """输出为:tensor([1], device='cuda:0', dtype=torch.int32) """print(Data.__len__())  """输出为:233 """"""划分训练集与测试集"""train_size = int(len(Data) * 0.7) # 训练集的样本数量test_size = len(Data) - train_size # 测试集的样本数量train_Data, test_Data = random_split(Data, [train_size, test_size])"""批次加载器"""""" 第一个参数:表示要加载的数据集,即之前划分好的 train_Data或test_Data 。"""""" 第二个参数:表示在每个 epoch(训练周期)开始之前是否重新洗牌数据。在训练过程中,通常会将数据进行洗牌,以确保模型能够学习到更加泛化的特征。而测试数据不需要重新洗牌,因为测试集仅用于评估模型的性能,不涉及模型参数的更新"""""" 第三个参数:表示每个批次中的样本数量为 32。也就是说,每次迭代加载器时,它会从训练数据集中加载128个样本。"""train_loader = DataLoader(train_Data, shuffle=True, batch_size=128)test_loader = DataLoader(test_Data, shuffle=False, batch_size=64)"""打印第一个批次的输入与输出特征"""for inputs, targets in train_loader:print(inputs)print(targets)

二、手写数字识别

1. 下载数据集

在下载数据集之前,要设定转换参数:transform,该参数里解决两个问题:
⚫ ToTensor:将图像数据转为张量,且调整三个维度的顺序为 (C-W-H);C表示通道数,二维灰度图像的通道数为 1,三维 RGB 彩图的通道数为 3。
⚫ Normalize:将神经网络的输入数据转化为标准正态分布,训练更好;根据统计计算,MNIST 训练集所有像素的均值是 0.1307、标准差是 0.3081

"""数据转换为tensor数据"""
transform_data = transforms.Compose([transforms.ToTensor(),transforms.Normalize(0.1307, 0.3081)
])"""下载训练集与测试集"""
train_Data = datasets.MNIST(root = 'E:/Desktop/Document/4. Python/例程代码/dataset/mnist/', """下载路径"""train = True, """训练集"""download = True,  """如果该路径没有该数据集,就下载"""transform = transform_data """数据集转换参数"""
)
test_Data = datasets.MNIST(root = 'E:/Desktop/Document/4. Python/例程代码/dataset/mnist_test/', """下载路径"""train = False, """非训练集,也就是测试集"""download = True, """如果该路径没有该数据集,就下载"""transform = transform_data """数据集转换参数"""
)"""批次加载器"""
train_loader = DataLoader(train_Data, shuffle=True, batch_size=64)
test_loader = DataLoader(test_Data, shuffle=False, batch_size=64)

在这里插入图片描述

2. 搭建模型

class DNN(nn.Module):def __init__(self):''' 搭建神经网络各层 '''super(DNN,self).__init__()self.net = nn.Sequential( # 按顺序搭建各层nn.Flatten(), # 把图像铺平成一维nn.Linear(784, 512), nn.ReLU(), # 第 1 层:全连接层nn.Linear(512, 256), nn.ReLU(), # 第 2 层:全连接层nn.Linear(256, 128), nn.ReLU(), # 第 3 层:全连接层nn.Linear(128, 64), nn.ReLU(), # 第 4 层:全连接层nn.Linear(64, 10) # 第 5 层:全连接层)def forward(self, x):''' 前向传播 '''y = self.net(x) # x 即输入数据return y # y 即输出数据

3. 训练网络

"""实例化模型"""
model = DNN().to('cuda:0') def train_net():"""1.损失函数的选择"""loss_fn = nn.CrossEntropyLoss()  # 自带 softmax 激活函数"""2.优化算法的选择"""learning_rate = 0.01              # 设置学习率optimizer = torch.optim.SGD(model.parameters(),lr=learning_rate,momentum=0.5                 # momentum(动量),它使梯度下降算法有了力与惯性)"""3.训练"""epochs = 5losses = []         """记录损失函数变化的列表"""for epoch in range(epochs):for (x, y) in train_loader:     """从批次加载器中获取小批次的x与y"""x, y = x.to('cuda:0'), y.to('cuda:0')Pred = model(x)               #将样本放入实例化的模型中,这里自动调用forward方法。loss = loss_fn(Pred, y)       # 计算损失函数losses.append(loss.item())    # 记录损失函数的变化optimizer.zero_grad()         # 清理上一轮滞留的梯度loss.backward()               # 一次反向传播optimizer.step()              # 优化内部参数"""4.画损失图"""Fig = plt.figure()plt.plot(range(len(losses)), losses)plt.show()

损失图如下:
在这里插入图片描述

4. 测试网络

测试网络不需要回传梯度。

"""实例化模型"""
model = DNN().to('cuda:0') def test_net():correct = 0total = 0with torch.no_grad():                                #该局部关闭梯度计算功能for (x, y) in test_loader:                       #从批次加载器中获取小批次的x与yx, y = x.to('cuda:0'), y.to('cuda:0')Pred = model (x)                             #将样本放入实例化的模型中,这里自动调用forward方法。_, predicted = torch.max(Pred.data, dim=1)correct += torch.sum((predicted == y))total += y.size(0)print(f'测试集精准度: {100 * correct / total} %')

在这里插入图片描述

5. 保存训练模型

在保存模型前,必须要先进行训练网络去获取和优化模型参数。

if __name__ == '__main__':model = DNN().to('cuda:0') train_net()torch.save(model,'old_model.pth')

6. 导入已经训练好的模型文件

导入训练好的模型文件,我们就不需要再进行训练网络,直接使用测试网络来测试即可。
new_model使用了原有模型文件,我们就需要在测试网络的前向传播中的模型修改为 new_model去进行测试。如下:

"""  假设我们之前保存好的模型文件为:'old_model.pth'  """def test_net():correct = 0total = 0with torch.no_grad():                                #该局部关闭梯度计算功能for (x, y) in test_loader:                       #从批次加载器中获取小批次的x与yx, y = x.to('cuda:0'), y.to('cuda:0')Pred = new_model (x)                         #将样本放入实例化的模型中,这里自动调用forward方法。_, predicted = torch.max(Pred.data, dim=1)correct += torch.sum((predicted == y))total += y.size(0)print(f'测试集精准度: {100 * correct / total} %')if __name__ == '__main__':new_model = torch.load('old_model.pth')test_net()

7. 完整代码

import torch
import torch.nn as nn
from torch.utils.data import DataLoader
from torchvision import transforms
from torchvision import datasets
import matplotlib.pyplot as plt"""------------1.下载数据集----------"""
"""数据转换为tensor数据"""
transform_data = transforms.Compose([transforms.ToTensor(),transforms.Normalize(0.1307, 0.3081)
])"""下载训练集与测试集"""
train_Data = datasets.MNIST(root = 'E:/Desktop/Document/4. Python/例程代码/dataset/mnist/', """下载路径"""train = True, """训练集"""download = True,  """如果该路径没有该数据集,就下载"""transform = transform_data """数据集转换参数"""
)
test_Data = datasets.MNIST(root = 'E:/Desktop/Document/4. Python/例程代码/dataset/mnist_test/', """下载路径"""train = False, """非训练集,也就是测试集"""download = True, """如果该路径没有该数据集,就下载"""transform = transform_data """数据集转换参数"""
)"""批次加载器"""
train_loader = DataLoader(train_Data, shuffle=True, batch_size=64)
test_loader = DataLoader(test_Data, shuffle=False, batch_size=64)"""---------------2.定义模型------------"""
class DNN(nn.Module):def __init__(self):''' 搭建神经网络各层 '''super(DNN,self).__init__()self.net = nn.Sequential( # 按顺序搭建各层nn.Flatten(), # 把图像铺平成一维nn.Linear(784, 512), nn.ReLU(), # 第 1 层:全连接层nn.Linear(512, 256), nn.ReLU(), # 第 2 层:全连接层nn.Linear(256, 128), nn.ReLU(), # 第 3 层:全连接层nn.Linear(128, 64), nn.ReLU(), # 第 4 层:全连接层nn.Linear(64, 10) # 第 5 层:全连接层)def forward(self, x):''' 前向传播 '''y = self.net(x) # x 即输入数据return y # y 即输出数据"""-------------3.训练网络-----------"""
def train_net():# 损失函数的选择loss_fn = nn.CrossEntropyLoss()  # 自带 softmax 激活函数# 优化算法的选择learning_rate = 0.01  # 设置学习率optimizer = torch.optim.SGD(model.parameters(),lr=learning_rate,momentum=0.5)epochs = 5losses = []  # 记录损失函数变化的列表for epoch in range(epochs):for (x, y) in train_loader:  # 获取小批次的 x 与 yx, y = x.to('cuda:0'), y.to('cuda:0')Pred = model(x)  # 一次前向传播(小批量)loss = loss_fn(Pred, y)  # 计算损失函数losses.append(loss.item())  # 记录损失函数的变化optimizer.zero_grad()  # 清理上一轮滞留的梯度loss.backward()  # 一次反向传播optimizer.step()  # 优化内部参数"""Fig = plt.figure()""""""plt.plot(range(len(losses)), losses)""""""plt.show()""""""--------------------4.测试网络-----------"""
def test_net():correct = 0total = 0with torch.no_grad():  						 	#该局部关闭梯度计算功能for (x, y) in test_loader: 				 	#获取小批次的 x 与 yx, y = x.to('cuda:0'), y.to('cuda:0')Pred = new_model(x)  				 	#一次前向传播(小批量)_, predicted = torch.max(Pred.data, dim=1)correct += torch.sum((predicted == y))total += y.size(0)print(f'测试集精准度: {100 * correct / total} %')if __name__ == '__main__':""" ------- 5.保存模型文件------""""""   model = DNN().to('cuda:0')        """"""   train_net()                       """"""   torch.save(model,'old_model.pth') """""" ------- 6.加载模型文件 ----- """new_model = torch.load('old_model.pth')test_net()

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

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

相关文章

TXT文本高效编辑神器,教你进行隔行删除不需要的内容,轻松整理文本内容。

在信息爆炸的时代,我们每天都会接触到大量的文本信息,无论是工作中的报告、邮件,还是生活中的读书笔记、备忘录,都需要我们对文本进行高效的管理和编辑。然而,传统的文本编辑方式往往繁琐低效,无法满足我们…

PTA L2-048 寻宝图

给定一幅地图,其中有水域,有陆地。被水域完全环绕的陆地是岛屿。有些岛屿上埋藏有宝藏,这些有宝藏的点也被标记出来了。本题就请你统计一下,给定的地图上一共有多少岛屿,其中有多少是有宝藏的岛屿。 输入格式&#xf…

LeetCode练习题--567.字符串的排列

今天讲一个非常经典的滑动窗口的问题 这道题的意思很明显: 给你两个字符串s1与s2,判断s2中是否存在一个子串:它包含s1中所有字符且不包含其他字符 让我们先来写一下滑动窗口的模板: /*** 滑动窗口模板 * param s1 * param s2 */public static void model (String s1, String s2…

51单片机入门:认识开发板

认识开发板 板载资源: 数码管模块 说明: 2个四位一体共阴数码管 详细: 2个四位一体:两个独立的四位数码管,每个四位数码管都是“一体”的设计,也就是说,每个数码管内部集成了四个独立的七段LE…

HTTPS跟HTTP有区别吗?

HTTPS和HTTP的区别,白话一点说就是: 1. 安全程度: - HTTP:就像是你和朋友面对面聊天,说的话大家都能听见(信息明文传输,容易被偷听)。 - HTTPS:就像是你们俩戴着加密耳机…

论大数据服务化发展史

引言 一直想写一篇服务化相关的文章,那就别犹豫了现在就开始吧 正文 作为大数据基础架构工程师,业界也笑称“运维Boy”,日常工作就是在各个机器上部署以及维护服务,例如部署Hadoop、Kafka、Pulsar这些等等,用于给公…

InternLM2-lesson2笔记

书生浦语大模型趣味 Demo 视频连接:https://www.bilibili.com/video/BV1AH4y1H78d/?vd_source902e3124d4683c41b103f1d1322401fa 目录 书生浦语大模型趣味 Demo课程总览SIG项目Demo部署的一般流程存在的问题总结 课程总览 InternLM2-chat-1.8B部署八戒-chat-1.8B…

【css】文本过长溢出一行不换行普通css以及antd实现

.text-box { white-space: nowrap; /* 防止文字换行 */ overflow: hidden; /* 隐藏超出div的内容 */ text-overflow: ellipsis; /* 当内容超出时,显示省略号 */ max-width: calc(100% - 80px); /* 假设按钮宽度为80px,则设置div的最大宽度为容器宽度…

Mysql索引总结(1)

文章目录 InnoDB索引与MyISAM索引实现的区别是什么?一个表中如果没有创建索引,那么还会创建B树吗?B树索引实现原理(数据结构) InnoDB索引与MyISAM索引实现的区别是什么? MyISAM的索引方式都是非聚簇的&…

07-app端文章搜索

app端文章搜索 1) 今日内容介绍 1.1)App端搜索-效果图 1.2)今日内容 文章搜索 ElasticSearch环境搭建 索引库创建 文章搜索多条件复合查询 索引数据同步 搜索历史记录 Mongodb环境搭建 异步保存搜索历史 查看搜索历史列表 删除搜索历史 联想词查询 联想词的来源 联…

elasticSearch原理浅尝

终于等到你 马上就要放弃 开个玩笑 ,进入正题 on fire 基础的咱不说了,一搜一麻袋 读 全文检索: 协调节点广播查询请求到相关分片 并 将其响应 整合 全局排序 返回结果集合 带路由:具体文档 shard hash(document_id) % (…

redis进阶入门主从复制与哨兵集群

一、主从复制 1.1背景 一般来说,要将 Redis用于工程项目中,只使用一台 Redist是万万不能的,原因如下: 从结构上,单个 Redist服务器会发生单点故障,井且一台服务器需要处理所有的请求负載,压力…

HTML基础知识详解(上)(如何想知道html的全部基础知识点,那么只看这一篇就足够了!)

前言:在学习前端基础时,必不可少的就是三大件(html、css、javascript ),而HTML(超文本标记语言——HyperText Markup Language)是构成 Web 世界的一砖一瓦,它定义了网页内容的含义和…

物联网实战--驱动篇之(一)EEPROM存储器(AT24C64)

目录 一、驱动概述 二、AT24C64简介 三、驱动编写 四、驱动应用 一、驱动概述 这是驱动篇的第一篇,所以先说明下驱动篇的作用和书写计划。之前的净化器项目已有提及,向ESP8266、SHT30这些都属于驱动设备,主芯片STM32是核心,相…

redis 数据库的安装及使用方法

目录 一 关系数据库与非关系型数据库 (一)关系型数据库 1,关系型数据库是什么 2,主流的关系型数据库有哪些 3,关系型数据库注意事项 (二)非关系型数据库 1,非关系型数据库是…

day04-MQ

1.初识MQ 1.1.同步和异步通讯 微服务间通讯有同步和异步两种方式: 同步通讯:就像打电话,需要实时响应。异步通讯:就像发邮件,不需要马上回复。 两种方式各有优劣,打电话可以立即得到响应,但是你…

LeNet卷积神经网络

文章目录 简介conv2d网络层的结构 简介 它是最早发布的卷积神经网络之一 conv2d 这个卷积成的参数先进行介绍一下: self.conv1 nn.Conv2d(in_channels3, out_channels10, kernel_size3, stride1, padding1)先看一下in_channels 输入的通道数,out_cha…

Redis从入门到精通(五)Redis实战(二)商户查询缓存

↑↑↑请在文章头部下载测试项目原代码↑↑↑ 文章目录 前言4.2 商户查询缓存4.2.1 缓存介绍4.2.2 查询商户信息的传统做法4.2.2.1 接口文档4.2.2.2 代码实现4.2.2.3 功能测试 4.2.3 查询商户信息添加Redis缓存4.2.3.1 逻辑分析4.2.3.2 代码实现4.2.3.3 功能测试 4.2.3 数据一致…

接口的总结与面试题

接口本身不能创建对象,只能创建接口的实现类对象,接口类型的变量可以与实现类对象构成多态引用。 声明接口用interface,接口的成员声明有限制: (1)公共的静态常量 (2)公共的抽象方…

Python网络爬虫(四):b站评论

首先来看一下采集的数据格式: 本文不对数据采集的过程做探讨,直接上代码。首先要在程序入口处bvids列表内替换成自己想要采集的视频bvid号,然后将self.cookies替换成自己的(需要字典格式),代码可以同时爬取多个视频的评论,且爬取的评论较为完整,亲测有效: im…