PyTorch深度学习简介

深度学习图像算法 2018-10-06

PyTorch深度学习简介

在本教程中,将使用PyTorch框架介绍深度学习,并通过其结论,您可以轻松地将其应用于您的深度学习模型。Facebook今年早些时候推出了PyTorch 1.0,集成了Google Cloud, AWS和Azure Machine Learning。在本教程中,我假设您已熟悉Scikit-learn,Pandas,NumPy和SciPy。这些包是本教程的重要先决条件。

什么是深度学习?

深度学习是机器学习的一个子领域,其算法受到人类大脑工作的启发。这些算法称为人工神经网络。这些神经网络的示例包括用于图像分类的卷积神经网络,人工神经网络和循环神经网络。

PyTorch简介

PyTorch是一个基于Torch的Python机器学习包,它是一个基于编程语言Lua的开源机器学习包。PyTorch有两个主要特征:

  • 具有强大的GPU加速度的张量计算(如NumPy)
  • 自动微分建立和训练神经网络

为什么你可能更喜欢PyTorch而不是其他Python深度学习库

有几个原因你可能更喜欢PyTorch而不是其他深度学习库:

  • 与TensorFlow等其他库不同,在运行模型之前必须先定义整个计算图,PyTorch允许动态定义图。
  • PyTorch也非常适合深度学习研究,并提供最大的灵活性和速度。

PyTorch Tensors

PyTorch Tensors与NumPy数组非常相似,并且可以在GPU上运行。这很重要,因为它有助于加速数值计算,这可以将神经网络的速度提高50倍或更多。要使用PyTorch,您需要转到https://PyTorch.org/并安装PyTorch。如果你正在使用Conda,你可以通过运行这个简单的命令来安装PyTorch:

conda install PyTorch torchvision -c PyTorch

为了定义PyTorch张量,首先要导入torch包。PyTorch允许您定义两种类型的张量 - CPU和GPU张量。对于本教程,我假设您正在运行CPU机器,但我还将向您展示如何在GPU中定义张量:

import torch

PyTorch的默认张量类型是一个浮点张量,定义为torch.FloatTensor。例如,您将从Python list中创建一个张量:

torch.FloatTensor([[20, 30, 40], [90, 60, 70]])

如果您使用的是支持GPU的计算机,则可以定义张量,Python代码如下所示:

torch.cuda.FloatTensor([[20, 30, 40], [90, 60, 70]])

您还可以使用PyTorch张量执行数学计算,例如加法和减法:

x = torch.FloatTensor([25])
y = torch.FloatTensor([30])
x + y

您还可以定义矩阵并执行矩阵运算。让我们看看如何定义矩阵并对其进行转置:

matrix = torch.randn(4, 5)
matrix
matrix.t()

PyTorch Autograd

PyTorch使用一种称为自动微分的技术,该技术在数值上评估函数的导数。自动微分计算神经网络中的Backward pass。在训练神经网络中,权重被随机初始化为接近零但不为零的数字。Backward pass是从右到左调整这些权重的过程,而forward pass是反向(从左到右)。

torch.autograd是支持PyTorch中自动微分库。这个包的核心类是torch.Tensor。要跟踪它上的所有操作,请将.requires_grad设置为True。要计算梯度,调用 .backward() 。这个张量的梯度将累积在.grad属性中。

如果希望从计算历史中分离一个张量,请调用.detach()函数。这也将防止将来对张量的计算被跟踪。另一种防止历史跟踪的方法是用torch.no_grad():

在Tensor和Function 类是相互连接的,以构建一个非循环图,对计算的完整历史进行编码。张量的.grad_fn 属性引用了创建这个张量的函数。要计算梯度,调用 .backward() 。如果张量包含多个元素,指定一个梯度,它是一个形状匹配的张量。

例如,您将创建两个张量,一个用requires_grad as True和另一个False。然后,您将使用这两个张量来执行加法和求和运算。然后,计算其中一个张量的梯度。

a = torch.tensor([3.0, 2.0], requires_grad=True)
b = torch.tensor([4.0, 7.0])
ab_sum = a + b
ab_sum
ab_res = (ab_sum*8).sum()
ab_res.backward()
ab_res
a.grad

