Python 家族的深度学习框架有很多,比方:

  • TensorFlow
  • PyTorch
  • Keras
  • Theano
  • Lasagne

而 PyTorh 是其中体现十分好的一个,明天咱们就来开启 PyTorh 的入门之旅

什么是 PyTorch

它是一个基于 Python 的科学计算包,次要有两大特色:

  • 代替 NumPy,用以利用 GPU 的弱小计算性能
  • 领有最大灵活性和速度的深度学习钻研平台

PyTorch 的特点/亮点

  1. 对 Python 的原生反对及其库的应用
  2. 深度联合于 Facebook 的开发,以满足平台中的所有深度学习要求
  3. PyTorch 确保提供易于应用的 API,这有助于更换的应用和了解 API
  4. 动态图计算是 PyTorch 的一个次要亮点,能够确保在代码执行的每个点动静构建图形,并且能够在运行时进行操作
  5. PyTorch 速度快,因而能够确保轻松编码和疾速解决
  6. 对 CUDA 的反对确保代码能够在 GPU 上运行,从而缩小运行代码所需的工夫并进步零碎的整体性能

装置 PyTorch

在机器上装置 PyTorch 还是非常简单的

基于操作系统或包管理器等零碎属性,它能够从命令提示符或在 IDE(如 PyCharm 等)中间接装置

张量(Tensors)

Tensors 相似于 NumPy 的 n 维数组,此外 Tensors 也能够在 GPU 上进行减速计算

让咱们结构一个简略的 Tensors 并查看输入,首先让咱们看看如何构建一个 5×3 的未初始化矩阵:

x = torch.empty(5, 3)print(x)

Output:

tensor([[8.3665e+22, 4.5580e-41, 1.6025e-03],        [3.0763e-41, 0.0000e+00, 0.0000e+00],        [0.0000e+00, 0.0000e+00, 3.4438e-41],        [0.0000e+00, 4.8901e-36, 2.8026e-45],        [6.6121e+31, 0.0000e+00, 9.1084e-44]])

当初让咱们结构一个随机初始化的矩阵:

x = torch.rand(5, 3)print(x)

Output:

tensor([[0.1607, 0.0298, 0.7555],        [0.8887, 0.1625, 0.6643],        [0.7328, 0.5419, 0.6686],        [0.0793, 0.1133, 0.5956],        [0.3149, 0.9995, 0.6372]])

间接从数据结构张量:

x = torch.tensor([5.5, 3])print(x)

Output:

tensor([5.5000, 3.0000])

张量运算

张量运算操作有多种语法,在上面的例子中,咱们将看看加法运算:

y = torch.rand(5, 3)print(x + y)

Output:

tensor([[ 0.2349, -0.0427, -0.5053],            [ 0.6455,  0.1199,  0.4239],            [ 0.1279,  0.1105,  1.4637],            [ 0.4259, -0.0763, -0.9671],            [ 0.6856,  0.5047,  0.4250]])

调整大小:如果咱们想重塑/调整张量的大小,能够应用“torch.view”:

x = torch.randn(4, 4)y = x.view(16)z = x.view(-1, 8) # the size -1 is inferred from other dimensionsprint(x.size(), y.size(), z.size())

Output:

torch.Size([4, 4]) torch.Size([16]) torch.Size([2, 8])

NumPy

NumPy 是 Python 编程语言的库,减少了对大型、多维数组和矩阵的反对,以及用于对这些数组进行操作的大量高级数学函数汇合

Numpy 还有一下特定

  • 提供用于集成 C/C++ 和 FORTRAN 代码的工具
  • 具备线性代数、傅立叶变换和随机数性能的运算能力

除了显著的迷信用处外,NumPy 还能够用作通用数据的高效多维容器,也能够定义任意的数据类型

这使得 NumPy 能够无缝疾速地与各种数据库集成!

连贯 Array 和 Tensors 的桥梁

将 Torch Tensor 转换为 NumPy 数组,反之亦然是轻而易举

Torch Tensor 和 NumPy 数组将共享它们的底层内存地位,扭转一个将同时扭转另一个

将 Torch 张量转换为 NumPy 数组:

a = torch.ones(5)print(a)b = a.numpy()print(b)

Output:

tensor([1., 1., 1., 1., 1.])[1. 1. 1. 1. 1.]

上面让咱们执行求和运算并查看值的变动:

a.add_(1)print(a)print(b)

Output:

tensor([2., 2., 2., 2., 2.]) [2. 2. 2. 2. 2.]

将 NumPy 数组转换为 Torch 张量:

import numpy as noa = np.ones(5)b = torch.from_numpy(a)np.add(a, 1, out=a)print(a)print(b)

Output:

[2. 2. 2. 2. 2.]tensor([2., 2., 2., 2., 2.], dtype=torch.float64)

能够看到,Numpy 与 Torch 之间的互转还是十分不便的

实战--训练图像分类器

数据集抉择

通常,当咱们解决图像、文本、音频或视频数据时,能够应用规范的 Python 包将数据加载到 Numpy 数组中,而后就能够把这个数组转换成一个 torch.*Tensor

  • 对于图像,能够 Pillow 和 OpenCV
  • 对于音频,应用 Scipy 和 Librosa
  • 对于文本,原始 Python、基于 Cython 的加载或 NLTK 和 SpaCy 都能够

专门针对视觉,有一个名为 torchvision 的包,它实现了 Imagenet、CIFAR10、MNIST 等常见数据集的数据加载器和用于图像的数据转换器,这样咱们就能够很不便的应用已有数据集进行学习

在这里,咱们将应用 CIFAR10 数据集

它有类别:“飞机”、“汽车”、“鸟”、“猫”、“鹿”、“狗”、“青蛙”、“马”、“船”、“卡车”。 CIFAR-10 中的图像大小为3x32x32,即32×32像素大小的3通道彩色图像,如下图:

训练 CIFAR10 分类器

首先咱们加载和归一化 CIFAR10
应用 torchvision 加载

import torchimport torchvisionimport torchvision.transforms as transforms

torchvision 数据集的输入是范畴 [0, 1] 的 PILImage 图像,咱们将它们转换为归一化范畴 [-1, 1] 的张量

transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])trainset = torchvision.datasets.CIFAR10(root='./data', train=True,download=True, transform=transform)trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,shuffle=True, num_workers=2)testset = torchvision.datasets.CIFAR10(root='./data', train=False,download=True, transform=transform)testloader = torch.utils.data.DataLoader(testset, batch_size=4,shuffle=False, num_workers=2)classes = ('plane', 'car', 'bird', 'cat','deer', 'dog', 'frog', 'horse', 'ship', 'truck')

Output:

Downloading https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz to ./data/cifar-10-python.tar.gz Files already downloaded and verified 

接下来,咱们从数据集中打印一些训练图像

import matplotlib.pyplot as pltimport numpy as np # functions to show an image  def imshow(img):img = img / 2 + 0.5 # unnormalizenpimg = img.numpy()plt.imshow(np.transpose(npimg, (1, 2, 0)))  # get some random training imagesdataiter = iter(trainloader)images, labels = dataiter.next() # show imagesimshow(torchvision.utils.make_grid(images))# print labelsprint(' '.join('%5s' % classes[labels[j]] for j in range(4)))

Output:

dog  bird horse horse

上面咱们定义卷积神经网络
思考应用 3 通道图像(红色、绿色和蓝色)的状况,咱们定义 CNN 架构

import torch.nn as nnimport torch.nn.functional as F  class Net(nn.Module):def __init__(self):super(Net, self).__init__()self.conv1 = nn.Conv2d(3, 6, 5)self.pool = nn.MaxPool2d(2, 2)self.conv2 = nn.Conv2d(6, 16, 5)self.fc1 = nn.Linear(16 * 5 * 5, 120)self.fc2 = nn.Linear(120, 84)self.fc3 = nn.Linear(84, 10) def forward(self, x):x = self.pool(F.relu(self.conv1(x)))x = self.pool(F.relu(self.conv2(x)))x = x.view(-1, 16 * 5 * 5)x = F.relu(self.fc1(x))x = F.relu(self.fc2(x))x = self.fc3(x)return x  net = Net()

接下来定义损失函数和优化器

