【深度学习】Pytorch 教程(十五):PyTorch数据结构:7、模块(Module)详解(自定义神经网络模型并训练、评估)

文章目录

  • 一、前言
  • 二、实验环境
  • 三、PyTorch数据结构
    • 1、Tensor(张量)
      • 1. 维度(Dimensions)
      • 2. 数据类型(Data Types)
      • 3. GPU加速(GPU Acceleration)
    • 2、张量的数学运算
      • 1. 向量运算
      • 2. 矩阵运算
      • 3. 向量范数、矩阵范数、与谱半径详解
      • 4. 一维卷积运算
      • 5. 二维卷积运算
      • 6. 高维张量
    • 3、张量的统计计算
    • 4、张量操作
      • 1. 张量变形
      • 2. 索引
      • 3. 切片
      • 4. 张量修改
    • 5、张量的梯度计算
    • 6、数据集(Dataset)与数据加载器(DataLoader)
    • 7、模块(Module)
      • 1. 自定义神经网络模型
      • 2. Module类功能简介
      • 3. 训练模型
      • 4. 评估模型
      • 5. 代码整合

一、前言

  PyTorch的Module模块是定义神经网络模型的基类,提供了方便的方式来定义模型的结构和行为。通过继承Module类,可以轻松地定义自定义的神经网络模型,并在其中实现初始化方法、前向传播方法等。Module类还提供了模型保存和加载、自动求导等功能,使得模型的训练和使用变得更加便利。

二、实验环境

  本系列实验使用如下环境

conda create -n DL python==3.11
conda activate DL
conda install pytorch torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c nvidia

三、PyTorch数据结构

1、Tensor(张量)

  Tensor(张量)是PyTorch中用于表示多维数据的主要数据结构,类似于多维数组,可以存储和操作数字数据。

1. 维度(Dimensions)

  Tensor(张量)的维度(Dimensions)是指张量的轴数或阶数。在PyTorch中,可以使用size()方法获取张量的维度信息,使用dim()方法获取张量的轴数。

在这里插入图片描述

2. 数据类型(Data Types)

  PyTorch中的张量可以具有不同的数据类型:

  • torch.float32或torch.float:32位浮点数张量。
  • torch.float64或torch.double:64位浮点数张量。
  • torch.float16或torch.half:16位浮点数张量。
  • torch.int8:8位整数张量。
  • torch.int16或torch.short:16位整数张量。
  • torch.int32或torch.int:32位整数张量。
  • torch.int64或torch.long:64位整数张量。
  • torch.bool:布尔张量,存储True或False。

【深度学习】Pytorch 系列教程(一):PyTorch数据结构:1、Tensor(张量)及其维度(Dimensions)、数据类型(Data Types)

3. GPU加速(GPU Acceleration)

【深度学习】Pytorch 系列教程(二):PyTorch数据结构:1、Tensor(张量): GPU加速(GPU Acceleration)

2、张量的数学运算

  PyTorch提供了丰富的操作函数,用于对Tensor进行各种操作,如数学运算、统计计算、张量变形、索引和切片等。这些操作函数能够高效地利用GPU进行并行计算,加速模型训练过程。

1. 向量运算

【深度学习】Pytorch 系列教程(三):PyTorch数据结构:2、张量的数学运算(1):向量运算(加减乘除、数乘、内积、外积、范数、广播机制)

2. 矩阵运算

【深度学习】Pytorch 系列教程(四):PyTorch数据结构:2、张量的数学运算(2):矩阵运算及其数学原理(基础运算、转置、行列式、迹、伴随矩阵、逆、特征值和特征向量)

3. 向量范数、矩阵范数、与谱半径详解

【深度学习】Pytorch 系列教程(五):PyTorch数据结构:2、张量的数学运算(3):向量范数(0、1、2、p、无穷)、矩阵范数(弗罗贝尼乌斯、列和、行和、谱范数、核范数)与谱半径详解

4. 一维卷积运算

【深度学习】Pytorch 系列教程(六):PyTorch数据结构:2、张量的数学运算(4):一维卷积及其数学原理(步长stride、零填充pad;宽卷积、窄卷积、等宽卷积;卷积运算与互相关运算)

5. 二维卷积运算

【深度学习】Pytorch 系列教程(七):PyTorch数据结构:2、张量的数学运算(5):二维卷积及其数学原理

6. 高维张量

