【基于 PyTorch 的 Python 深度学习】5 机器学习基础(3)

前言

文章性质:学习笔记 📖

学习资料:吴茂贵《 Python 深度学习基于 PyTorch ( 第 2 版 ) 》【ISBN】978-7-111-71880-2

主要内容:根据学习资料撰写的学习笔记,该篇主要介绍了单 GPU 加速和多 GPU 加速,以及使用 GPU 的注意事项。

预:关于 GPU 加速

深度学习涉及很多向量或多矩阵运算,如矩阵相乘、矩阵相加、矩阵-向量乘法等。深层模型的算法,如 BP 、自编码器、CNN 等,都可以写成矩阵运算的形式,而无须写成循环运算。然而,在单核 CPU 上执行时,矩阵运算会被展开成循环的形式,本质上还是串行执行。GPU(Graphic Process Unit,图形处理器)的众核体系结构包含几千个流处理器,可将矩阵运算并行化执行,大幅缩短计算时间。随着 NVIDIA 、AMD 等公司不断推进其 GPU 的大规模并行架构,面向通用计算的 GPU 已成为加速可并行应用程序的重要手段。得益于 GPU 众核(Many-Core)体系结构,程序在 GPU 系统上的运行速度相较于单核 CPU 往往提升几十倍乃至上千倍。

目前,GPU 已经发展到了较为成熟的阶段。利用 GPU 来训练深度神经网络,可以充分发挥其计算核心的能力,使得在使用海量训练数据的场景下所耗费的时间大幅缩短,占用的服务器也更少。如果对深度神经网络进行合理优化,一块 GPU 卡相当于数十甚至上百台 CPU 服务器的计算能力,因此 GPU 已经成为业界在深度学习模型训练方面的首选解决方案。

如何使用 GPU ?现在很多深度学习工具都支持 GPU 运算,使用时只需要简单配置即可。PyTorch 支持 GPU,可以通过 to(device) 函数来将数据从内存中转移到 GPU 显存,如果有多个 GPU ,还可以定位到哪个或哪些 GPU ?PyTorch 一般把 GPU 作用于张量或模型(包括 torch.nn 下面的一些网络模型以及自己创建的模型)等数据结构上。

一、单 GPU 加速

使用 GPU 之前,需要确保 GPU 是可用的,可以通过 torch.cuda.is_available() 的返回值来进行判断。返回 True 则表示具有能够使用的 GPU 。 通过 torch.cuda.device_count() 可以获得可用的 GPU 的数量。

如何查看平台 GPU 的配置信息?在命令行输入命令 nvidia-smi 即可(适合于 Linux 或 Windows 环境),如图 5-28 所示。

把数据从内存转移到 GPU ,通常针对 张量(我们需要的数据)和 模型

1. 对于类型为 FloatTensor 或 LongTensor 等的张量,我们直接使用方法 .to(device).cuda() 即可。

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# 或 device = torch.device("cuda:0")
device1 = torch.device("cuda:1")  
for batch_idx, (img, label) in enumerate(train_loader):img = img.to(device)label = label.to(device)

2. 对于模型来说,也使用 .to(device).cuda() 方法来将网络放到 GPU 显存中。

# 实例化网络
model = Net()
model.to(device)    # 使用序号为 0 的 GPU
# 或 model.to(device1)    # 使用序号为 1 的 GPU

二、多 GPU 加速

这里我们介绍单主机多 GPU 的情况,单主机多 GPU 主要采用的是 DataParallel 函数,而不是 DistributedParallel,后者一般用于多主机多 GPU ,当然也可用于单主机多 GPU 。使用多 GPU 训练的方式有很多,前提是我们的设备中存在两个及以上 GPU 。使用时直接用模型传入 torch.nn.DataParallel 函数即可,代码如下:

# 对于模型
net = torch.nn.DataParallel(model)

这时,默认所有存在的显卡都会被使用。如果你的电脑有很多显卡,但只想利用其中的部分,例如,只使用编号为 0 、1 、3 、4 的四个 GPU ,那么可以采用以下方式:

