【pytorch框架】使用 PyTorch 进行深度学习

1.Pytorch介绍

 PyTorch 是由 Facebook 创建和发布的用于深度学习计算的 Python 库。它起源于早期的库 Torch 7,但完全重写。

它是两个最受欢迎的深度学习库之一。PyTorch 是一个完整的库,能够训练深度学习模型以及在推理模式下运行模型,并支持使用 GPU 进行更快的训练和推理。这是一个我们不能忽视的平台。

您可以使用 pip安装 PyTorch 。在撰写本文时,PyTorch 的最新版本是 2.0。每个平台(包括 Windows、Linux 和 macOS)都有预构建的 PyTorch。在有效的 Python 环境中,应该照顾好这一点, pip 以便在您的平台中为您提供最新版本。

除了 PyTorch 之外,还有通常与 PyTorch 一起使用的 torchvision 库。它提供了许多有用的功能来帮助计算机视觉项目。

sudo pip install torch torchvision

这样安装可能默认安装最新版本,也可以通过pip自定义进行安装 Previous PyTorch Versions | PyTorch

 可选cuda版本或者使用cpu还有平台版本(windows、linux、mac)

使用示例

# Example of PyTorch library
import torch
# declare two symbolic floating-point scalars
a = torch.tensor(1.5)
b = torch.tensor(2.5)
# create a simple symbolic expression using the add function
c = torch.add(a, b)
print(c)

 查看torch版本

import torch
print(torch.__version__)

2.构建第一个多层感知机模型

 深度学习是关于构建大规模神经网络。神经网络最简单的形式称为多层感知器模型。神经网络的构建块是人工神经元或感知器。这些是简单的计算单元,具有加权输入信号并使用激活函数产生输出信号。

感知器被排列成网络。一排感知器称为一层,一个网络可以有多个层。网络中感知器的架构通常称为网络拓扑。配置完成后,需要在数据集上训练神经网络。神经网络的经典且仍然首选的训练算法称为随机梯度下降。

 PyTorch 允许您在极少的代码行中开发和评估深度学习模型。

 在下文中,您的目标是使用 PyTorch 开发您的第一个神经网络。使用 UCI 机器学习存储库中的标准二进制(两类)分类数据集,例如 Pima Indians 数据集。

为了简单起见,网络模型只是几层完全连接的感知器。在此特定模型中,数据集有 12 个输入或预测变量,输出是 0 或 1 的单个值。因此,网络模型应有 12 个输入(第一层)和 1 个输出(最后一层)。您的第一个模型将按如下方式构建: 

import torch.nn as nn

model = nn.Sequential(
  nn.Linear(8, 12),
  nn.ReLU(),
  nn.Linear(12, 8),
  nn.ReLU(),
  nn.Linear(8, 1),
  nn.Sigmoid()
)
print(model)

这是一个具有 3 个全连接层的网络。每个层都是使用以下 nn.Linear(x, y) 语法在 PyTorch 中创建的,第一个参数是该层的输入数,第二个参数是输出数。在每层之间,使用整流线性激活,但在输出端,应用 Sigmoid 激活,使输出值介于 0 和 1 之间。这是一个典型的网络。深度学习模型就是在模型中有很多这样的层。 

3.训练Pytorch模型

在 PyTorch 中构建神经网络并不能说明应该如何为特定作业训练模型。事实上,正如超参数所描述的那样,这方面有许多变化。在 PyTorch 或所有深度学习模型中,您需要决定以下有关如何训练模型: 

  • 什么是数据集,特别是输入和目标的外观
  • 什么是损失函数来评估模型与数据的拟合优度
  • 训练模型的优化算法是什么,优化算法的参数,如学习率和学习次数

使用了皮马印第安人数据集,所有输入都是数字。这将是最简单的情况,因为您不需要对数据进行任何预处理,因为神经网络可以轻松处理数字。

由于是二元分类问题,损失函数应为二元交叉熵。这意味着模型输出的目标值为分类结果的 0 或 1。但实际上,该模型可能会输出介于两者之间的任何内容。它越接近目标值越好(即损耗越低)。

梯度下降是优化神经网络的算法。梯度下降有许多变化,亚当是最常用的一种。

