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

news2024/11/28 20:40:25

目录

  • 前期准备
  • 一、制作数据集
    • 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.len

	
if __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 = 5
    losses = []         """记录损失函数变化的列表"""
    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 = 0
    total = 0
    with torch.no_grad():                                #该局部关闭梯度计算功能
        for (x, y) in test_loader:                       #从批次加载器中获取小批次的x与y
            x, 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 = 0
    total = 0
    with torch.no_grad():                                #该局部关闭梯度计算功能
        for (x, y) in test_loader:                       #从批次加载器中获取小批次的x与y
            x, 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 = 5
    losses = []  # 记录损失函数变化的列表
    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)  # 一次前向传播(小批量)
            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 = 0
    total = 0
    with torch.no_grad():  						 	#该局部关闭梯度计算功能
        for (x, y) in test_loader: 				 	#获取小批次的 x 与 y
            x, 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.coloradmin.cn/o/1562394.html

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

相关文章

java数据结构与算法刷题-----LeetCode695. 岛屿的最大面积

java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846 文章目录 1. 深度优先遍历2. 广度优先 1. 深度优先遍历 这不是找最短路径&…

量化交易入门(三十八)CCI指标Python实现和回测

今天我们先单纯用CCI指标来完成策略的编写,后续我们会改进这个策略,将CCI指标和前面讲到的MACD和RSI相结合来优化,看看我们优化后的效果会不会更好。 一、量化策略 CCI指标在量化交易中的策略: 在以下情况下生成买入信号&#…

C# 排序的多种实现方式(经典)

一、 对数组进行排序 最常见的排序是对一个数组排序,比如: int[] aArray new int[8] { 18, 17, 21, 23, 11, 31, 27, 38 }; 1、利用冒泡排序进行排序: (即每个值都和它后面的数值比较,每次拿出最小值) s…

黄仁勋:我们有望在未来五到十年内见证完全由人工智能生成的游戏

黄仁勋:我们有望在未来五到十年内见证完全由人工智能生成的游戏 近日,英伟达(Nvidia)GPU技术大会上,英伟达首席执行官黄仁勋(Jensen Huang)对未来游戏产业的展望引发了业界的广泛关注。在一次与…

centos安装docker,docker安装centos进而安装宝塔