【深度学习】pytorch教程(八):PyTorch数据结构:2、张量的数学运算(6):高维张量:乘法、卷积(conv2d~ 四维张量;conv3d~五维张量)

3、张量的统计计算

【深度学习】Pytorch教程(九):PyTorch数据结构:3、张量的统计计算详解

4、张量操作

1. 张量变形

【深度学习】Pytorch教程(十):PyTorch数据结构:4、张量操作(1):张量变形操作

2. 索引

3. 切片

【深度学习】Pytorch 教程(十一):PyTorch数据结构:4、张量操作(2):索引和切片操作

4. 张量修改

【深度学习】Pytorch 教程(十二):PyTorch数据结构:4、张量操作(3):张量修改操作(拆分、拓展、修改)

5、张量的梯度计算

【深度学习】Pytorch教程(十三):PyTorch数据结构:5、张量的梯度计算:变量(Variable)、自动微分、计算图及其可视化

6、数据集(Dataset)与数据加载器(DataLoader)

【深度学习】Pytorch 教程(十四):PyTorch数据结构:6、数据集(Dataset)与数据加载器(DataLoader):自定义鸢尾花数据类

import torch
from sklearn.datasets import load_iris
from torch.utils.data import Dataset, DataLoader
 
# 此函数用于加载鸢尾花数据集
def load_data(shuffle=True):
    x = torch.tensor(load_iris().data)
    y = torch.tensor(load_iris().target)
 
    # 数据归一化
    x_min = torch.min(x, dim=0).values
    x_max = torch.max(x, dim=0).values
    x = (x - x_min) / (x_max - x_min)
 
    if shuffle:
        idx = torch.randperm(x.shape[0])
        x = x[idx]
        y = y[idx]
    return x, y
 
# 自定义鸢尾花数据类
class IrisDataset(Dataset):
    def __init__(self, mode='train', num_train=120, num_dev=15):
        super(IrisDataset, self).__init__()
        x, y = load_data(shuffle=True)
        if mode == 'train':
            self.x, self.y = x[:num_train], y[:num_train]
        elif mode == 'dev':
            self.x, self.y = x[num_train:num_train + num_dev], y[num_train:num_train + num_dev]
        else:
            self.x, self.y = x[num_train + num_dev:], y[num_train + num_dev:]
 
    def __getitem__(self, idx):
        return self.x[idx], self.y[idx]
 
    def __len__(self):
        return len(self.x)
 
batch_size = 16
 
# 分别构建训练集、验证集和测试集
train_dataset = IrisDataset(mode='train')
dev_dataset = IrisDataset(mode='dev')
test_dataset = IrisDataset(mode='test')
 
train_loader = DataLoader(train_dataset, batch_size=batch_size,shuffle=True)
dev_loader = DataLoader(dev_dataset, batch_size=batch_size)
test_loader = DataLoader(test_dataset, batch_size=1, shuffle=True)

7、模块(Module)

  PyTorch的Module模块是构建神经网络模型的基本组件之一。Module模块提供了一种方便的方式来定义神经网络模型的结构,并且可以方便地进行参数的管理和训练。

1. 自定义神经网络模型

  Module模块是所有神经网络模型的基类,它包含了一些方法和属性,用来定义神经网络的结构和行为。通过继承Module类,可以轻松地自定义一个神经网络模型,其中至少要包含下面两个方法:

  1. __init__()方法:用于初始化网络模型的结构,可以在这个方法中定义网络的层和参数。
    • 这个方法通常会调用父类的__init__()方法来初始化模型的参数。
  2. forward()方法:定义了模型的前向传播过程,即给定输入数据,通过网络模型计算出输出。
    • 这是Module模块中必须要实现的方法,它定义了整个神经网络模型的计算过程。
class IrisModel(nn.Module):
    def __init__(self):
        super(IrisModel, self).__init__()
        self.fc = nn.Linear(4, 3)

    def forward(self, x):
        return self.fc(x)