在b上调用.grad将不会返回任何东西,因为您没有在它上设置requires_grad为True。

PyTorch nn模块

这是在PyTorch中构建神经网络的模块。nn取决于autograd定义模型并区分它们。让我们从定义训练神经网络的过程开始:

  1. 使用一些可学习的参数定义神经网络,称为权重。
  2. 迭代输入数据集。
  3. 通过网络处理输入。
  4. 将预测结果与实际值进行比较并测量误差。
  5. 将梯度传播回网络的参数中。
  6. 使用简单的更新规则更新网络权重:

weight = weight — learning_rate * gradient

您现在将使用该nn包创建一个two-layer神经网络:

N, D_in, H, D_out = 64, 1000, 100, 10
x = torch.randn(N, D_in)
y = torch.randn(N, D_out)
model = torch.nn.Sequential(
torch.nn.Linear(D_in, H),
torch.nn.ReLU(),
torch.nn.Linear(H, D_out),
)
loss_fn = torch.nn.MSELoss()
learning_rate = 1e-4

让我们解释一下上面使用的一些参数:

  • N是批量大小。批量大小是在观察数量之后更新权重。
  • D_in 是输入维度
  • H 是隐藏的维度
  • D_out 是输出维度
  • torch.randn 定义指定尺寸的矩阵
  • torch.nn.Sequential 初初始化层的线性堆栈
  • torch.nn.Linear 对输入数据应用线性变换
  • torch.nn.ReLU 按元素应用relu函数
  • torch.nn.MSELoss 创建一个衡量输入x和目标y中n个元素之间的均方误差的标准

PyTorch optim Package

接下来,您将使用optim包定义一个优化器,该优化器将为您更新权重。optim包抽象了优化算法的思想,并提供了常用的优化算法的实现,如AdaGrad、RMSProp和Adam。我们将使用Adam优化器,它是最流行的优化器之一。

这个优化器采用的第一个参数是张量,它应该更新。在forward pass中,您将通过将x传递给模型来计算预测的y。之后,计算并打印损失。在运行backward pass之前,将使用优化器更新的变量的所有梯度设置为零。这样做是因为默认情况下,调用.backward() 时不会覆盖渐变 。然后,在优化器上调用step函数,并更新其参数。Python实现下所示

optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
for t in range(500):
 y_pred = model(x)
 loss = loss_fn(y_pred, y)
 print(t, loss.item())
 optimizer.zero_grad()
 loss.backward()
 optimizer.step()

PyTorch深度学习简介

PyTorch中的自定义nn模块

有时您需要构建自己的自定义模块。在这些情况下,你将继承子类nn.Module。然后,您需要定义一个forward,它将接收输入张量并产生输出张量。如何使用nn.Module实现two-layer网络如下所示。这个模型与上面的模型非常相似,但不同之处在于您将使用torch.nn.Module创建神经网络。另一个区别是使用随机梯度下降优化器而不是Adam。您可以实现自定义nn模块,如下所示:

import torch
class TwoLayerNet(torch.nn.Module):
 def __init__(self, D_in, H, D_out):
 super(TwoLayerNet, self).__init__()
 self.linear1 = torch.nn.Linear(D_in, H)
 self.linear2 = torch.nn.Linear(H, D_out)
 def forward(self, x):
 h_relu = self.linear1(x).clamp(min=0)
 y_pred = self.linear2(h_relu)
 return y_pred
N, D_in, H, D_out = 64, 1000, 100, 10
x = torch.randn(N, D_in)
y = torch.randn(N, D_out)
model = TwoLayerNet(D_in, H, D_out)
criterion = torch.nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=1e-4)
for t in range(500):
 y_pred = model(x)
 loss = criterion(y_pred, y)
 print(t, loss.item())
 optimizer.zero_grad()
 loss.backward()
 optimizer.step()

PyTorch深度学习简介

最后

PyTorch允许您实现不同类型的层,例如卷积层, 循环层和线性层等。您可以从官方文档中了解有关PyTorch的更多信息。

相关推荐