深度学习框架pytorch
深度学习是Google,亚马逊,微软和Facebook以及众多小型公司业务的重要组成部分。 它负责自动语言翻译,图像分类和对话界面等领域的许多最新进展。
我们还没有到达一个单一的主导深度学习框架的地步。 TensorFlow (Google)很好,但是一直很难学习和使用。 而且TensorFlow的数据流图很难调试,这就是为什么TensorFlow项目一直致力于急切执行和TensorFlow调试器的原因 。 TensorFlow过去缺乏用于创建模型的高级API。 现在它有三个,包括定制的Keras版本。
CNTK (Microsoft)和Apache MXNet (Amazon)是TensorFlow的主要竞争对手,但还有其他框架要考虑。 Caffe (伯克利人工智能研究实验室)最初用于图像分类,后来扩展并更新为Caffe2 (Facebook等),并具有强大的生产能力。 Torch (Facebook,Twitter,Google等)使用Lua脚本和CUDA (计算机统一设备架构)C / C ++后端来有效解决机器学习,计算机视觉,信号处理和其他领域的问题。 尽管Lua具有脚本语言的优势,但当大多数深度学习社区采用Python时,Lua还是Torch的责任。
CUDA是Nvidia通用GPU的API。 GPU在深度神经网络的训练和预测方面比CPU快得多。 Google的TPU(张量处理单元)和FPGA(现场可编程门阵列)也可以在AWS,Microsoft Azure和其他地方使用。 在某些情况下,使用高级芯片(GPU,TPU或FPGA)可使每个CPU上的CPU速度提高50倍,从而将训练时间从数周缩短至数小时,或将数小时的训练时间从数小时缩短至数分钟。
PyTorch (Facebook,Twitter,Salesforce等)在Torch和Caffe2的基础上构建,使用Python作为其脚本语言,并开发了Torch CUDA后端。 Caffe2的生产功能-高度可扩展的执行引擎,加速的硬件支持,对移动设备的支持等-已合并到PyTorch项目中。
PyTorch被其开发人员称为“具有强大GPU加速功能的Python中的张量和动态神经网络”。 那是什么意思?
张量是一种数学构造,在物理学和工程学中大量使用。 二阶张量是一种特殊的矩阵。 取一个带有张量的向量的内积会产生另一个具有新大小和新方向的向量。 TensorFlow的名称来自张量(具有突触权重或节点之间的连接强度)在其网络模型中流动的方式。 NumPy还使用张量,但将它们称为n维数组( ndarray
)。
我们已经讨论过GPU加速。 动态神经网络是可以在迭代之间变化的网络。 例如,PyTorch中的动态神经网络模型可以在训练过程中添加和删除隐藏层,以提高其准确性和通用性。 PyTorch会在每个迭代步骤动态地重新创建图形。 相反,TensorFlow默认情况下会创建一个数据流图,优化图代码的性能,然后训练模型。
在TensorFlow中,急切的执行模式是一个相当新的选项,但这是PyTorch运行的唯一方式:API调用在调用时执行,而不是添加到图形中以便以后运行。 看来它的计算效率会降低,但是PyTorch就是按照这种方式工作的,并且在训练或预测速度上也不乏味。
在较高的层次上,PyTorch库包含以下组件:
包 | 描述 |
---|---|
torch |
像NumPy这样的张量库,具有强大的GPU支持。 |
torch.autograd |
基于磁带的自动微分库,支持火炬中所有可微分的张量操作。 |
torch.nn |
神经网络库与autograd高度集成,旨在最大程度地提高灵活性。 |
|
Python多处理,但跨进程的火炬张量具有神奇的内存共享。 对于数据加载和Hogwild培训很有用。 |
torch.utils |
为了方便起见,数据加载器,培训器和其他实用程序功能。 |
torch.legacy(.nn/.optim) |
由于向后兼容的原因而从火炬移植过来的旧代码。 |
PyTorch集成了加速库,例如英特尔MKL(数学内核库)和Nvidia cuDNN(CUDA深度神经网络)和NCCL(Nvidia集体通信)库,以最大化速度。 它的核心CPU和GPU张量和神经网络后端-TH(Torch),THC(Torch CUDA),THNN(Torch CUDA神经网络)和THCUNN(Torch CUDA神经网络)-被编写为具有C99 API的独立库。 同时,PyTorch并不是将Python绑定到整体C ++框架中,而是旨在与Python深度集成并允许使用其他Python库。
与Torch和某些替代方案相比,PyTorch中的内存使用效率很高。 其中一项优化是针对GPU的一组自定义内存分配器,因为可用的GPU内存通常会限制可以以GPU速度解决的深度学习模型的大小。
PyTorch对CUDA GPU的支持降至最基本的水平。 在下面的示例中,您将看到代码检测CUDA设备,在GPU上创建张量,将张量从CPU复制到GPU,在GPU上添加两个张量,打印结果,最后将结果从GPU复制到CPU使用不同的数据类型并打印结果。
# Let us run this cell only if CUDA is available
# We will use ``torch.device`` objects to move tensors in and out of GPU
if torch.cuda.is_available():
device = torch.device(“cuda”) # a CUDA device object
y = torch.ones_like(x, device=device) # directly create a tensor on GPU
x = x.to(device) # or just use strings ``.to(“cuda”)``
z = x + y
print (z)
print (z.to(“cpu”, torch.double)) # ``.to`` can also change dtype together!
Out:
tensor([ 1.9422], device=’cuda:0’)
tensor([ 1.9422], dtype=torch.float64)
在更高级别的场景中,您将在GPU上运行整个神经网络培训。 首先,您将如上所述检测第一个CUDA设备,并将所有模块从CPU张量转换为CUDA张量:
net.to(device) #this is a deep conversion of the whole neural network
您还必须将每一步的输入和目标也发送到GPU:
inputs, labels = inputs.to(device), labels.to(device)
基本上,您只需几行代码就可以将整个计算移至GPU。
使用多个GPU呢? DataParallel
是nn
神经网络类的一种方法,可自动拆分数据并将作业订单发送到多个GPU上的多个模型。 每个模型完成工作后, DataParallel
收集并合并结果,然后再将结果返回给您。
model = Model(input_size, output_size) # this is a neural network class
if torch.cuda.device_count() > 1: # can we go parallel?
print (“Let’s use”, torch.cuda.device_count(), “GPUs!”) # yes, we can
# dim = 0 [30, xxx] -> [10, ...], [10, ...], [10, ...] on 3 GPUs
model = nn.DataParallel(model) # use all available GPUs
model.to(device) # copy the model to the GPUs
PyTorch能够在张量变化时对张量进行快照,从而使您可以记录张量上的操作历史并在以后自动计算梯度。 通过在创建张量时设置requires_grad
属性来启用此功能:
x = torch.ones(2, 2, requires_grad=True)
随后需要张量的张量的后续操作可能会创建新的张量,这些张量将继承requires_grad
标志。 您可以随时使用requires_grad_(…)
方法在张量上更改requires_grad
标志。 在PyTorch,在一个方法的名称,如尾随下划线requires_grad_
装置,它在适当位置更新张量; 没有尾随下划线的方法会生成新的张量。
这些快照如何帮助计算梯度? 基本上,框架通过查看该点与先前张量之间的差异来近似每个已保存张量的梯度。 这种方法的准确性较差,但每个变量参数的效率大约是评估每个状态周围的增量以获得导数的三倍。 如果步长较小,则近似值不会太差。
在PyTorch,通过调用张量的计算使用反向传播(backprop)梯度backward()
方法, 如本动画 ,从神经网络的缓冲器清除任何现有梯度之后。 然后,您可以使用它来更新权重张量。 简而言之,PyTorch程序可以即时创建图形。 然后反向传播使用动态创建的图,根据保存的张量状态自动计算梯度。
用于查找最小误差的大多数权重更新规则(优化器)都以损失函数的梯度为初始方向来更改下一步骤的值,再乘以较小的学习率即可减小该步骤的幅度。 基本算法称为最速下降。 对于机器学习,通常的变体是随机梯度下降(SGD),它使用多批数据点,并且经常要遍历数据多次(历元)。
随机梯度下降的更高级版本(例如Adam和RMSprop )可以补偿偏差,随梯度的动量和速度折叠,平均梯度或使用自适应学习率。 PyTorch目前支持10种优化方法。
torch.nn
类定义模块和其他容器,模块参数,11种层,17种损失函数,20种激活函数和两种距离函数。 每种层都有许多变体,例如六个卷积层和18个池化层。
torch.nn.functional
类定义了11类功能。 令人困惑的是, torch.nn
和torch.nn.functional
都包含丢失和激活成员函数。 但是,在许多情况下, torch.nn
成员不过是相应的torch.nn.functional
成员的包装器。
您可以将自己的自定义模型定义为nn.Module
子类。 例如:
import torch.nn as nn
import torch.nn.functional as F
class Model (nn.Module):
def __init__(self):
super(Model, self).__init__()
self.conv1 = nn.Conv2d(1, 20, 5)
self.conv2 = nn.Conv2d(20, 20, 5)
def forward(self, x):
x = F.relu(self.conv1(x))
return F.relu(self.conv2(x))
这个非常简单的模型具有两个2D卷积层,并且对两个层都使用了整流线性单位(ReLU)激活函数。 nn.Conv2d
的三个参数是输入通道数,输出通道数和卷积内核的大小。
您还可以使用容器模块之一将图层分组为模型。 nn.Sequential
容器按照在构造函数中列出的顺序添加模块:
# Example of using Sequential
model = nn.Sequential(
nn.Conv2d(1,20,5),
nn.ReLU(),
nn.Conv2d(20,64,5),
nn.ReLU()
)
# Example of using Sequential with OrderedDict
model = nn.Sequential(OrderedDict([
(‘conv1’, nn.Conv2d(1,20,5)),
(‘relu1’, nn.ReLU()),
(‘conv2’, nn.Conv2d(20,64,5)),
(‘relu2’, nn.ReLU())
]))
nn.ModuleList
容器非常适合您要从代码生成可枚举的图层列表的情况。 例如,看一下10个线性层的用法:
class MyModule (nn.Module):
def __init__(self):
super(MyModule, self).__init__()
self.linears = nn.ModuleList([nn.Linear(10, 10) for i in range(10)])
def forward(self, x):
# ModuleList can act as an iterable, or be indexed using ints
for i, l in enumerate(self.linears):
x = self.linears[i // 2](x) + l(x)
return x
pytorch / examples回购包含使用卷积神经网络进行MNIST数字分类的可行模型; 使用LSTM RNN进行词级语言建模; 使用残差网络进行ImageNet图像分类; 使用深度卷积生成对抗网络(DCGAN)进行LSUN场景理解; 可变自动编码器网络; 使用高效的亚像素卷积神经网络进行图像超分辨率; 利用感知损失功能进行艺术风格的转移; 在演员评论模型中训练CartPole平衡OpenAI Gym; SNLI自然语言推理与单词表示全球向量( 手套 ),LSTMs和torchtext; 使用LSTM进行时间序列预测(正弦波信号值)。
翻译自: https://www.infoworld.com/article/3289633/pytorch-review-a-deep-learning-framework-built-for-speed.html
深度学习框架pytorch