2. Module类功能简介

  • 自动求导:Module类内部的操作默认支持自动求导。在前向传播过程中,PyTorch会自动构建计算图,并记录每个操作的梯度计算方式。这样,在反向传播过程中,可以自动计算和更新模型的参数梯度。
  • parameters()方法:返回模型中定义的所有可学习的参数,可以用于在训练过程中更新参数。
  • modules()方法:返回模型中定义的所有子模块,可以用于递归地遍历和访问模型的所有组件。
    • Module类自动跟踪和管理模型中的可学习参数。
  • 模型保存和加载:可以使用torch.save()方法将整个模型保存到文件中,以便在以后重新加载和使用。加载模型时,可以使用torch.load()方法加载保存的模型参数。
  • 将模型移动到指定的设备(如CPU或GPU)
    • 通过传入一个torch.device对象或一个字符串来指定目标设备,模型的所有参数和缓冲区都将被移动到目标设备。
    • 例如,使用model.to("cuda")将模型移动到GPU设备上。
  • 切换模型的训练和评估模式
    • train()eval()方法

3. 训练模型

# 实例化神经网络模型
model = IrisModel()

# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)

# 训练模型
num_epochs = 20
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)

for epoch in range(num_epochs):
    model.train()
    total_loss = 0

    for batch_x, batch_y in train_loader:
        batch_x, batch_y = batch_x.to(device), batch_y.to(device)
        batch_x = batch_x.to(torch.float)  # 使用float32数据类型
        # RuntimeError: mat1 and mat2 must have the same dtype, but got Double and Float
        optimizer.zero_grad()
        output = model(batch_x)
        loss = criterion(output, batch_y)
        loss.backward()
        optimizer.step()
        total_loss += loss.item()

    avg_loss = total_loss / len(train_loader)
    print(f"Epoch [{epoch + 1}/{num_epochs}], Train Loss: {avg_loss}")

# 保存模型
torch.save(model.state_dict(), 'iris_model.pth')

4. 评估模型

# 加载模型
model = IrisModel()  # 先实例化一个模型
model.to(device)
model.load_state_dict(torch.load('iris_model.pth'))
model.eval()  # 加载后的模型需要调用eval()方法

# 评估模型
model.eval()
total_correct = 0
total_samples = 0

with torch.no_grad():
    for batch_x, batch_y in test_loader:
        batch_x, batch_y = batch_x.to(device), batch_y.to(device)
        batch_x = batch_x.to(torch.float)  # 使用float32数据类型
        output = model(batch_x)
        _, predicted = torch.max(output, dim=1)
        total_correct += (predicted == batch_y).sum().item()
        total_samples += batch_y.size(0)

accuracy = total_correct / total_samples
print(f"Test Accuracy: {accuracy}")

5. 代码整合

import torch
import torch.nn as nn
from sklearn.datasets import load_iris
from torch.utils.data import Dataset, DataLoader


# 此函数用于加载鸢尾花数据集
def load_data(shuffle=True):
    x = torch.tensor(load_iris().data)
    y = torch.tensor(load_iris().target)

    # 数据归一化
    x_min = torch.min(x, dim=0).values
    x_max = torch.max(x, dim=0).values
    x = (x - x_min) / (x_max - x_min)

    if shuffle:
        idx = torch.randperm(x.shape[0])
        x = x[idx]
        y = y[idx]
    return x, y


# 自定义鸢尾花数据类
class IrisDataset(Dataset):
    def __init__(self, mode='train', num_train=120, num_dev=15):
        super(IrisDataset, self).__init__()
        x, y = load_data(shuffle=True)  # 将x转换为浮点型数据
        y = y.long()  # 将y转换为长整型数据
        # x, y = load_data(shuffle=True)
        if mode == 'train':
            self.x, self.y = x[:num_train], y[:num_train]
        elif mode == 'dev':
            self.x, self.y = x[num_train:num_train + num_dev], y[num_train:num_train + num_dev]
        else:
            self.x, self.y = x[num_train + num_dev:], y[num_train + num_dev:]

    def __getitem__(self, idx):
        return self.x[idx], self.y[idx]

    def __len__(self):
        return len(self.x)


# 创建一个模型类来定义神经网络模型
class IrisModel(nn.Module):
    def __init__(self):
        super(IrisModel, self).__init__()
        self.fc = nn.Linear(4, 3)

    def forward(self, x):
        return self.fc(x)


# 加载数据
batch_size = 16

train_dataset = IrisDataset(mode='train')
dev_dataset = IrisDataset(mode='dev')
test_dataset = IrisDataset(mode='test')

train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
dev_loader = DataLoader(dev_dataset, batch_size=batch_size)
test_loader = DataLoader(test_dataset, batch_size=1, shuffle=True)

# 实例化神经网络模型
model = IrisModel()

# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)

# 训练模型
num_epochs = 20
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)

for epoch in range(num_epochs):
    model.train()
    total_loss = 0

    for batch_x, batch_y in train_loader:
        batch_x, batch_y = batch_x.to(device), batch_y.to(device)
        batch_x = batch_x.to(torch.float)  # 使用float32数据类型
        # RuntimeError: mat1 and mat2 must have the same dtype, but got Double and Float
        optimizer.zero_grad()
        output = model(batch_x)
        loss = criterion(output, batch_y)
        loss.backward()
        optimizer.step()
        total_loss += loss.item()

    avg_loss = total_loss / len(train_loader)
    print(f"Epoch [{epoch + 1}/{num_epochs}], Train Loss: {avg_loss}")

# 保存模型
torch.save(model.state_dict(), 'iris_model.pth')

#%%
# 加载模型
model = IrisModel()  # 先实例化一个模型
model.to(device)
model.load_state_dict(torch.load('iris_model.pth'))
model.eval()  # 加载后的模型需要调用eval()方法

# 评估模型
model.eval()
total_correct = 0
total_samples = 0

with torch.no_grad():
    for batch_x, batch_y in test_loader:
        batch_x, batch_y = batch_x.to(device), batch_y.to(device)
        batch_x = batch_x.to(torch.float)  # 使用float32数据类型
        output = model(batch_x)
        _, predicted = torch.max(output, dim=1)
        total_correct += (predicted == batch_y).sum().item()
        total_samples += batch_y.size(0)

accuracy = total_correct / total_samples
print(f"Test Accuracy: {accuracy}")

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

《2023跨境电商投诉大数据报告》发布|亚马逊 天猫国际 考拉海购 敦煌网 阿里巴巴

