13个你一定要知道的PyTorch特性_pytorch 硬件加速

2023-03-26 07:51:30

 

1.pytorch cpu 加速

作者:ronghuaiyang转载自:极市平台原文链接:13个你一定要知道的PyTorch特性​mp.weixin.qq.com/s/YOrInbNOuBrj0wlMHl8OwA

2.pytorch jit加速

PyTorch在学术界和工业界的应用研究中都获得了很多关注它是一个具有很大灵活性的深度学习框架,使用了大量的实用工具和函数来加快工作速度PyTorch的学习曲线并不是那么陡峭,但在其中实现高效和干净的代码可能会很棘手。

3.pytorch gpu加速

在使用它超过2年之后,以下是我最喜欢的PyTorch功能,我希望我一开始学习它就知道1 DatasetFolder当学习PyTorch时,人们首先要做的事情之一是实现自己的某种Dataset 这是一个低级错误,没有必要浪费时间写这样的东西。

4.pytorch训练加速

通常,数据集要么是数据列表(或者是numpy数组),要么磁盘上的文件所以,把数据在磁盘上组织好,要比写一个自定义的Dataset来加载某种奇怪的格式更好分类器最常见的数据格式之一,是有一个带有子文件夹的目录,子文件夹表示类,子文件夹中的文件表示样本,如下所示。

5.pytorch dataloader加速

folder/class_0/file1.txtfolder/class_0/file2.txtfolder/class_0/...folder/class_1/file3.txtfolder/class_1

6.pytorch显卡加速

/file4.txtfolder/class_2/file5.txtfolder/class_2/...有一个内置的方式来加载这类数据集,不管你的数据是图像,文本文件或其他什么,只要使用DatasetFolder就可以了。

7.python硬件加速

令人惊讶的是,这个类是torchvision包的一部分,而不是核心PyTorch这个类非常全面,你可以从文件夹中过滤文件,使用自定义代码加载它们,并动态转换原始文件例子:fromtorchvision.datasets

8.pytorch性能

importDatasetFolderfrompathlibimportPath# I have text files in this folderds=DatasetFolder("/Users/marcin/Dev/tmp/my_text_dataset"

9.pytorch 慢

,loader=lambdapath:Path(path).read_text(),extensions=(".txt",),#only load .txt filestransform=lambdatext

10.pytorch硬件要求

:text[:100],# only take first 100 characters)# Everything you need is already therelen(ds),ds.classes

,ds.class_to_idx(20,[novels,thrillers],{novels:0,thrillers:1})如果你在处理图像,还有一个torchvision.datasets.ImageFolder类,它基于DatasetLoader,它被预先配置为加载图像。

2 尽量少用.to\(device\),用zeros\_like/ones\_like之类的代替我读过很多来自GitHub仓库的PyTorch代码最让我恼火的是,几乎在每个repo中都有许多*.to(device)行,它们将数据从CPU或GPU转移到其他地方。

这样的语句通常会出现在大量的repos或初学者教程中我强烈建议尽可能少地实现这类操作,并依赖内置的PyTorch功能自动实现这类操作到处使用.to(device)通常会导致性能下降,还会出现异常:Expected object of device type cuda but got device type cpu

显然,有些情况下你无法回避它,但大多数情况(如果不是全部)都在这里其中一种情况是初始化一个全0或全1的张量,这在深度神经网络计算损失的的时候是经常发生的,模型的输出已经在cuda上了,你需要另外的tensor也是在cuda上,这时,你可以使用*_like操作符:。

my_output# on any device, if its cuda then my_zeros will also be on cudamy_zeros=torch.zeros_like(my_output_from_model

)在内部,PyTorch所做的是调用以下操作:my_zeros=torch.zeros(my_output.size(),dtype=my_output.dtype,layout=my_output.layout

,device=my_output.device)所以所有的设置都是正确的,这样就减少了代码中出现错误的概率类似的操作包括:torch.zeros_like()torch.ones_like()torch。

.rand_like()torch.randn_like()torch.randint_like()torch.empty_like()torch.full_like()3 Register Buffer ( nn.Module.register_buffer)