# 假设有 4 个 GPU ,其 id 设置如下
device_ids = [0, 1, 2, 3]
# 对于数据
input_data = input_data.to(device=device_ids[0])
# 对于模型
net = torch.nn.DataParallel(model)
net.to(device)

或者:

os.environ["CUDA_VISIBLE_DEVICES"] = ','.join(map(str, [0, 1, 2, 3]))
net = torch.nn.DataParallel(model)

说明:其中的 CUDA_VISIBLE_DEVICES 表示当前可以被 PyTorch 程序检测到的 GPU 。

下面为单机多 GPU 的实现代码:

1)背景说明。以波士顿房价数据为例,共 506 个样本,13 个特征。数据划分成训练集和测试集,然后用 data.DataLoader 将数据转换为可批加载的方式。采用 nn.DataParallel 并发机制,环境有 2 个 GPU 。当然,数据量很小,按理不宜用 nn.DataParallel 。

2)加载数据。

boston = load_boston()
X, y = (boston.data, boston.target)
dim = X.shape[1]X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
# 组合训练数据及标签
myset = list(zip(X_train, y_train))

3)把数据转换为批处理加载方式。批次大小为 128 ,打乱数据。

from torch.utils import data
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
dtype = torch.FloatTensortrain_loader = data.DataLoader(myset, batch_size=128, shuffle=True)

4)定义网络。

class Net1(nn.Module):"""使用 Sequential() 函数构建网络,Sequential()函数的功能是将网络的层组合到一起"""def __init__(self, in_dim, n_hidden_1, n_hidden_2, out_dim):super(Net1, self).__init__()self.layer1 = torch.nn.Sequential(nn.Linear(in_dim, n_hidden_1))self.layer2 = torch.nn.Sequential(nn.Linear(n_hidden_1, n_hidden_2))self.layer3 = torch.nn.Sequential(nn.Linear(n_hidden_2, out_dim))def forward(self, x):x1 = F.relu(self.layer1(x))x1 = F.relu(self.layer2(x1))x2 = self.layer3(x1)# 显示每个 GPU 分配的数据大小print("\tIn Model: input size", x.size(), "output size", x2.size())return x2

5)把模型转换为多 GPU 并发处理格式。

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# 实例化网络
model = Net1(13, 16, 32, 1)
if torch.cuda.device_count() > 1:print("Let's use", torch.cuda.device_count(), "GPUs")# dim = 0 [64, xxx] -> [32, ...], [32, ...] on 2GPUsmodel = nn.DataParallel(model)model.to(device)

运行的结果如下:

6)选择优化器及损失函数。

optimizer_orig = torch.optim.Adam(model.parameters(), lr=0.01)
loss_func = torch.nn.MSELoss()

7)模型训练,并可视化损失值。

from torch.utils.tensorboard import SummaryWriter
# from tensorboardX import SummaryWriter
writer = SummaryWriter(log_dir='logs')
for epoch in range(100):        model.train()for data, label in train_loader:input = data.type(dtype).to(device)label = label.type(dtype).to(device)output = model(input)       loss = loss_func(output, label)# 反向传播optimizer_orig.zero_grad()loss.backward()optimizer_orig.step()print("Outside: input size", input.size(), "output_size", output.size())writer.add_scalar('train_loss_paral', loss, epoch)

运行的部分结果如下:

从运行结果可以看出,一个批次数据( batch-size=128 )拆分成两份,每份大小为 64 ,分别放在不同的 GPU 上。此时用 GPU 监控也可以发现两个 GPU 同时在使用,如图 5-29 所示。

 8)通过 Web 页面查看损失值的变化情况,如图 5-30 所示。

图形中出现较大振幅是由于采用批次处理,而且数据没有做任何预处理,因此对数据进行规范化应该更平滑一些。

单主机多 GPU 也可使用 DistributedParallel 函数,虽然配置比使用 nn.DataParallel 函数稍微麻烦一点,但是训练速度和效果更好。

具体配置为:

# 初始化使用 nccl 后端
torch.distributed.init_process_group(backend="nccl")
# 模型并行化,使用多进程,可单机或分布式训练
model = torch.nn.parallel.DistributedDataParallel(model)

