PyTorch使用上的13个特性,确实非常的有用。
PyTorch在学术界和工业界的应用研究中都获得了很多关注。它是一个具有很大灵活性的深度学习框架,使用了大量的实用工具和函数来加快工作速度。PyTorch的学习曲线并不是那么陡峭,但在其中实现高效和干净的代码可能会很棘手。在使用它超过2年之后,以下是我最喜欢的PyTorch功能,我希望我一开始学习它就知道。 当学习PyTorch时,人们首先要做的事情之一是实现自己的某种 分类器最常见的数据格式之一,是有一个带有子文件夹的目录,子文件夹表示类,子文件夹中的文件表示样本,如下所示。 有一个内置的方式来加载这类数据集,不管你的数据是图像,文本文件或其他什么,只要使用' 如果你在处理图像,还有一个 我读过很多来自GitHub仓库的PyTorch代码。最让我恼火的是,几乎在每个repo中都有许多 显然,有些情况下你无法回避它,但大多数情况(如果不是全部)都在这里。其中一种情况是初始化一个全0或全1的张量,这在深度神经网络计算损失的的时候是经常发生的,模型的输出已经在cuda上了,你需要另外的tensor也是在cuda上,这时,你可以使用 在内部,PyTorch所做的是调用以下操作: 所以所有的设置都是正确的,这样就减少了代码中出现错误的概率。类似的操作包括: 这将是我劝人们不要到处使用 一旦注册,这些值就可以在forward函数中访问,就像其他模块的属性一样。 有时候,当你使用迁移学习时,你需要用1:1的映射替换一些层,可以用 例子,你想要在分类层之前从一个预训练过的 下次当你遇到计算两个张量之间的欧几里得距离(或者一般来说:p范数)的问题时,请记住 没有矩阵乘法或有矩阵乘法的性能,在我的机器上使用mm时,速度快了2倍以上。 867µs±142µs per loop (mean±std. dev. of 7 run, 1000 loop each) 417µs±52.9µs per loop (mean±std. dev. of 7 run, 1000 loop each) 与上一点相同,计算欧几里得距离并不总是你需要的东西。当处理向量时,通常余弦相似度是选择的度量。PyTorch也有一个内置的余弦相似度实现。 最后一点仍然与向量和距离有松散的联系,那就是归一化:通常是通过改变向量的大小来提高计算的稳定性。最常用的归一化是L2,可以在PyTorch中按如下方式应用: 在PyTorch中执行归一化的旧方法是: 这是我最近发现的一个有创意的技巧。假设你想把你的输入映射到N个不同的线性投影中。你可以通过创建N个 289 µs ± 30.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 202 µs ± 8.09 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 有时你只需要对输入张量的一部分进行计算。给你一个例子:你想计算的损失只在满足某些条件的张量上。为了做到这一点,你可以使用 类似的行为可以通过使用mask作为输入张量的 “indexer”来实现。 有时,一个理想的解决方案是用0填充mask中所有的 当你想把两个张量结合在一个条件下这个函数很有用,如果条件是真,那么从第一个张量中取元素,如果条件是假,从第二个张量中取元素。 这个函数的用例如下,你想用给定位置下另一个张量的值填充一个张量。一维张量更容易理解,所以我将先展示它,然后继续更高级的例子。 上面的例子很简单,但是现在看看如果将index改为 为什么最后一个值是-3,这是反直觉的,对吧?这是PyTorch 始终记住, 当我学习PyTorch时,我惊讶地发现,实际上可以在前向传递中调整图像(或任何中间张量),并保持梯度流。这种方法在使用CNN和GANs时特别有用。 看看梯度流是如何保存的: 当使用PyTorch和torchvision时,不需要使用matplotlib或一些外部库来复制粘贴代码来显示图像网格。只要使用
1. DatasetFolder
<span style="font-size: 15px;">Dataset</span>
。这是一个低级错误,没有必要浪费时间写这样的东西。通常,数据集要么是数据列表(或者是numpy数组),要么磁盘上的文件。所以,把数据在磁盘上组织好,要比写一个自定义的<span style="font-size: 15px;">Dataset</span>
来加载某种奇怪的格式更好。<span style="font-size: 15px;">DatasetFolder</span>
就可以了。令人惊讶的是,这个类是<span style="font-size: 15px;">torchvision</span>
包的一部分,而不是核心PyTorch。这个类非常全面,你可以从文件夹中过滤文件,使用自定义代码加载它们,并动态转换原始文件。例子:<span style="font-size: 15px;">torchvision.datasets.ImageFolder</span>
类,它基于<span style="font-size: 15px;">DatasetLoader</span>
,它被预先配置为加载图像。2. 尽量少用
<span style="font-size: 20px;">.to(device)</span>
,用 <span style="font-size: 20px;">zeros_like</span>
/ <span style="font-size: 20px;">ones_like</span>
之类的代替<span style="font-size: 15px;">*.to(device)</span>
行,它们将数据从CPU或GPU转移到其他地方。这样的语句通常会出现在大量的repos或初学者教程中。我强烈建议尽可能少地实现这类操作,并依赖内置的PyTorch功能自动实现这类操作。到处使用<span style="font-size: 15px;">.to(device)</span>
通常会导致性能下降,还会出现异常:
<span style="font-size: 15px;">*_like</span>
操作符:3. Register Buffer (
<span style="font-size: 20px;">nn.Module.register_buffer</span>
)<span style="font-size: 15px;">.to(device)</span>
的下一步。有时,你的模型或损失函数需要有预先设置的参数,并在调用<span style="font-size: 15px;">forward</span>
时使用,例如,它可以是一个“权重”参数,它可以缩放损失或一些固定张量,它不会改变,但每次都使用。对于这种情况,请使用<span style="font-size: 15px;">nn.Module.register_buffer</span>
方法,它告诉PyTorch将传递给它的值存储在模块中,并将这些值随模块一起移动。如果你初始化你的模块,然后将它移动到GPU,这些值也会自动移动。此外,如果你保存模块的状态,buffers也会被保存!4. Built-in
<span style="font-size: 20px;">Identity()</span>
<span style="font-size: 15px;">nn.Module</span>
来实现这个目的,只返回输入值。PyTorch内置了这个类。<span style="font-size: 15px;">ResNet50</span>
获取图像表示。以下是如何做到这一点:5. Pairwise distances:
<span style="font-size: 20px;">torch.cdist</span>
<span style="font-size: 15px;">torch.cdist</span>
。它确实做到了这一点,并且在使用欧几里得距离时还自动使用矩阵乘法,从而提高了性能。6. Cosine similarity:
<span style="font-size: 20px;">F.cosine_similarity</span>
PyTorch中批量计算余弦距离
7. 归一化向量:
<span style="font-size: 20px;">F.normalize</span>
在PyTorch中批量进行L2归一化
8. 线性层 + 分块技巧 (
<span style="font-size: 20px;">torch.chunk</span>
)<span style="font-size: 15px;">nn.Linear</span>
来做到这一点。或者你也可以创建一个单一的线性层,做一个向前传递,然后将输出分成N块。这种方法通常会带来更高的性能,所以这是一个值得记住的技巧。9. Masked select (
<span style="font-size: 20px;">torch.masked_select</span>
)<span style="font-size: 15px;">torch.masked_select</span>
,注意,当需要梯度时也可以使用这个操作。直接在tensor上应用mask
<span style="font-size: 15px;">False</span>
值,可以这样做:10. 使用
<span style="font-size: 20px;">torch.where</span>
来对tensors加条件11. 在给定的位置给张量填入值(
<span style="font-size: 20px;">Tensor.scatter</span>
)<span style="font-size: 15px;">index = torch.tensor([0, 1, 4])</span>
会发生什么:<span style="font-size: 15px;">scatter</span>
函数的中心思想。<span style="font-size: 15px;">index</span>
变量表示<span style="font-size: 15px;">data</span>
张量的第i个值应该放在<span style="font-size: 15px;">values</span>
张量的哪个位置。我希望下面的简单python版的这个操作能让你更明白:
2D数据的PyTorch scatter例子
<span style="font-size: 15px;">index</span>
的形状与<span style="font-size: 15px;">values</span>
的形状相关,而<span style="font-size: 15px;">index</span>
中的值对应于<span style="font-size: 15px;">data</span>
中的位置。12. 在网络中进行图像插值 (
<span style="font-size: 20px;">F.interpolate</span>
)13. 将图像做成网格 (
<span style="font-size: 20px;">torchvision.utils.make_grid</span>
)<span style="font-size: 15px;">torchvision.utils.make_grid</span>
就行了。
本文为原创文章,版权归知行编程网所有,欢迎分享本文,转载请保留出处!
内容反馈