这将是我劝人们不要到处使用 .to(device) 的下一步有时,你的模型或损失函数需要有预先设置的参数,并在调用forward时使用,例如,它可以是一个“权重”参数,它可以缩放损失或一些固定张量,它不会改变,但每次都使用。

对于这种情况,请使用nn.Module.register_buffer 方法,它告诉PyTorch将传递给它的值存储在模块中,并将这些值随模块一起移动如果你初始化你的模块,然后将它移动到GPU,这些值也会自动移动。

此外,如果你保存模块的状态,buffers也会被保存!一旦注册,这些值就可以在forward函数中访问,就像其他模块的属性一样fromtorchimportnnimporttorchclassModuleWithCustomValues。

(nn.Module):def__init__(self,weights,alpha):super().__init__()self.register_buffer("weights",torch.tensor

(weights))self.register_buffer("alpha",torch.tensor(alpha))defforward(self,x):returnx*self.weights+self

.alpham=ModuleWithCustomValues(weights=[1.0,2.0],alpha=1e-4)m(torch.tensor([1.23,4.56]))tensor([1.2301

,9.1201])4 Built-in Identity()有时候,当你使用迁移学习时,你需要用1:1的映射替换一些层,可以用nn.Module来实现这个目的,只返回输入值PyTorch内置了这个类例子,你想要在分类层之前从一个预训练过的ResNet50获取图像表示。

以下是如何做到这一点:fromtorchvision.modelsimportresnet50model=resnet50(pretrained=True)model.fc=nn.Identity()last_layer_output

=model(torch.rand((1,3,224,224)))last_layer_output.shapetorch.Size([1,2048])5 Pairwise distances: torch.cdist

下次当你遇到计算两个张量之间的欧几里得距离(或者一般来说:p范数)的问题时,请记住torch.cdist它确实做到了这一点,并且在使用欧几里得距离时还自动使用矩阵乘法,从而提高了性能points1=torch

.tensor([[0.0,0.0],[1.0,1.0],[2.0,2.0]])points2=torch.tensor([[0.0,0.0],[-1.0,-1.0],[-2.0,-2.0],[-3.0

,-3.0]])# batches dont have to be equaltorch.cdist(points1,points2,p=2.0)tensor([[0.0000,1.4142,2.8284

,4.2426],[1.4142,2.8284,4.2426,5.6569],[2.8284,4.2426,5.6569,7.0711]])没有矩阵乘法或有矩阵乘法的性能,在我的机器上使用mm时,速度快了2倍以上。

%%timeitpoints1=torch.rand((512,2))points2=torch.rand((512,2))torch.cdist(points1,points2,p=2.0,compute_mode

="donot_use_mm_for_euclid_dist")867µs±142µs per loop (mean±std. dev. of 7 run, 1000 loop each)%%timeit

points1=torch.rand((512,2))points2=torch.rand((512,2))torch.cdist(points1,points2,p=2.0)417µs±52.9µs per loop (mean±std. dev. of 7 run, 1000 loop each)

6 Cosine similarity: F.cosine_similarity与上一点相同,计算欧几里得距离并不总是你需要的东西当处理向量时,通常余弦相似度是选择的度量PyTorch也有一个内置的余弦相似度实现。

importtorch.nn.functionalasFvector1=torch.tensor([0.0,1.0])vector2=torch.tensor([0.05,1.0])print(F.cosine_similarity

(vector1,vector2,dim=0))vector3=torch.tensor([0.0,-1.0])print(F.cosine_similarity(vector1,vector3,dim

=0))tensor(0.9988)tensor(-1.)PyTorch中批量计算余弦距离importtorch.nn.functionalasFbatch_of_vectors=torch.rand((

4,64))similarity_matrix=F.cosine_similarity(batch_of_vectors.unsqueeze(1),batch_of_vectors.unsqueeze(

0),dim=2)similarity_matrixtensor([[1.0000,0.6922,0.6480,0.6789],[0.6922,1.0000,0.7143,0.7172],[0.6480

,0.7143,1.0000,0.7312],[0.6789,0.7172,0.7312,1.0000]])7 归一化向量: F.normalize最后一点仍然与向量和距离有松散的联系,那就是归一化:通常是通过改变向量的大小来提高计算的稳定性。