单主机运行时,使用下列方法启动:

python -m torch.distributed.launch main.py

参考代码:feiguyunai/Python-DL-PyTorch2/pytorch-05/pytorch-05-05.ipynb at main · Wumg3000/feiguyunai · GitHub

三、使用 GPU 的注意事项

使用 GPU 可以提升训练的速度,但如果使用不当,可能影响使用效率,具体注意事项如下:

• GPU 的数量尽量为偶数,奇数个 GPU 可能会出现异常中断的情况;

• GPU 训练速度很快,但数据量较小时,效果可能没有单 GPU 好,甚至还不如 CPU ;

• 如果内存不够大,使用多 GPU 训练的时候可通过设置 pin_memory 为 False,当然有时使用精度稍低的数据类型的效果也还行。

第五章の小结 

本章从机器学习的概念出发,首先说明其基本任务、一般流程等,然后说明在机器学习中解决过拟合、欠拟合的一些常用技巧或方法。同时介绍了各种激活函数、损失函数、优化器等机器学习、深度学习的核心内容。最后说明在程序中如何设置 GPU 设备、如何用 GPU 加速训练模型等内容。这章是深度学习的基础。

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

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

相关文章

英语口语情景对话视频软件分享!

在当今全球化的时代,英语已成为一种通用的国际语言。为了提高英语口语能力,越来越多的人选择使用英语口语情景对话视频软件。本文将为您推荐几款备受欢迎的英语口语情景对话视频软件,帮助您轻松提高英语口语水平。 AI外语陪练 AI外语陪练软件…

已经有 Prometheus 了,还需要夜莺?

谈起当下监控,Prometheus 无疑是最火的项目,如果只是监控机器、网络设备,Zabbix 尚可一战,如果既要监控设备又要监控应用程序、Kubernetes 等基础设施,Prometheus 就是最佳选择。甚至有些开源项目,已经内置…

LoRA的原理简介

在文章开始前先澄清一个概念,需要区分形近的单词"LoRa"(long range),这是一项通信技术。熟悉物联网行业的朋友相对会比较熟悉LoRa这项技术,因为有些设备比如电梯的控制就使用了这个技术进行本地数据和命令的…

小红书释放被封手机号 无限注册

前几年抖音也可以释放被封手机号 那时候都不重视 导致现在被封手机号想释放 基本不可能的 或者就是最少几百块 有专业的人帮你通过某些信息差释放 本教程是拆解 小红书被封手机号怎么释放,从今年开始,被封的手机号无法注销了 所以很困扰 那么本教程来…

基于一种改进小波阈值的微震信号降噪方法(MATLAB)

微震是指岩体由于在人为扰动或自然原因下受力变形,发生破裂过程中能量积聚而释放的弹性波或应力波。微震信号具有信噪比低、不稳定性、瞬时性和多样性等特点。因此,在任何损坏之前都会出现微小的裂缝,这种微小的裂缝是由岩层中应力和应变的变…

PPT职场课:话术+技巧+框架+案例,告别只会念PPT不会讲(8节课)

课程目录 001-讲PPT如何开场及导入?5个简单实用的方法.mp4 002-讲PPT如何过渡衔接结尾?6类话术争来就用.mp4 003-掌握这3个逻辑表达万能框架,搞定98的PPT.mp4 004-学会这3种PPT结构讲解技巧告别只会念不会讲(上).mp4 005-学会这3种PPT结构讲解技巧告别只会念…

Logstash分析MySQL慢查询日志实践

删除匹配到的行,当前行信息不记录到message中

106网页短信群发平台

什么是106网页短信群发平台? 106网页短信群发平台是一种便捷的在线群发工具,通过该平台用户可以方便地向大量的手机号码*。相比传统的群发方式,106网页群发平台具有更高效、更便捷的特点。 为什么选择106网页短信群发平台? 高效快…

浙大×移动云,携手点亮AI新时代

近年来,中国移动依托强大的算网资源优势,围绕大模型训练、推理和应用三大场景,打造了一站式智算产品体系。该体系旨在为客户提供覆盖资源、平台、应用的AI全链路服务。目前,一站式智算产品体系已在浙江大学智算中心和许昌中原智算…