咱们应用 Cross-Entropy loss 和 SGD

事实上,Cross-Entropy Loss 是一个介于 0-1 之间的概率值,完满模型的穿插熵损失为 0,但也可能产生预期值为 0.2 但最终却失去 2 的状况,这将导致十分高的损失并且基本没有任何作用

import torch.optim as optim criterion = nn.CrossEntropyLoss()optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)

上面就能够训练神经网络了

咱们只须要遍历咱们的数据迭代器,并将输出提供给网络并进行优化

for epoch in range(2): # loop over the dataset multiple times running_loss = 0.0for i, data in enumerate(trainloader, 0):# get the inputsinputs, labels = data # zero the parameter gradientsoptimizer.zero_grad() # forward + backward + optimizeoutputs = net(inputs)loss = criterion(outputs, labels)loss.backward()optimizer.step() # print statisticsrunning_loss += loss.item()if i % 2000 == 1999: # print every 2000 mini-batchesprint('[%d, %5d] loss: %.3f' %(epoch + 1, i + 1, running_loss / 2000))running_loss = 0.0 print('Finished Training')

Output:

[1,  2000] loss: 2.236[1,  4000] loss: 1.880[1,  6000] loss: 1.676[1,  8000] loss: 1.586[1, 10000] loss: 1.515[1, 12000] loss: 1.464[2,  2000] loss: 1.410[2,  4000] loss: 1.360[2,  6000] loss: 1.360[2,  8000] loss: 1.325[2, 10000] loss: 1.312[2, 12000] loss: 1.302Finished Training

最初,在测试集上测试神经网络

咱们曾经在训练数据集上训练了 2 遍网络,然而还须要查看网络是否学到了什么货色

咱们将通过预测神经网络输入的类标签来查看这一点,并依据真实情况进行查看,如果预测正确,咱们将样本增加到正确预测列表中

第一步,让咱们展现一张来自测试集的图片

dataiter = iter(testloader)images, labels = dataiter.next() # print imagesimshow(torchvision.utils.make_grid(images))print('GroundTruth: ', ' '.join('%5s' % classes[labels[j]] for j in range(4)))

Output:

GroundTruth:    cat  ship  ship plane

第二步,应用神经网络进行预测

outputs = net(images)predicted = torch.max(outputs, 1) print('Predicted: ', ' '.join('%5s' % classes[predicted[j]]for j in range(4)))

outputs 输入是 10 个类别的权重,一个类别的权重越高,神经网络就越认为该图像属于该类别
Output:

Predicted:    cat   car   car plane

成果仿佛还不错

再接下来让咱们看看神经网络在整个数据集上的体现

correct = 0total = 0with torch.no_grad():for data in testloader:images, labels = dataoutputs = net(images)_, predicted = torch.max(outputs.data, 1)total += labels.size(0)correct += (predicted == labels).sum().item() print('Accuracy of the network on the 10000 test images: %d %%' % (100 * correct / total))

Output:

Accuracy of the network on the 10000 test images: 54 %

准确率还能够,比随机偶尔的10%(从 10 个类中随机抉择一个类)还是高出不少的

最初咱们再看下不同类别的准确率

class_correct = list(0. for i in range(10))class_total = list(0. for i in range(10))with torch.no_grad():for data in testloader:images, labels = dataoutputs = net(images)_, predicted = torch.max(outputs, 1)c = (predicted == labels).squeeze()for i in range(4):label = labels[i]class_correct[label] += c[i].item()class_total[label] += 1  for i in range(10):print('Accuracy of %5s : %2d %%' % (classes[i], 100 * class_correct[i] / class_total[i]))

Output:

Accuracy of plane : 61 %Accuracy of   car : 85 %Accuracy of  bird : 46 %Accuracy of   cat : 23 %Accuracy of  deer : 40 %Accuracy of   dog : 36 %Accuracy of  frog : 80 %Accuracy of horse : 59 %Accuracy of  ship : 65 %Accuracy of truck : 46 %

好了,明天的分享就到这里了,看到这里的敌人,如果你感觉称心请务必点个赞 + 在看 反对下,感激~

本文由mdnice多平台公布