实现上述所有内容,以及上一课中构建的模型,以下是训练过程的代码:

import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim

dataset = np.loadtxt('pima-indians-diabetes.csv', delimiter=',')
X = dataset[:,0:8]
y = dataset[:,8]
X = torch.tensor(X, dtype=torch.float32)
y = torch.tensor(y, dtype=torch.float32).reshape(-1, 1)

loss_fn = nn.BCELoss() # binary cross-entropy
optimizer = optim.Adam(model.parameters(), lr=0.001)

n_epochs = 100
batch_size = 10
for epoch in range(n_epochs):
    for i in range(0, len(X), batch_size):
        Xbatch = X[i:i+batch_size]
        y_pred = model(Xbatch)
        ybatch = y[i:i+batch_size]
        loss = loss_fn(y_pred, ybatch)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    print(f'Finished epoch {epoch}, latest loss {loss}')

上面的for循环是获取一批数据并馈入模型。然后观察模型的输出并计算损失函数。基于损失函数,优化器将对模型进行一步微调,使其能够更好地匹配训练数据。经过多个更新步骤后,模型应该足够接近训练数据,以便能够高精度地预测目标。 

运行上面的训练循环,观察随着训练循环的进行,损失如何减少。

4.使用Pytorch模型推理

 经过训练的神经网络模型是一种记住输入和目标如何相关的模型。然后,该模型可以在给定另一个输入的情况下预测目标。

在 PyTorch 中,经过训练的模型可以像函数一样运行。假设您在上一课中训练了模型,您可以按如下方式简单地使用它:

i = 5
X_sample = X[i:i+1]
y_pred = model(X_sample)
print(f"{X_sample[0]} -> {y_pred[0]}")

 但实际上,运行推理的更好方法如下:

i = 5
X_sample = X[i:i+1]
model.eval()
with torch.no_grad():
    y_pred = model(X_sample)
print(f"{X_sample[0]} -> {y_pred[0]}")

 某些模型在训练和推理之间会有不同的行为。的 model.eval() 表示模型的目的是运行模型进行推理。该行 with torch.no_grad() 用于创建运行模型的上下文,以便 PyTorch 知道不需要计算梯度。这样可以消耗更少的资源。

这也是评估模型的方式。该模型输出一个介于 0 和 1 之间的 sigmoid 值。您可以通过将值四舍五入到最接近的整数(即布尔标签)来解释该值。比较舍入后的预测与目标匹配的频率,可以为模型分配准确率百分比,如下所示: 

model.eval()
with torch.no_grad():
    y_pred = model(X)
accuracy = (y_pred.round() == y).float().mean()
print(f"Accuracy {accuracy}")

运行上面的代码,看看你得到的准确性是多少。您应该达到大约 75%。 

5.使用Torchvision加载数据

 Torchvision 是 PyTorch 的姊妹库。在这个库中,有专门用于图像和计算机视觉的函数。如您所料,有一些功能可以帮助您读取图像或调整对比度。但可能最重要的是提供一个简单的接口来获取一些图像数据集。

 您将构建一个深度学习模型来对小图像进行分类。这是一个模型,允许您的计算机查看图像上的内容。正如您在前面的课程中所看到的,拥有数据集来训练模型非常重要。您将使用的数据集是 CIFAR-10。它是 10 个不同对象的数据集。还有一个更大的数据集,称为CIFAR-100。

CIFAR-10数据集可以从互联网上下载。但是,如果您安装了torchvision,则只需执行以下操作: 

import matplotlib.pyplot as plt
import torchvision

trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True)
testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True)

fig, ax = plt.subplots(4, 6, sharex=True, sharey=True, figsize=(12,8))
for i in range(0, 24):
    row, col = i//6, i%6
    ax[row][col].imshow(trainset.data[i])
plt.show()

该 torchvision.datasets.CIFAR10 函数可帮助您将 CIFAR-10 数据集下载到本地目录。数据集分为训练集和测试集。因此,上面的两行就是要得到它们。然后,从下载的数据集中绘制前 24 张图像。数据集中的每张图像都是以下之一的 32×32 像素图片:飞机、汽车、鸟、猫、鹿、狗、青蛙、马、船或卡车。 