C++:编程界的王者,引领未来的创新之路

在编程语言的浩瀚星空中,C犹如一颗耀眼的恒星,以其卓越的性能、深厚的底蕴和广泛的应用领域,持续引领着编程界的发展。它不仅在当下拥有无可替代的地位,更在未来展现出无限的潜力和可能性。 一、C:编程界的王者风范 …

若依框架dialog弹窗取消点击空白出关闭

如果想全局取消的话就找到main.js在里面加上下面的一行代码,添加完成之后记得清楚浏览器缓存重新加载js文件。 Element.Dialog.props.closeOnClickModal.default false;如果想指定某个弹窗取消点击空白处关闭,那么就找到那个弹窗加上。添加完毕之后刷新…

【python】基于岭回归算法对学生成绩进行预测

前言 在数据分析和机器学习领域,回归分析是一种预测连续数值的监督学习技术。当数据特征与目标变量之间存在线性关系时,线性回归模型尤其有用。然而,当特征数量多于样本数量,或者特征之间存在多重共线性时,普通最小二…

unaipp推荐算法的汽车租赁系统zaxzu 微信小程序hbuiderx

随着现代汽车租赁管理的快速发展,可以说汽车租赁管理已经逐渐成为现代汽车租赁管理过程中最为重要的部分之一。但是一直以来我国传统的汽车租赁管理并没有建立一套完善的行之有效的汽车租赁管理系统,传统的汽车租赁管理已经无法适应高速发展,…

基于SpringBoot+Vue点餐系统设计和实现(源码+LW+部署讲解)

🌹作者简介:✌全网粉丝10W,前大厂员工,多篇互联网电商推荐系统专利,现有多家创业公司,致力于建站、运营、SEO、网赚等赛道。也是csdn特邀作者、博客专家、Java领域优质创作者,博客之星、掘金/华…

nginx的应用部署nginx

这里写目录标题 nginxnginx的优点什么是集群常见的集群什么是正向代理、反向代理、透明代理常见的代理技术正向代理反向代理透明代理 nginx部署 nginx nginx(发音同enginex)是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3&…

「Java开发指南」如何用MyEclipse搭建GWT 2.1和Spring?(一)

本教程将指导您如何生成一个可运行的Google Web Toolkit (GWT) 2.1和Spring应用程序,该应用程序为域模型实现了CRUD应用程序模式。在本教程中,您将学习如何: 安装Google Eclipse插件为GWT配置一个项目搭建从数据库表到一个现有的项目GWT编译…

C++ 模拟实现 priority_queue(优先队列)

目录 一,优先队列简介 二,priority_queue 的内部实现原理 三,模拟实现 priority_queue 1,模板参数与数据结构 2,构造 3,辅助功能(堆的有序化,建立堆) 4&#xff0…

AcWing 4993 FEB

4993. FEB - AcWing题库 大佬亲笔 将原串分成三段&#xff1a; FFF|E.....B|FFF 先合并中间段&#xff0c;再合并两边的段 #include <iostream> #include <cstring> #include <algorithm> #include <string> #include <queue&g…

STM32--LoRa通信模块

ATK-LORA-01_V3.0(V3.0 是版本号&#xff0c;型号是 ATK-LORA-01 &#xff0c;下面均以 ATK-LORA-01表示该产品) 是 ALIENTEK 推出的一款体积小、微功率、低功耗、高性能远距离 LORA 无线串口模块。模块设计是采用高效的 ISM 频段射频 SX1278 扩频芯片&#xff0c;模…

GaussianBody:基于3D高斯散射的服装人体重建

GaussianBody: Clothed Human Reconstruction via 3d Gaussian Splatting GaussianBody&#xff1a;基于3D高斯散射的服装人体重建 Mengtian Li1,2,3, Shengxiang Yao1, Zhifeng Xie1,3,2, Keyu Chen4,2, Yu-Gang Jiang2 李梦田 1,2,3 、姚胜祥 1 、谢志峰 1,3, 2 、陈科宇 4, …