背景 由于工作需要自己有许多的web应用要部署在云服务器上。然而资金有限每年都要去阿里云,腾讯云,华为云买最便宜的服务器,这就意味着每年都要经历一次痛苦的环境安装项目部署的过程(nginx、mysql、elasticsearch、redis等等&am…

【Redis】Redis的类型及相关操作

一、常用的key操作命令 keys * 查看当前数据库的键值 ttl key 查看还有多少秒过期,-1表示永不过期,-2表示过期 del / unlink key 同样是删除,unlink是非阻塞删除,del则有可能导致阻塞 select dbindex 切换数据库 flushdb 清空…

CA根证书——https安全保障的基石

HTTPS通信中,服务器端使用数字证书来证明自己的身份。客户端需要验证服务器发送的证书的真实性。这就需要一个可信的第三方机构,即CA,来颁发和管理证书。CA根证书是证书颁发机构层次结构的顶级证书,客户端信任的所有证书都可以追溯…

并发编程之线程池的详细解析

线程池 线程池的优势: 线程池做的工作只要是控制运行的线程数量,处理过程中将任务放入队列,然后线程创建石后启动这些任务,如果线程数量超过了最大数量,超出数量的线程排队等候,等其他线程执行完毕&#xf…

【回眸】Tessy 单元测试软件使用指南(三)怎么打桩和指针赋值和测试

目录 前言 Tessy 如何进行打桩操作 普通桩 高级桩 手写桩 Tessy单元测试之指针相关测试注意事项 有类型的指针(非函数指针): 有类型的函数指针: void 类型的指针: 结语 前言 进行单元测试之后,但凡…

css-盒子阴影

1.box-shadow: 10px 20px 10px 10px blue; 参数对应顺序:上下,左右 ,模糊程度,颜色 ,阴影大小 2.box-shadow: 10px 20px 10px 20px blue,-10px -20px 10px 50px red; 负号就是相反方向 支持多个阴影 在后面加逗号 3…

dockerfile制作-pytoch+深度学习环境版

你好你好! 以下内容仅为当前认识,可能有不足之处,欢迎讨论! 文章目录 文档内容docker相关术语docker常用命令容器常用命令根据dockerfile创建容器dokerfile文件内容 docker问题:可能的原因和解决方法示例修改修改后的D…

谷粒商城——通过接口幂等性防止重复提交订单

如果用户向后端服务提交多次相同订单的提交服务,那么后端应该只生成一条订单记录。 有一些操作天然是幂等的,如查询操作和删除操作等。 幂等性实现 1.token机制(仅这个方法适用于订单的重复提交) 后端先生成1个令牌将其记录在R…

MATLAB绘制堆叠填充图--巧用句柄

MATLAB绘制堆叠填充图–巧用句柄 目录 MATLAB绘制堆叠填充图--巧用句柄1. 主要原理讲解1.1 主要函数1.2 句柄原理 2. 绘图示例2.1 准备数据2.2 绘制堆叠填充图-使用句柄控制图形属性2.3 设置填充颜色和样式2.4 添加标题和标签2.5 绘图效果 3. 结语 堆叠填充图是一种常见的数据可…

【2024年5月备考新增】《2024高项论文精华版(3)考试技巧》

3 考试技巧 3.1 考试难度 考试难度上,越是常见的题目、越是被大家预测的题目,阅卷就会更严格。 越是大家猜测不到的,越是小众的题目,阅卷严格程度就会低。 3.2 技巧 1、记住软考论文的目的,不是为了证明你的格式严谨…

中科驭数超低时延网络解决方案入选2023年度金融信创优秀解决方案

近日,由中国人民银行领导、中国金融电子化集团有限公司牵头组建的金融信创生态实验室发布「2023年度第三期金融信创优秀解决方案」,中科驭数超低时延网络解决方案从众多方案中脱颖而出,成功入选,代表了该方案的技术创新和金融实践…

使用plasmo开发浏览器插件在网页指定位置添加自定义UI

使用plasmo开发浏览器插件的时候,有时候需要在指定网站的指定页面添加自定义的UI内容,如果通过content.js内容脚本去通过js创建的话,可就太麻烦了,要写不少的js代码。不过plasmo已经帮我们实现了这个功能,就是Content …

安全防御产品—锐安盾重磅上线,助力更安全、更流畅的业务体验

在互联网时代,互联网技术蓬勃发展,然而,随之而来的网络安全问题也备受关注。诸如DDoS攻击、CC攻击、常见Web攻击等攻击手段突如其来,导致企业业务中断,严重影响企业业务正常运行。对此,锐成云重磅推出安全防…

分布式全闪占比剧增 152%,2023 年企业存储市场报告发布

近日,IDC 发布了 2023 年度的中国存储市场报告。根据该报告,在 2023 年软件定义存储的市场占比进一步扩大,分布式全闪的增长尤其亮眼,其市场份额从 2022 年的 7% 剧增到 2023 年的 17.7%,增长了 152%。 01 中国企业存…

提升LLM效果的几种简单方法

其实这个文章想写很久了,最近一直在做大模型相关的产品,经过和团队成员一段时间的摸索,对大模型知识库做一下相关的认知和总结。希望最终形成一个系列。 对于知识库问答,现在有两种方案,一种基于llamaindex&#xff0…

绝地求生:[更新周报] 4/3 不停机更新:无上新、众多物品和活动即将下架!

大家好,我闲游盒;本周三4月3号,绝地求生不会有停机时间,大家可以随便玩~ ▲本周可选地图池 亚服/东南亚服:艾伦格、荣都、萨诺、米拉玛、帕拉莫; 日服/韩服KAKAO服:艾伦格、泰戈、萨诺、荣都、…