最常用的归一化是L2,可以在PyTorch中按如下方式应用:vector=torch.tensor([99.0,-512.0,123.0,0.1,6.66])normalized_vector=F.normalize

(vector,p=2.0,dim=0)normalized_vectortensor([1.8476e-01,-9.5552e-01,2.2955e-01,1.8662e-04,1.2429e-02])

在PyTorch中执行归一化的旧方法是:vector=torch.tensor([99.0,-512.0,123.0,0.1,6.66])normalized_vector=vector/torch.norm

(vector,p=2.0)normalized_vectortensor([1.8476e-01,-9.5552e-01,2.2955e-01,1.8662e-04,1.2429e-02])在PyTorch中批量进行L2归一化

batch_of_vectors=torch.rand((4,64))normalized_batch_of_vectors=F.normalize(batch_of_vectors,p=2.0,dim

=1)normalized_batch_of_vectors.shape,torch.norm(normalized_batch_of_vectors,dim=1)# all vectors will have length of 1.0

(torch.Size([4,64]),tensor([1.0000,1.0000,1.0000,1.0000]))8 线性层 + 分块技巧 (torch.chunk)这是我最近发现的一个有创意的技巧假设你想把你的输入映射到N个不同的线性投影中。

你可以通过创建N个nn.Linear来做到这一点或者你也可以创建一个单一的线性层,做一个向前传递,然后将输出分成N块这种方法通常会带来更高的性能,所以这是一个值得记住的技巧d=1024batch=torch

.rand((8,d))layers=nn.Linear(d,128,bias=False),nn.Linear(d,128,bias=False),nn.Linear(d,128,bias=False

)one_layer=nn.Linear(d,128*3,bias=False)%%timeito1=layers[0](batch)o2=layers[1](batch)o3=layers[2](batch

)289 µs ± 30.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)%%timeito1,o2,o3=torch.chunk(

one_layer(batch),3,dim=1)202 µs ± 8.09 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)9 Masked select (torch.masked_select)

有时你只需要对输入张量的一部分进行计算给你一个例子:你想计算的损失只在满足某些条件的张量上为了做到这一点,你可以使用torch.masked_select,注意,当需要梯度时也可以使用这个操作data=

torch.rand((3,3)).requires_grad_()print(data)mask=data>data.mean()print(mask)torch.masked_select(data

,mask)tensor([[0.0582,0.7170,0.7713],[0.9458,0.2597,0.6711],[0.2828,0.2232,0.1981]],requires_grad=True

)tensor([[False,True,True],[True,False,True],[False,False,False]])tensor([0.7170,0.7713,0.9458,0.6711

],grad_fn=)直接在tensor上应用mask类似的行为可以通过使用mask作为输入张量的 “indexer”来实现data[mask]tensor([

0.7170,0.7713,0.9458,0.6711],grad_fn=)有时,一个理想的解决方案是用0填充mask中所有的False值,可以这样做:data*masktensor

([[0.0000,0.7170,0.7713],[0.9458,0.0000,0.6711],[0.0000,0.0000,0.0000]],grad_fn=)10 使用 torch.where来对tensors加条件

当你想把两个张量结合在一个条件下这个函数很有用,如果条件是真,那么从第一个张量中取元素,如果条件是假,从第二个张量中取元素x=torch.tensor([1.0,2.0,3.0,4.0,5.0],requires_grad。

=True)y=-xcondition_or_mask=x<=3.0torch.where(condition_or_mask,x,y)tensor([1.,2.,3.,-4.,-5.],grad_fn

=)11 在给定的位置给张量填入值(Tensor.scatter)这个函数的用例如下,你想用给定位置下另一个张量的值填充一个张量一维张量更容易理解,所以我将先展示它,然后继续更高级的例子。

data=torch.tensor([1,2,3,4,5])index=torch.tensor([0,1])values=torch.tensor([-1,-2,-3,-4,-5])data.scatter

