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

news2024/9/29 13:31:21

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

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

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

相关文章

Vue3 watch与watchEffect区别

✨ 专栏介绍 在当今Web开发领域中,构建交互性强、可复用且易于维护的用户界面是至关重要的。而Vue.js作为一款现代化且流行的JavaScript框架,正是为了满足这些需求而诞生。它采用了MVVM架构模式,并通过数据驱动和组件化的方式,使…

Unity中UGUI在Mask剪裁粒子特效的实现

在Unity使用Mask是剪裁不了粒子特效的,之前有想过RenderTexture来实现,不过使用RenderTexture不适合用于很多个特效,因为RenderTexture依赖Camera的照射,如果在背包中每种道具都有不同的特效,那使用RenderTexture则需要…

255:vue+openlayers 加载tomtom地图(多种形式)

第255个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+openlayers中添加tomtom地图,这里包含了多种形式,诸如中文标记、英文标记、白天地图、晚上地图、卫星影像图,高山海拔地形图等。 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果 文章目录 示…

基于SpringBoot + vue 的旅游景区网站系统设计与实现

目录 一、需求分析 二、技术分析 三、功能分析 四、数据设计 五、界面展示 六、资源获取 一、需求分析 旅游推荐网站是指提供旅游相关信息、服务和建议的在线平台。这些网站旨在帮助用户规划和安排旅行,提供目的地信息、酒店预订、机票预订、租车服务、旅行建…

v42.循环控制语句breakcontinue

1.break 跟在if语句、Switch语句之后 跳出循环 2.continue 例如打印0--20的质数程序。此循环为for循环: 初始化后判断条件,执行完代码块,i的值必定会递增!⚠️ 循环的是if语句和printf函数。如果满足if语句 ,那么continue跳过当…

【视野提升】ChatGPT的系统是如何工作的?

类似ChatGPT的系统是如何工作的? 我们试图在下图中解释它是如何工作的。这个过程可以分为两个部分。 训练 要训练一个ChatGPT模型,有两个阶段: 预训练 在这个阶段,我们在大量互联网数据上训练一个GPT模型(仅解码器转…

配置环境变量—使用cmd打开QQ

1.windowsR输入cmd打开命令窗口,输入qq点击回车,不能正常运行,因为没有配置环境变量 2.鼠标右键点击QQ,打开文件所在位置,找到QQ.exe文件 3.点击上方复制路径 开始配置环境变量。 1.选中此电脑,鼠标右击&a…

css中>>>、/deep/、::v-deep的作用和区别,element-ui自定义样式

文章目录 一、前言1.1、/deep/1.2、::v-deep1.3、>>> 二、区别三、总结四、最后 一、前言 1.1、/deep/ 在style经常用scoped属性实现组件的私有化时,要改变element-ui某个深层元素(例如.el-input__inner)或其他深层样式时&#xf…

C++ Qt day2

自己封装一个矩形类(Rect)&#xff0c;拥有私有属性:宽度(width)、高度(height)&#xff0c; 定义公有成员函数: 初始化函数:void init(int w, int h) 更改宽度的函数:set_w(int w) 更改高度的函数:set_h(int h) 输出该矩形的周长和面积函数:void show() #include <io…

vue3-elementPlus部分组件样式修改

前提&#xff1a;在less语言下使用/deep/&#xff1b;在sass语言下使用 ::v-deep 替换 /deep/ 但::v-deep的写法已经废弃&#xff0c;建议使用:deep(css选择器) elementUI样式修改&#xff1a;vue2-elementUI部分组件样式修改_vue2 圆圈选中样式-CSDN博客 el-dropdown //下拉…

照片上的杂物怎么清除?这两个方法很好用

随着智能手机的普及和拍照技术的发展&#xff0c;我们经常会在社交媒体上分享自己的照片。然而&#xff0c;有时候拍摄的照片中会包含一些不必要的杂物&#xff0c;如电线、垃圾、阴影等&#xff0c;这些杂物会影响照片的美观度和视觉效果。这时候我们就需要借助工具来帮我们清…

ISA server2006 URL中文 报500错误

我在运维一个10几年前的老项目&#xff0c;有一个问题&#xff0c;一直困扰着我的客户。很久都没有解决。 表现就是在用中文搜索表单时&#xff0c;会看到如下的错误&#xff1a; 后来经过我的测试发现&#xff0c;只要是GET请求中传参包含中文时就必然出现这个报错。 探索…

Linux部署幻兽帕鲁服务器,PalWorld开服联机教程,保姆级教程

Linux系统搭建PalWorld私服&#xff0c;幻兽帕鲁开服联机教程&#xff0c;保姆级教程 最近这游戏挺火&#xff0c;很多人想跟朋友联机&#xff0c;如果有专用服务器&#xff0c;就不需要房主一直开着电脑&#xff0c;稳定性也好得多。 幻兽帕鲁简介 《幻兽帕鲁》是一款游戏作…

hdu1195 Open the lock 双向广度优先搜索

D-BFS 双向广度优先搜索 从起点和终点同时开始搜索&#xff0c;直到两个搜索的点相交&#xff0c;得到最短路径 Code: // D-BFS //by:MuQY #include <iostream> #include <algorithm> #include <string.h> #include <queue> #include <string> …

《WebKit 技术内幕》学习之十三(1):移动WebKit

1 触控和手势事件 1.1 HTML5规范 随着电容屏幕的流行&#xff0c;触控操作变得前所未有的流行起来。时至今日&#xff0c;带有多点触控功能已经成为了移动设备的标准配置&#xff0c;基于触控的手势识别技术也获得巨大的发展&#xff0c;如使用两个手指来缩放应用的大小等。…

【多线程】ThreadLocal 详解,举例说明

不理解多线程的同学可先了解多线程理论篇【多线程】线程是什么&#xff1f;多线程为什么&#xff1f;怎么做&#xff1f;通俗易懂讲解多线程 以及多线程进阶篇【多线程】多线程安全&#xff0c;为什么不安全&#xff0c;要怎么做保证其安全&#xff0c;实例 1、ThreadLocal是什…

快速入门Playwright框架:从零到自动化测试的第一步

Playwright框架&#xff1a; 背景介绍&#xff1a; ​ Playwright 是微软开发的 Web应用 的 自动化测试框架 。selenium相对于Playwright慢很多&#xff0c;因为Playwright是异步实现的&#xff0c;但是selenium是同步的&#xff0c;就是后一个操作必须等待前一个操作。 sel…

Python添加、修改和删除列表元素

Python 是一种简洁而强大的编程语言&#xff0c;广泛用于不同领域的软件开发和数据分析中。在 Python 中&#xff0c;列表&#xff08;List&#xff09;是一种非常常用的数据类型&#xff0c;用于存储一组元素并按顺序访问。本文将讨论如何在 Python 中对列表进行添加、修改和删…

[极客大挑战 2019]Upload1

直接上传php一句话木马&#xff0c;提示要上传image 把文件名改成gif并加上gif文件头后&#xff0c;绕过了对image类型的检测&#xff0c;但是提示文件内含有<?&#xff0c;且bp抓包后改回php也会被检测 那我们考虑使用js执行php代码 <script languagephp>eval($_PO…

mysql生成最近24小时整点最近30天最近12个月时间临时表

文章目录 生成最近24小时整点生成最近30天生成最近12个月 在统计的时候需要按时间来展示&#xff0c;但是数据的时间不一定是连续的&#xff0c;那就需要在代码里面生成连续的时间&#xff0c;然后按时间匹配到对应的数据&#xff0c;这样比较麻烦&#xff0c;可以在sql中使用连…