6.使用Pytorch的DataLoader

上一课的 CIFAR-10 图像确实是 numpy 数组的格式。但对于 PyTorch 模型的使用,它需要位于 PyTorch 张量中。将 numpy 数组转换为 PyTorch 张量并不难,但在训练循环中,仍然需要将数据集分批划分。PyTorch DataLoader 可以帮助您使此过程更加顺畅。 

回到上一课中加载的 CIFAR-10 数据集,您可以执行以下操作以获得相同的效果:

import matplotlib.pyplot as plt
import torchvision
import torch
from torchvision.datasets import CIFAR10

transform = torchvision.transforms.Compose([torchvision.transforms.ToTensor()])
trainset = CIFAR10(root='./data', train=True, download=True, transform=transform)
testset = CIFAR10(root='./data', train=False, download=True, transform=transform)

batch_size = 24
trainloader = torch.utils.data.DataLoader(trainset, batch_size=batch_size, shuffle=True)
testloader = torch.utils.data.DataLoader(testset, batch_size=batch_size, shuffle=True)

fig, ax = plt.subplots(4, 6, sharex=True, sharey=True, figsize=(12,8))
for images, labels in trainloader:
    for i in range(batch_size):
        row, col = i//6, i%6
        ax[row][col].imshow(images[i].numpy().transpose([1,2,0]))
    break  # take only the first batch
plt.show()

在此代码中,使用 transform 参数创建, trainset 以便在提取数据时将数据转换为 PyTorch 张量。这是在它后面的几行中 DataLoader 执行的。该 DataLoader 对象是一个 Python 可迭代对象,您可以提取输入(图像)和目标(整数类标签)。在本例中,将批处理大小设置为 24,并迭代第一个批处理。然后,显示批处理中的每个图像。 

7.卷积神经网络

 图像是 2D 结构。您可以通过扁平化它们轻松地将它们转换为一维向量,并构建神经网络模型来对它们进行分类。但众所周知,保留 2D 结构会更合适,因为分类是关于图像中的内容,即平移不变的。

图像处理神经网络的标准方法是使用卷积层。使用卷积层的神经网络称为卷积神经网络。示例如下:

import torch.nn as nn

model = nn.Sequential(
    nn.Conv2d(3, 32, kernel_size=(3,3), stride=1, padding=1),
    nn.ReLU(),
    nn.Dropout(0.3),
    nn.Conv2d(32, 32, kernel_size=(3,3), stride=1, padding=1),
    nn.ReLU(),
    nn.MaxPool2d(kernel_size=(2, 2)),
    nn.Flatten(),
    nn.Linear(8192, 512),
    nn.ReLU(),
    nn.Dropout(0.5),
    nn.Linear(512, 10)
)
print(model)

在上面,我们多次使用了 Conv2d 图层,以及 ReLU 激活。卷积层用于从图像中学习和提取特征。您添加的卷积层越多,网络可以学习更多高级特征。最终,您将使用池化层( MaxPool2d 如上图)对提取的特征进行分组,将它们展平为向量,然后将其传递到多层感知器网络进行最终分类。这是图像分类模型的通常结构。 

8.训练图像分类器

结合为 CIFAR-10 数据集创建的 DataLoader,您可以使用以下训练循环来训练上一课中的卷积神经网络: 

import torch.nn as nn
import torch.optim as optim

loss_fn = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)

n_epochs = 20
for epoch in range(n_epochs):
    model.train()
    for inputs, labels in trainloader:
        y_pred = model(inputs)
        loss = loss_fn(y_pred, labels)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    acc = 0
    count = 0
    model.eval()
    with torch.no_grad():
        for inputs, labels in testloader:
            y_pred = model(inputs)
            acc += (torch.argmax(y_pred, 1) == labels).float().sum()
            count += len(labels)
    acc /= count
    print("Epoch %d: model accuracy %.2f%%" % (epoch, acc*100))

这将需要一段时间才能运行,您应该看到生成的模型可以达到不低于 70% 的准确率。 

该模型是一个多分类网络。输出不是一个,而是许多分数,每个类一个。我们认为分数越高,模型认为图像属于某个类的置信度就越高。因此,使用的损失函数是交叉熵,即二元交叉熵的多类版本。 