(0,index,values)tensor([-1,-2,3,4,5])上面的例子很简单,但是现在看看如果将index改为index = torch.tensor([0, 1, 4])会发生什么:data

=torch.tensor([1,2,3,4,5])index=torch.tensor([0,1,4])values=torch.tensor([-1,-2,-3,-4,-5])data.scatter

(0,index,values)tensor([-1,-2,3,4,-3])为什么最后一个值是-3,这是反直觉的,对吧?这是PyTorch scatter函数的中心思想index变量表示data张量的第i个值应该放在values张量的哪个位置。

我希望下面的简单python版的这个操作能让你更明白:data_orig=torch.tensor([1,2,3,4,5])index=torch.tensor([0,1,4])values=torch

.tensor([-1,-2,-3,-4,-5])scattered=data_orig.scatter(0,index,values)data=data_orig.clone()foridx_in_values

,where_to_put_the_valueinenumerate(index):what_value_to_put=values[idx_in_values]data[where_to_put_the_value

]=what_value_to_putdata,scattered(tensor([-1,-2,3,4,-3]),tensor([-1,-2,3,4,-3]))2D数据的PyTorch scatter例子

始终记住,index的形状与values的形状相关,而index中的值对应于data中的位置data=torch.zeros((4,4)).float()index=torch.tensor([[0,1

],[2,3],[0,3],[1,2]])values=torch.arange(1,9).float().view(4,2)values,data.scatter(1,index,values)(tensor

([[1.,2.],[3.,4.],[5.,6.],[7.,8.]]),tensor([[1.,2.,0.,0.],[0.,0.,3.,4.],[5.,0.,0.,6.],[0.,7.,8.,0.]]))

12 在网络中进行图像插值 (F.interpolate)当我学习PyTorch时,我惊讶地发现,实际上可以在前向传递中调整图像(或任何中间张量),并保持梯度流这种方法在使用CNN和GANs时特别有用# image from https://commons.wikimedia.org/wiki/File:A_female_British_Shorthair_at_the_age_of_20_months.jpg

img=Image.open("./cat.jpg")img

