深度学习图像算法 2018-10-06
在本教程中,将使用PyTorch框架介绍深度学习,并通过其结论,您可以轻松地将其应用于您的深度学习模型。Facebook今年早些时候推出了PyTorch 1.0,集成了Google Cloud, AWS和Azure Machine Learning。在本教程中,我假设您已熟悉Scikit-learn,Pandas,NumPy和SciPy。这些包是本教程的重要先决条件。
深度学习是机器学习的一个子领域,其算法受到人类大脑工作的启发。这些算法称为人工神经网络。这些神经网络的示例包括用于图像分类的卷积神经网络,人工神经网络和循环神经网络。
PyTorch是一个基于Torch的Python机器学习包,它是一个基于编程语言Lua的开源机器学习包。PyTorch有两个主要特征:
有几个原因你可能更喜欢PyTorch而不是其他深度学习库:
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使用一种称为自动微分的技术,该技术在数值上评估函数的导数。自动微分计算神经网络中的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取决于autograd定义模型并区分它们。让我们从定义训练神经网络的过程开始:
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
让我们解释一下上面使用的一些参数:
接下来,您将使用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()
有时您需要构建自己的自定义模块。在这些情况下,你将继承子类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的更多信息。