2023年,跨境电商API接口天猫国际、京东国际和抖音全球购以其强大的品牌影响力和市场占有率,稳坐行业前三的位置。同时,各大跨境电商平台消费纠纷问题层出不穷。依据国内知名网络消费纠纷调解平台“电诉宝”(315.100EC.CN&#xff…

C++设计模式_创建型模式_工厂方法模式

目录 C设计模式_创建型模式_工厂方法模式 一、简单工厂模式 1.1 简单工厂模式引入 1.2 简单工厂模式 1.3 简单工厂模式利弊分析 1.4 简单工厂模式的UML图 二、工厂方法模式 2.1 工厂模式和简单工厂模式比较 2.2 工厂模式代码实现 2.3 工厂模式UML 三、抽象工厂模式 3.1 战斗场景…

C语言可以干些什么?C语言主要涉及哪些IT领域?

C语言可以干些什么?C语言主要涉及哪些IT领域? 在开始前我有一些资料,是我根据网友给的问题精心整理了一份「C语言的资料从专业入门到高级教程」, 点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给大家…

LangChain---大型语言模型(LLM)的标准接口和编程框架

1.背景说明 公司在新的一年规划中突然提出要搞生成式AI(GenAI)的相关东西,在公司分享的参考资料中了解到了一些相关的信息,之所以想到使用LangChain,是因为在应用中遇到了瓶颈问题,除了已经了解和研究过的OpenAI的ChatGpt&#xf…

分层解耦-三层架构(未完)

controller层——》service——》dao——》service——》controller 控制反转 依赖注入

阿里巴巴找黄金宝箱(I)【华为OD机试-JAVAPythonC++JS】

题目描述 一贫如洗的樵夫阿里巴巴在去砍柴的路上,无意中发现了强盗集团的藏宝地,藏宝地有编号从0~N的箱子,每个箱子上面贴有一个数字,箱子中可能有一个黄金宝箱。 黄金宝箱满足排在它之前的所有箱子数字和等于排在它之后的所有箱子…

Android 性能优化--APK加固(1)混淆

文章目录 为什么要开启混淆如何开启代码混淆如何开启资源压缩代码混淆配置代码混淆后,Crash 问题定位结尾 本文首发地址:https://h89.cn/archives/211.html 最新更新地址:https://gitee.com/chenjim/chenjimblog 为什么要开启混淆 先上一个 …

“智农”-高标准农田

高标准农田是指通过土地整治、土壤改良、水利设施、农电配套、机械化作业等措施,提升农田质量和生产能力,达到田块平整、集中连片、设施完善、节水高效、宜机作业、土壤肥沃、生态友好、抗灾能力强、与现代农业生产和经营方式相适应的旱涝保收、稳产高产…

BUUCTF---wireshark1

1.题目描述 2.下载附件是一个.pcap的文件 3.需要用到wireshark工具,用该工具打开文件 4.用户在登录密码时一般不会用get方式提交,因为这样不安全,相比较而言post安全一点。 5.使用http.request.methodPOST命令进行过滤,得到一条流…

道路千万条,安全第一条,如何让机器人更安全?

停的住,停的稳,该避就避,该停就停。 商用机器人实现落地的前提有很多,但安全问题毫无疑问是重中之重。尤其随着机器人的应用场景开始向复杂化、小型化方向拓展,对机器人的安全能力要求更是与日俱增。如何保证机器人在…

供水管网水力模型的建立与应用

阐述管网水力模型构建流程,建立供水管网水力模型。通过数据录入生成管网基本拓扑结构及物理信息,在模型简化之后利用监测数据进行模型校核,保障管网模型满足精度要求。利用管网模型进行管网工况分析,掌握管网内压力分布与管道流速分布状态,提出管网运行薄弱环节。 给…

测试环境搭建整套大数据系统(七:集群搭建kafka(2.13)+flink(1.13.6)+dinky(0.6)+iceberg)

一:搭建kafka。 1. 三台机器执行以下命令。 cd /opt wget wget https://dlcdn.apache.org/kafka/3.6.1/kafka_2.13-3.6.1.tgz tar zxvf kafka_2.13-3.6.1.tgz cd kafka_2.13-3.6.1/config vim server.properties修改以下俩内容 1.三台机器分别给予各自的broker_id…

C++设计模式之——享元模式详解和代码案例

文章目录 C中实现享元模式通常涉及以下几个关键部分:一个简单的C代码片段示例享元模式的进一步说明C享元模式代码案例——咖啡店订单系统享元模式在现实世界的应用场景 C中实现享元模式通常涉及以下几个关键部分: 享元模式(Flyweight Patter…

【Java设计模式】二、单例模式

文章目录 0、单例模式1、饿汉式2、懒汉式3、双重检查4、静态内部类5、枚举6、单例模式的破坏:序列化和反序列化7、单例模式的破坏:反射8、单例模式的实际应用 设计模式即总结出来的一些最佳实现。GoF(四人组) 书中提到23种设计模式,可分为三大…

linux c++ 开发 tensorrt 安装

tensorrt 官方下载地址(需要注册账号登录):Log in | NVIDIA Developer 根据系统发行版和CUDA版本 (nvcc -V) 选择合适的安装包 EA(early access)版本代表抢先体验。 GA(general availability)代…

文件对比工具Beyond Compare 4 mac v4.4.7(28397)中文版

Beyond Compare是一款适用于Windows、Mac OS X和Linux平台的文件和文件夹比较工具。它可以帮助用户比较和同步文件夹、文件和压缩包等内容,支持多种文件格式,如文本、图像、音频、视频等。 软件下载:Beyond Compare 4 mac v4.4.7(28397)中文版…

如何在Node.js中使用定时器

在Node.js中使用定时器是一项常见且重要的任务,特别是在需要执行定时任务或者轮询操作的情况下。Node.js提供了多种方式来实现定时器功能,包括setTimeout、setInterval和setImmediate等方法。本篇博客将介绍如何在Node.js中使用这些定时器,并…

WPF真入门教程30--顺风物流单据管理系统

1、教程回顾 到现在为止,真入门系列教程已完成了29刺由浅入深地讲解,当然不可能讲到了WPF的所有技能点,但读者看到了wpf的内部各种功能及之间的联系,在此基础上,提供一个完整有效的综合项目,本项目采用的是…

期货开户保证金保障市场正常运转

期货保证金是什么?在期货市场上,采取保证金交易制度,投资者只需按期货合约的价值,交一定比率少量资金即可参与期货合约买卖交易,这种资金就是期货保证金。期货保证金(以下简称保证金〕按性质与作用的不同。…

AGV搬运机器人能给企业带来哪些效益?

agv 当前物流行业正在以每年40%的速度快速增长,却依然是典型的劳动密集型行业。随着机器人技术的崛起,传统物流行业也开始加大对物流科技设备的研发。AGV机器人被广泛应用于整个仓储系统内,疏解了一部分人力的负担,使后台工作更加…