在上面的训练循环中,您应该会看到在前面的课程中学到的相当多的元素。包括在模型中的训练模式和推理模式之间切换、使用 torch.no_grad() 上下文以及计算准确性。

9.使用GPU训练

在 PyTorch 中使用 GPU 的方法是在执行之前将模型和数据发送到 GPU。然后,您可以选择从 GPU 发回结果,或直接在 GPU 中执行评估。

 修改上一课中的代码以使用 GPU 并不难。以下是应该做的:

import torch.nn as nn
import torch.optim as optim

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model.to(device)

loss_fn = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)

n_epochs = 20
for epoch in range(n_epochs):
    model.train()
    for inputs, labels in trainloader:
        y_pred = model(inputs.to(device))
        loss = loss_fn(y_pred, labels.to(device))
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    acc = 0
    count = 0
    model.eval()
    with torch.no_grad():
        for inputs, labels in testloader:
            y_pred = model(inputs.to(device))
            acc += (torch.argmax(y_pred, 1) == labels.to(device)).float().sum()
            count += len(labels)
    acc /= count
    print("Epoch %d: model accuracy %.2f%%" % (epoch, acc*100))

所做的更改如下: 您检查 GPU 是否可用并相应地设置。 device 然后将模型发送到设备。当输入(即一批图像)传递到模型时,应首先将其发送到相应的设备。由于模型输出也将在那里,因此损失计算或精度计算也应首先将目标发送到 GPU。

参考链接

Deep Learning with PyTorch (9-Day Mini-Course) - MachineLearningMastery.com

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

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

相关文章

stm32内存分配博客笔记

原文: stm32内存分配 笔记: 1、向量表与代码段;根据Cortex-M3权威指南描述,系统复位后,在向量表异常0处保存的是堆栈起始地址,而后紧跟中断向量表 2、可以从链接脚本.ld文件中看到终端向量表第一个被链接…

一篇文章带你了解 什么是u(ustd)带你了解他的前世今生

在数字货币的繁荣世界中,USDT无疑是其中一位重要的角色。它的前世今生,是一个从无到有,从小到大,经历了种种波折和争议的故事。 2014年11月下旬,一个名为Realcoin的注册地为马恩岛和香港的公司决定改变自己的名字&…

如何创建vite项目!

vite 官网:vite是一种新型前端构建工具,能够显著提升前端开发体验 网络:vite是一个静态服务器,也可以说是一个开发的构建工具 它的目标就是提供快速的开发体验和性能优化 vite优点与缺点 Vite 优点Vite 缺点开发服务器比 Webp…

flink部署模式介绍

在一些应用场景中,对于集群资源分配和占用的方式,可能会有特定的需求。Flink 为各种场景提供了不同的部署模式,主要有以下三种,它们的区别主要在于: 集群的生命周期以及资源的分配方式;应用的 main 方法到…

宠物空气净化器推荐哪个好?实惠的猫用猫用净化器牌子测评

作为宠物主人,我们深知养宠物的乐趣和责任,但同时也面临着一些挑战,比如宠物掉毛、异味和空气质量等问题。这就是为什么越来越多的家庭选择宠物空气净化器,为我们创造一个清新、健康的室内环境。 无论我们多么爱我们的毛茸茸伙伴…

[RK-Linux] 移植Linux-5.10到RK3399(九)| 配置USB-A支持HOST功能

文章目录 一、原理图二、设备树三、功能验证一、原理图 RK3399 的 USB 控制器接口如图: 其中 USB PHY0 的 HOST0_DP、HOST0_DM 网络没有使用。 USB PHY0 的 TYPEC0_DP、TYPEC0_DM、TYPEC0_U2VBUSDET 网络用作 type-c 接口。 USB PHY1 的 HOST1_DP、HOST1_DM 网络用作 USB2.…

仰暮计划|“日子过得苦为什么还要生三个小孩呢”

故事的主角是我的奶奶,今年74岁。她的个子不高,但她的脊背笔挺,透露着难掩的坚毅,从她的独家记忆中,更证实了这一点。 少年担责 “奶奶,给我讲讲你小时候吧。” 还没开口,奶奶的眼中泛起了点点…