to_pil_image(F.interpolate(to_tensor(img).unsqueeze(0),# batch of size 1mode="bilinear",scale_factor=

2.0,align_corners=False).squeeze(0)# remove batch dimension)

看看梯度流是如何保存的:F.interpolate(to_tensor(img).unsqueeze(0).requires_grad_(),mode="bicubic",scale_factor=2.0

,align_corners=False)tensor([[[[0.9216,0.9216,0.9216,...,0.8361,0.8272,0.8219],[0.9214,0.9214,0.9214,

...,0.8361,0.8272,0.8219],[0.9212,0.9212,0.9212,...,0.8361,0.8272,0.8219],...,[0.9098,0.9098,0.9098,...

,0.3592,0.3486,0.3421],[0.9098,0.9098,0.9098,...,0.3566,0.3463,0.3400],[0.9098,0.9098,0.9098,...,0.3550

,0.3449,0.3387]],[[0.6627,0.6627,0.6627,...,0.5380,0.5292,0.5238],[0.6626,0.6626,0.6626,...,0.5380,0.5292

,0.5238],[0.6623,0.6623,0.6623,...,0.5380,0.5292,0.5238],...,[0.6196,0.6196,0.6196,...,0.3631,0.3525,

0.3461],[0.6196,0.6196,0.6196,...,0.3605,0.3502,0.3439],[0.6196,0.6196,0.6196,...,0.3589,0.3488,0.3426

]],[[0.4353,0.4353,0.4353,...,0.1913,0.1835,0.1787],[0.4352,0.4352,0.4352,...,0.1913,0.1835,0.1787],[

0.4349,0.4349,0.4349,...,0.1913,0.1835,0.1787],...,[0.3333,0.3333,0.3333,...,0.3827,0.3721,0.3657],[0.3333

,0.3333,0.3333,...,0.3801,0.3698,0.3635],[0.3333,0.3333,0.3333,...,0.3785,0.3684,0.3622]]]],grad_fn=<

UpsampleBicubic2DBackward1>)13 将图像做成网格 (torchvision.utils.make_grid)当使用PyTorch和torchvision时,不需要使用matplotlib或一些外部库来复制粘贴代码来显示图像网格。

只要使用torchvision.utils.make_grid就行了fromtorchvision.utilsimportmake_gridfromtorchvision.transforms.functional

importto_tensor,to_pil_imagefromPILimportImageimg=Image.open("./cat.jpg")to_pil_image(make_grid([to_tensor

(i)foriin[img,img,img]],nrow=2,# number of images in single rowpadding=5# "frame" size))

原文链接:https://zablo.net/blog/post/pytorch-13-features-you-should-know/机器学习/深度学习算法/自然语言处理交流群已建立机器学习算法-自然语言处理微信交流群!想要进交流群进行学习的同学,可以直接加我的微信号:

HIT_NLP加的时候备注一下:知乎+学校+昵称 (不加备注不会接受同意,望谅解),想进pytorch群,备注知乎+学校+昵称+Pytorch即可然后我们就可以拉你进群了群里已经有非得多国内外高校同学,交流氛围非常好。

强烈推荐大家关注机器学习算法与自然语言处理账号和机器学习算法与自然语言处理微信公众号,可以快速了解到最新优质的干货资源推荐阅读每日论文速递:自然语言处理相关(10月18日更新版) - 知乎 (zhihu.com)。

每日论文速递:计算机视觉相关(10月18日更新版) - 知乎 (zhihu.com)火爆全网,却只有4页!ICLR爆款论文「你只需要Patch」到底香不香? - 知乎 (zhihu.com)博士论文写不好?Barrett博士发超强攻略,手把手教你写论文 - 知乎 (zhihu.com)

ICLR 2022哪篇论文最火?这个「集邮」狂魔放出3400篇大礼包 - 知乎 (zhihu.com)一份来自1300+互联网公司的「996作息表」 - 知乎 (zhihu.com)每日论文速递:自然语言处理相关(10月15日更新版) - 知乎 (zhihu.com)

博士后招聘 | 清华NLP实验室招聘博士后 - 知乎 (zhihu.com)做个好审稿人吧!!! - 知乎 (zhihu.com)博后招聘 | 新加坡国立大学WING实验室招募自然语言处理方向博士后 - 知乎 (zhihu.com)

Swin Transformer获ICCV最佳论文奖-马尔奖 - 知乎 (zhihu.com)ACM Multimedia 2021“多模态任务中的小样本学习”讲习班将于10.24举行 - 知乎 (zhihu.com)

每日论文速递:计算机视觉相关(10月14日更新版) - 知乎 (zhihu.com)每日论文速递:自然语言处理相关(10月14日更新版) - 知乎 (zhihu.com)一文搞懂Transformers - 知乎 (zhihu.com)

每日论文速递:自然语言处理相关(10月12日更新版) - 知乎 (zhihu.com)每日论文速递:计算机视觉相关(10月12日更新版) - 知乎 (zhihu.com)博士申请 | CS@UNCCharlotte招收机器人/强化学习/控制博士[Spring/Fall22] - 知乎 (zhihu.com)

招聘 | AIR人工智能与生物计算教师/工程师/博士后/实习生 - 知乎 (zhihu.com)NLPer的核心竞争力是什么? - 知乎 (zhihu.com)ICCV 2021审稿结果出炉,有人已总结出了一份Rebuttal写作指南 - 知乎 (zhihu.com)

腾讯优图+厦门大学发布!2021十大人工智能趋势 - 知乎 (zhihu.com)2021下半年会议论文投稿时间小结与历年接受率回顾(欢迎收藏) - 知乎 (zhihu.com)深度学习中的Attention总结 - 知乎 (zhihu.com)


以上就是关于《13个你一定要知道的PyTorch特性_pytorch 硬件加速》的全部内容,本文网址:https://www.7ca.cn/baike/8214.shtml,如对您有帮助可以分享给好友,谢谢。
标签:
声明