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

目录

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

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

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

相关文章

蓝桥杯 - 穿越雷区

解题思路: dfs 方法一: import java.util.Scanner;public class Main {static char[][] a;static int[][] visited;static int[] dx { 0, 1, 0, -1 };static int[] dy { 1, 0, -1, 0 };static long min Long.MAX_VALUE;static long count 0;publi…

先进电气技术 —— (控制理论)何为稳定性?

一、系统稳定性 在控制理论中,系统稳定性是一个非常关键的概念,它主要涉及系统对外界扰动或内部变动的响应行为。以下是与系统稳定性相关的一些核心名词及其解释: 基本概念 稳定性(Stability) 系统稳定性是指当系统受…

Autosar工具链配置 CanNM

CAN网络管理filter 网管报文范围0x600~0x6FF repeat message time 超时时间 接收到主动唤醒源,网管报文快发周期,次数;正常周期发送时间 网管报文btye设置:1、重复消息请求位设置 2、ECU地址 wait bus-sleep 定时设置以及网管报…

蓝桥杯第十四届--子树的大小

题目描述 给定一棵包含 n 个结点的完全 m 叉树,结点按从根到叶、从左到右的顺序依次编号。 例如下图是一个拥有 11 个结点的完全 3 叉树。 你需要求出第 k 个结点对应的子树拥有的结点数量。 输入格式 输入包含多组询问。 输入的第一行包含一个整数 T &#xf…

telnet远程管理设备

实验目的:通过本机管理远端设备,模拟本地网卡和远端设备可以通信,配置telnet账户,远程管理设备,不用进入机房方式 拓扑图 云朵模拟本机的网卡,配置ar1的g0/0/0口IP后,确保在同一网络&#xff0…

【正点原子探索者STM32F4】TFTLCD实验学习记录

【正点原子探索者STM32】LCD实验学习记录 硬件硬件连接软件设计变量类型定义LCD参数结构体LCD地址结构体 函数定义读写命令和数据简介6个基本函数坐标设置函数画点函数读点函数字符显示函数LCD初始化 小结参考 硬件 STM32F407、4.3寸LCD屏 硬件连接 LCD_BL(背光控制)对应 PB1…

传输层 --- TCP (上篇)

目录 1. TCP 1.1. TCP协议段格式 1.2. TCP的两个问题 1.3. 如何理解可靠性 1.4. 理解确认应答机制 2. TCP 报头中字段的分析 2.1. 序号和确认序号 2.1.1. 序号和确认序号的初步认识 2.1.2. 如何正确理解序号和确认序号 2.2. TCP是如何做到全双工的 2.3. 16位窗口大小…

Redis Desktop Manager可视化工具

可视化工具 Redis https://www.alipan.com/s/uHSbg14XmsL 提取码: 38cl 点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看,视频原画倍速播放。 官网下载(不推荐):http…

【智能优化算法】IHAOAVOA(一种改进的混合天鹰优化算法(AO)和非洲秃鹫优化算法(AVOA))

发表在Mathematical Biosciences and Engineering的文章:IHAOAVOA: An improved hybrid aquila optimizer and African vultures optimization algorithm for global optimization problems.https://www.x-mol.com/paperRedirect/1572654041256222720 01.引言 天鹰…

Linux 安装系统可视化监控工具 Netdata

目录 About 监控工具 NetdataLinux 系统安装 Netdata关于 openEuler1、查看内核信息2、查看主机信息3、查看 dnf 包管理器的版本 Netdata 安装1、更新系统环境相关 rpm 包2、查看 netdata 包信息3、安装 netdata 包4、编辑 netdata.conf 配置5、启动 netdata 服务6、查看 netda…

页面静态化:Freemarker入门案例和常用指令教程

页面静态化其实就是将原来的动态网页(例如通过ajax请求动态获取数据库中的数据并展示的网页)改为通过静态化技术生成的静态网页,这样用户在访问网页时,服务器直接给用户响应静态html页面,没有了动态查询数据库的过程。 那么这些静态HTML页面…

TestNG Include and exclude

在这篇文章中,我们将详细讨论TestNG的包含和排除标签。下面是我们将在这篇文章中看到的要点- 包含和排除包第二,包括和排除测试方法最后,包括和排除组 我们只能将exclude标记与packages、methods和run标记(groups的子标记&#…

公园景区小红书抖音打造线上流量运营策划方案

【干货资料持续更新,以防走丢】 公园景区小红书抖音打造线上流量运营策划方案 部分资料预览 资料部分是网络整理,仅供学习参考。 共70页可编辑(完整资料包含以下内容) 目录 公园的线上运营方案: 一、运营目标 1. 品…

微电网优化:基于小龙虾优化算法COA的微电网优化(提供MATLAB代码)

一、微电网优化模型 微电网是一个相对独立的本地化电力单元,用户现场的分布式发电可以支持用电需求。为此,您的微电网将接入、监控、预测和控制您本地的分布式能源系统,同时强化供电系统的弹性,保障您的用电更经济。您可以在连接…

TCP三次握手过程及抓包分析

TCP三次握手过程 一、TCP分段格式二、TCP三次握手三、Wireshark抓包分析 一、TCP分段格式 二、TCP三次握手 三、Wireshark抓包分析

cmake中报错undefined reference to `pthread_create‘的解决方法

出现报错: 解决方法 一般网上会建议在终端指令g/gcc后面增加参数-pthread,但是我们没有用到g/gcc指令. cmake的解决方法是在CMakeLists.txt文件里面增加一行. add_executable(server2 main.cpp) target_link_libraries(server2 pthread)问题就解决了

[VulnHub靶机渗透] pWnOS 2.0

🍬 博主介绍👨‍🎓 博主介绍:大家好,我是 hacker-routing ,很高兴认识大家~ ✨主攻领域:【渗透领域】【应急响应】 【Java、PHP】 【VulnHub靶场复现】【面试分析】 🎉点赞➕评论➕收…

lora pingpang系统 4

1 深入了解LoRa技术原理 1.1 LoRa扩频通信原理 1.1.1 模拟无线通信: 模拟无线通信是一种使用模拟信号传输数据的通信方式。这种通信方式已经被数字无线通信所取代,因为数字通信具有更高的效率和可靠性。 天线:从空中接收到的无线电波转换成…

用友NC Cloud importhttpscer 任意文件上传漏洞复现

0x01 产品简介 用友 NC Cloud 是一种商业级的企业资源规划云平台,为企业提供全面的管理解决方案,包括财务管理、采购管理、销售管理、人力资源管理等功能,基于云原生架构,深度应用新一代数字技术,打造开放、 互联、融合、智能的一体化云平台,支持公有云、混合云、专属云…

ViewModel 使用及原理解析

public final MutableLiveData mUserLiveData new MutableLiveData<>(); public UserModel() { //模拟从网络加载用户信息 mUserLiveData.postValue(new User(1, “name1”)); } //模拟 进行一些数据骚操作 public void doSomething() { User user mUserLiveDat…