C# wpf利用Clip属性实现截屏框

wpf截屏系列 第一章 使用GDI实现截屏 第二章 制作截屏框(本章) ______第一节 使用DockPanel制作截屏框 ______第二节 利用Clip属性实现截屏框(本节) 第三章 实现截屏框热键截屏 第四章 实现截屏框实时截屏 第五章 使用ffmpeg命令行实现录屏 文章目录 wp…

pnpm使用

文章目录 前言一、安装二、设置镜像三、使用总结如有启发,可点赞收藏哟~ 前言 pnpm 全称 performant npm,意思为 高性能的 npm 速度快、节约磁盘空间、支持 monorepo、安全性高。 一、安装 npm install -g pnpm or brew install pnpm二、设置镜像 #…

每日一题 670. 最大交换(中等,后缀)

先考虑最简单的情况,如果在首位之后有比它大的数字,那么显然交换这两个数字是最优解其次如果比它大的数字在后面不止出现了一次,那面显然是用最后一次出现的那个位置进行交换(要使值最大,低位要小,高位要大…

MAXWELL

MAXWELL 一、maxwell是什么 maxwell 官网地址:http://maxwells-daemon.io/ 因为官网是纯英文的,倒是不难懂,但总觉得写的略粗糙(也可能笔者英文水平确实拉胯,有待提高)。所以还是自己百度了一下。 当my…

WhatsApp会话信息该如何备份以及还原

对于出海企业来说,WhatsApp是和客户沟通的必备软件之一。无论是聊单还是询盘都可以在WhatsApp上进行,所以WhatsApp上通常存储了很多交易信息。但是WhatsApp软件本身是端对端加密,所以它不会像其他社交软件一样帮你自动在后台备份,…

制造业管理软件:为何ERP替代不了MES?

一、ERP和MES的功能区别 ERP是一种综合性的企业管理软件,它涵盖了企业的各个方面,包括财务、采购、库存、销售、人力资源等。它的主要功能是将企业内部的各项业务整合为一个整体进行管理,实现信息共享和协同工作。ERP的主要特点是可以对企业…

HackTheBox - Medium - Linux - Noter

Noter Noter 是一种中型 Linux 机器,其特点是利用了 Python Flask 应用程序,该应用程序使用易受远程代码执行影响的“节点”模块。由于“MySQL”守护进程以用户“root”身份运行,因此可以通过利用“MySQL”的用户定义函数来利用它来获得RCE并…

c语言小游戏之扫雷

目录 一:游戏设计理念及思路 二:初步规划的游戏界面 三:开始扫雷游戏的实现 注:1.创建三个文件,test.c用来测试整个游戏的运行,game.c用来实现扫雷游戏的主体,game.h用来函数声明和包含头文…

【立创EDA-PCB设计基础】5.布线设计规则设置

前言:本文详解布线前的设计规则设置。经过本专栏中的【立创EDA-PCB设计基础】前几节已经完成了布局,接下来开始进行布线,在布线之前,要设置设计规则。 目录 1.间距设置 1.1 安全间距设置 1.2 其它间距设置 2.物理设置 2.1 导…

枚举类型有着一篇足以

✅作者简介:大家好,我是橘橙黄又青,一个想要与大家共同进步的男人😉😉 🍎个人主页:橘橙黄又青-CSDN博客 1.关键字enum的定义 enum是C语言中的一个关键字,enum叫枚举数据类型&#…

JavaScript基础之JavaScript引入方式

JavaScript引入方式 JavaScript 程序不能独立运行,它需要被嵌入 HTML 中,然后浏览器才能执行 JavaScript 代码。通过 script 标签将 JavaScript 代码引入到 HTML 中,一般以下方式: 外部方式内部方式JavaScript元素事件通过JavaScript伪URL引…

Spring Boot 4.0:构建云原生Java应用的前沿工具

目录 前言 Spring Boot简介 Spring Boot 的新特性 1. 支持JDK 17 2. 集成云原生组件 3. 响应式编程支持 4. 更强大的安全性 5. 更简化的配置 Spring Boot 的应用场景 1. 云原生应用开发 2. 响应式应用程序 3. 安全性要求高的应用 4. JDK 17的应用 总结 作…