Урок за PyTorch

Резюме на урока по Pytorch

В този урок по pytorch ще научите всички концепции от нулата. Този урок обхваща основни до напреднали теми като дефиниция на pytorch, предимства и недостатъци на pytorch, сравнение, инсталиране, рамка на pytorch, регресия и класификация на изображения. Този урок по pytorch е абсолютно безплатен.

Какво е PyTorch?

PyTorch е базирана на Torch библиотека с отворен код за машинно обучение за използване на обработка на естествен език Python. Той е подобен на NumPy, но с мощна GPU поддръжка. Той предлага динамични изчислителни графики, които можете да променяте в движение с помощта на autograd. PyTorch също е по-бърз от някои други рамки. Той е разработен от изследователската група за изкуствен интелект на Facebook през 2016 г.

Предимства и недостатъци на PyTorch

Следват предимствата и недостатъците на PyTorch:

Предимства на PyTorch

  1. Проста библиотека
    Кодът на PyTorch е прост. Лесно е за разбиране и вие използвате библиотеката незабавно. Например, разгледайте кодовия фрагмент по-долу:
class Net(torch.nn.Module):
   def __init__(self):
       super(Net, self).__init__()
       self.layer = torch.nn.Linear(1, 1)

   def forward(self, x):
       x = self.layer(x)      
       return x

Както бе споменато по-горе, можете лесно да дефинирате мрежовия модел и можете да разберете кода бързо без много обучение.

  1. Динамична изчислителна графика

Динамична изчислителна графика

Източник на изображението: Изследване на задълбочено обучение с PyTorch

Pytorch предлага Dynamic Computational Graph (DAG). Изчислителните графики са начин за изразяване на математически изрази в графични модели или теории като възли и ръбове. Възелът ще извърши математическата операция, а ръбът е тензор, който ще бъде подаден във възлите и ще носи изхода на възела в тензора.

DAG е графика, която поддържа произволна форма и може да извършва операции между различни входни графики. При всяка итерация се създава нова графика. Така че е възможно да имаме същата структура на графиката или да създадем нова графика с различна операция, или можем да я наречем динамична графика.

  1. По-добро представяне

Общности и изследователи, сравните и сравнете рамки, за да видите коя е по-бърза. Репо GitHub Бенчмарк за Deep Learning Frameworks и GPU съобщи, че PyTorch е по-бърз от другата рамка по отношение на изображенията, обработвани за секунда.

Както можете да видите по-долу, сравнителните графики с vgg16 и resnet152

Предимства на PyTorch

Предимства на PyTorch

  1. Роден Python

PyTorch е по-базиран на python. Например, ако искате да обучите модел, можете да използвате собствен контролен поток, като цикъл и рекурсии, без да е необходимо да добавяте повече специални променливи или сесии, за да можете да ги изпълнявате. Това е много полезно за процеса на обучение.

Pytorch също така прилага императивно програмиране и определено е по-гъвкав. Така че е възможно да се отпечата стойността на тензора в средата на изчислителен процес.

Недостатък на PyTorch

PyTorch изисква приложения на трети страни за визуализация. Той също така се нуждае от API сървър за производство.

След това в този урок за PyTorch ще научим за разликата между PyTorch и TensorFlow.

PyTorch Vs. Tensorflow

Параметър PyTorch Тензорен поток
Определение на модела Моделът е дефиниран в подклас и предлага лесен за използване пакет Моделът е дефиниран с много и трябва да разберете синтаксиса
GPU Поддръжка Да Да
Тип графика Динамичен Статичен
Инструменти Няма инструмент за визуализация Можете да използвате инструмента за визуализация Tensorboard
общност Общността все още расте Големи активни общности

Инсталиране на PyTorch

Linux

Лесно е да го инсталирате в Linux. Можете да изберете да използвате виртуална среда или да я инсталирате директно с root достъп. Въведете тази команда в терминала

pip3 install --upgrade torch torchvision

AWS Sagemaker

Sagemaker е една от платформите в Amazon Уеб сервиз който предлага мощен двигател за машинно обучение с предварително инсталирани конфигурации за дълбоко обучение за специалисти по данни или разработчици за изграждане, обучение и внедряване на модели във всякакъв мащаб.

Първо отворете Amazon Sagemaker конзола и щракнете върху Създаване на екземпляр на бележник и попълнете всички подробности за вашия бележник.

AWS Sagemaker

Следващата стъпка, щракнете върху Отвори, за да стартирате екземпляра на вашия бележник.

AWS Sagemaker

Накрая, In Jupyter, Щракнете върху Нов и изберете conda_pytorch_p36 и сте готови да използвате вашия екземпляр на бележник с инсталиран Pytorch.

След това в този урок за PyTorch ще научим за основите на рамката на PyTorch.

Основи на PyTorch Framework

Нека научим основните концепции на PyTorch, преди да се потопим дълбоко. PyTorch използва Tensor за всяка променлива, подобна на ndarray на numpy, но с поддръжка на GPU изчисления. Тук ще обясним мрежовия модел, функцията за загуба, Backprop и Optimizer.

Мрежов модел

Мрежата може да бъде изградена чрез подкласиране на torch.nn. Има 2 основни части,

  1. Първата част е да дефинирате параметрите и слоевете, които ще използвате
  2. Втората част е основната задача, наречена напредващ процес, който ще приеме вход и ще предвиди изхода.
Import torch
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(3, 20, 5)
        self.conv2 = nn.Conv2d(20, 40, 5)
self.fc1 = nn.Linear(320, 10)

def forward(self, x):
       x = F.relu(self.conv1(x))
       x = F.relu(self.conv2(x))
       x = x.view(-1, 320)
       x = F.relu(self.fc1(x))
       return F.log_softmax(x)

net = Model()

Както можете да видите по-горе, създавате клас от nn.Module, наречен Model. Съдържа 2 Conv2d слоя и линеен слой. Първият слой conv2d приема вход 3 и изходна форма 20. Вторият слой ще приема вход 20 и ще произведе изходна форма 40. Последният слой е напълно свързан слой във формата 320 и ще произведе изход от 10.

Процесът напред ще вземе вход от X и ще го подаде към слоя conv1 и ще изпълни ReLU функция,

По същия начин ще захранва и слоя conv2. След това x ще бъде преоформен в (-1, 320) и ще бъде подаден във финалния FC слой. Преди да изпратите изхода, ще използвате функцията за активиране на softmax.

Процесът назад се дефинира автоматично от autograd, така че трябва да дефинирате само процеса напред.

Функция загуба

Функцията на загубата се използва за измерване на това доколко моделът за прогнозиране е в състояние да предвиди очакваните резултати. PyTorch вече има много стандартни функции за загуба в модула torch.nn. Например, можете да използвате загубата на кръстосана ентропия, за да решите проблем с класификацията на PyTorch от няколко класа. Лесно е да се дефинира функцията на загубата и да се изчислят загубите:

loss_fn = nn.CrossEntropyLoss()

#training process
loss = loss_fn(out, target)

Лесно е да използвате собственото си изчисление на функцията за загуба с PyTorch.

Подпора

За да извършите обратното разпространение, просто извиквате los.backward(). Грешката ще бъде изчислена, но не забравяйте да изчистите съществуващия градиент с zero_grad()

net.zero_grad() # to clear the existing gradient
loss.backward() # to perform backpropragation

Optimizer

Torch.optim предоставя общи алгоритми за оптимизация. Можете да дефинирате оптимизатор с една проста стъпка:

optimizer = torch.optim.SGD(net.parameters(), lr = 0.01, momentum=0.9)

Трябва да предадете параметрите на мрежовия модел и скоростта на обучение, така че при всяка итерация параметрите да се актуализират след процеса на backprop.

Проста регресия с PyTorch

Нека научим проста регресия с примери на PyTorch:

Стъпка 1) Създаване на нашия мрежов модел

Нашият мрежов модел е прост линеен слой с входна и изходна форма 1.

from __future__ import print_function

import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable

class Net(nn.Module):
   def __init__(self):
       super(Net, self).__init__()
       self.layer = torch.nn.Linear(1, 1)

   def forward(self, x):
       x = self.layer(x)      
       return x

net = Net()
print(net)

И мрежовият изход трябва да бъде такъв

Net(
  (hidden): Linear(in_features=1, out_features=1, bias=True)
)

Стъпка 2) Тестови данни

Преди да започнете процеса на обучение, трябва да знаете нашите данни. Вие правите произволна функция, за да тествате нашия модел. Y = x3 sin(x)+ 3x+0.8 rand(100)

# Visualize our data
import matplotlib.pyplot as plt
import numpy as np

x = np.random.rand(100)
y = np.sin(x) * np.power(x,3) + 3*x + np.random.rand(100)*0.8

plt.scatter(x, y)
plt.show()

Ето диаграмата на разсейване на нашата функция:

Точкова диаграма на проста регресия с PyTorch

Преди да започнете процеса на обучение, трябва да преобразувате масива numpy в променливи, които се поддържат от Torch и autograd, както е показано в примера за регресия на PyTorch по-долу.

# convert numpy array to tensor in shape of input size
x = torch.from_numpy(x.reshape(-1,1)).float()
y = torch.from_numpy(y.reshape(-1,1)).float()
print(x, y)

Стъпка 3) Оптимизатор и загуба

След това трябва да дефинирате оптимизатора и функцията за загуба за нашия процес на обучение.

# Define Optimizer and Loss Function
optimizer = torch.optim.SGD(net.parameters(), lr=0.2)
loss_func = torch.nn.MSELoss()

Стъпка 4) Обучение

Сега нека започнем нашия процес на обучение. С епоха от 250 ще повторите нашите данни, за да намерите най-добрата стойност за нашите хиперпараметри.

inputs = Variable(x)
outputs = Variable(y)
for i in range(250):
   prediction = net(inputs)
   loss = loss_func(prediction, outputs) 
   optimizer.zero_grad()
   loss.backward()        
   optimizer.step()       

   if i % 10 == 0:
       # plot and show learning process
       plt.cla()
       plt.scatter(x.data.numpy(), y.data.numpy())
       plt.plot(x.data.numpy(), prediction.data.numpy(), 'r-', lw=2)
       plt.text(0.5, 0, 'Loss=%.4f' % loss.data.numpy(), fontdict={'size': 10, 'color':  'red'})
       plt.pause(0.1)

plt.show()

Стъпка 5) Резултат

Както можете да видите по-долу, успешно извършихте регресия на PyTorch с невронна мрежа. Всъщност при всяка итерация червената линия в диаграмата ще се актуализира и ще промени позицията си, за да пасне на данните. Но на тази снимка ви показва само крайния резултат, както е показано в примера на PyTorch по-долу:

Точкова диаграма на резултат от проста регресия

Пример за класификация на изображението с PyTorch

Един от популярните методи за изучаване на основите дълбоко учене е с набора от данни на MNIST. Това е „Здравей свят“ в дълбокото обучение. Наборът от данни съдържа ръкописни числа от 0 до 9 с общо 60,000 10,000 тренировъчни проби и 28 28 тестови проби, които вече са етикетирани с размер XNUMX × XNUMX пиксела.

Класификация на изображения с PyTorch

Стъпка 1) Предварителна обработка на данните

В първата стъпка от този пример за класификация на PyTorch ще заредите набора от данни с помощта на модул torchvision.

Преди да започнете процеса на обучение, трябва да разберете данните. Torchvision ще зареди набора от данни и ще трансформира изображенията с подходящото изискване за мрежата, като формата и нормализиране на изображенията.

import torch
import torchvision
import numpy as np
from torchvision import datasets, models, transforms

# This is used to transform the images to Tensor and normalize it
transform = transforms.Compose(
   [transforms.ToTensor(),
    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

training = torchvision.datasets.MNIST(root='./data', train=True,
                                       download=True, transform=transform)
train_loader = torch.utils.data.DataLoader(training, batch_size=4,
                                         shuffle=True, num_workers=2)

testing = torchvision.datasets.MNIST(root='./data', train=False,
                                      download=True, transform=transform)
test_loader = torch.utils.data.DataLoader(testing, batch_size=4,
                                        shuffle=False, num_workers=2)

classes = ('0', '1', '2', '3',
          '4', '5', '6', '7', '8', '9')
         
import matplotlib.pyplot as plt
import numpy as np

#create an iterator for train_loader
# get random training images
data_iterator = iter(train_loader)
images, labels = data_iterator.next()

#plot 4 images to visualize the data
rows = 2
columns = 2
fig=plt.figure()
for i in range(4):
   fig.add_subplot(rows, columns, i+1)
   plt.title(classes[labels[i]])
   img = images[i] / 2 + 0.5     # this is for unnormalize the image
   img = torchvision.transforms.ToPILImage()(img)
   plt.imshow(img)
plt.show()

Функцията за преобразуване преобразува изображенията в тензор и нормализира стойността. Функцията torchvision.transforms.MNIST ще изтегли набора от данни (ако не е наличен) в директорията, ще зададе набора от данни за обучение, ако е необходимо, и ще извърши процеса на трансформация.

За да визуализирате набора от данни, използвате data_iterator, за да получите следващата партида изображения и етикети. Използвате matplot, за да начертаете тези изображения и подходящия им етикет. Както можете да видите по-долу нашите изображения и техните етикети.

Пример за класификация на изображението с PyTorch

Стъпка 2) Конфигурация на мрежовия модел

Сега в този пример на PyTorch ще направите проста невронна мрежа за класификация на изображения на PyTorch.

Тук ви представяме друг начин за създаване на мрежов модел в PyTorch. Ще използваме nn.Sequential, за да направим модел на последователност, вместо да направим подклас на nn.Module.

import torch.nn as nn

# flatten the tensor into 
class Flatten(nn.Module):
   def forward(self, input):
       return input.view(input.size(0), -1)

#sequential based model
seq_model = nn.Sequential(
           nn.Conv2d(1, 10, kernel_size=5),
           nn.MaxPool2d(2),
           nn.ReLU(),
           nn.Dropout2d(),
           nn.Conv2d(10, 20, kernel_size=5),
           nn.MaxPool2d(2),
           nn.ReLU(),
           Flatten(),
           nn.Linear(320, 50),
           nn.ReLU(),
           nn.Linear(50, 10),
           nn.Softmax(),
         )

net = seq_model
print(net)

Ето резултата от нашия мрежов модел

Sequential(
  (0): Conv2d(1, 10, kernel_size=(5, 5), stride=(1, 1))
  (1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (2): ReLU()
  (3): Dropout2d(p=0.5)
  (4): Conv2d(10, 20, kernel_size=(5, 5), stride=(1, 1))
  (5): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (6): ReLU()
  (7): Flatten()
  (8): Linear(in_features=320, out_features=50, bias=True)
  (9): ReLU()
  (10): Linear(in_features=50, out_features=10, bias=True)
  (11): Softmax()
)

Мрежово обяснение

  1. Последователността е, че първият слой е Conv2D слой с входна форма 1 и изходна форма 10 с размер на ядрото 5
  2. След това имате слой MaxPool2D
  3. Функция за активиране на ReLU
  4. слой Dropout за премахване на стойности с ниска вероятност.
  5. След това втори Conv2d с входна форма 10 от последния слой и изходна форма 20 с размер на ядрото 5
  6. Следва слой MaxPool2d
  7. Функция за активиране на ReLU.
  8. След това ще изравните тензора, преди да го подадете в линейния слой
  9. Линеен слой ще картографира нашия изход във втория линеен слой с функция за активиране на softmax

Стъпка 3) Обучете модела

Преди да започнете процеса на обучение, е необходимо да настроите функцията за критерий и оптимизатор.

За критерия ще използвате CrossEntropyLoss. За оптимизатора ще използвате SGD със скорост на обучение от 0.001 и импулс от 0.9, както е показано в примера на PyTorch по-долу.

import torch.optim as optim

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

Процесът напред ще вземе входната форма и ще я предаде на първия слой conv2d. След това оттам ще бъде подаден в maxpool2d и накрая ще бъде поставен във функцията за активиране на ReLU. Същият процес ще се случи във втория слой conv2d. След това входът ще бъде преоформен в (-1,320) и ще бъде подаден в fc слоя, за да се предвиди изхода.

Сега ще започнете процеса на обучение. Ще преминете през нашия набор от данни 2 пъти или с епоха от 2 и ще отпечатате текущата загуба на всяка партида от 2000.

for epoch in range(2): 

#set the running loss at each epoch to zero
   running_loss = 0.0
# we will enumerate the train loader with starting index of 0
# for each iteration (i) and the data (tuple of input and labels)
   for i, data in enumerate(train_loader, 0):
       inputs, labels = data

# clear the gradient
       optimizer.zero_grad()

#feed the input and acquire the output from network
       outputs = net(inputs)

#calculating the predicted and the expected loss
       loss = criterion(outputs, labels)

#compute the gradient
       loss.backward()

#update the parameters
       optimizer.step()

       # print statistics
       running_loss += loss.item()
       if i % 1000 == 0:
           print('[%d, %5d] loss: %.3f' %
                 (epoch + 1, i + 1, running_loss / 1000))
           running_loss = 0.0

Във всяка епоха изброителят ще получи следващия кортеж от входни данни и съответните етикети. Преди да подадем входа към нашия мрежов модел, трябва да изчистим предишния градиент. Това е необходимо, защото след обратния процес (процес на обратно разпространение), градиентът ще бъде натрупан, вместо да бъде заменен. След това ще изчислим загубите от прогнозираната продукция от очакваната продукция. След това ще направим обратно разпространение, за да изчислим градиента, и накрая ще актуализираме параметрите.

Ето резултата от процеса на обучение

[1, 	1] loss: 0.002
[1,  1001] loss: 2.302
[1,  2001] loss: 2.295
[1,  3001] loss: 2.204
[1,  4001] loss: 1.930
[1,  5001] loss: 1.791
[1,  6001] loss: 1.756
[1,  7001] loss: 1.744
[1,  8001] loss: 1.696
[1,  9001] loss: 1.650
[1, 10001] loss: 1.640
[1, 11001] loss: 1.631
[1, 12001] loss: 1.631
[1, 13001] loss: 1.624
[1, 14001] loss: 1.616
[2, 	1] loss: 0.001
[2,  1001] loss: 1.604
[2,  2001] loss: 1.607
[2,  3001] loss: 1.602
[2,  4001] loss: 1.596
[2,  5001] loss: 1.608
[2,  6001] loss: 1.589
[2,  7001] loss: 1.610
[2,  8001] loss: 1.596
[2,  9001] loss: 1.598
[2, 10001] loss: 1.603
[2, 11001] loss: 1.596
[2, 12001] loss: 1.587
[2, 13001] loss: 1.596
[2, 14001] loss: 1.603

Стъпка 4) Тествайте модела

След като обучите нашия модел, трябва да тествате или оцените с други набори от изображения.

Ще използваме итератор за test_loader и той ще генерира пакет от изображения и етикети, които ще бъдат предадени на обучения модел. Прогнозираният резултат ще бъде показан и сравнен с очаквания резултат.

#make an iterator from test_loader
#Get a batch of training images
test_iterator = iter(test_loader)
images, labels = test_iterator.next()

results = net(images)
_, predicted = torch.max(results, 1)

print('Predicted: ', ' '.join('%5s' % classes[predicted[j]] for j in range(4)))

fig2 = plt.figure()
for i in range(4):
   fig2.add_subplot(rows, columns, i+1)
   plt.title('truth ' + classes[labels[i]] + ': predict ' + classes[predicted[i]])
   img = images[i] / 2 + 0.5     # this is to unnormalize the image
   img = torchvision.transforms.ToPILImage()(img)
   plt.imshow(img)
plt.show()

Пример за класификация на изображението с PyTorch

Oбобщение

  • PyTorch е базиран на Torch с отворен код Machine Learning библиотека за обработка на естествен език използвайки Python.
  • Предимства на PyTorch: 1) Проста библиотека, 2) Динамична изчислителна графика, 3) По-добра производителност, 4) Роден Python
  • PyTorch използва Tensor за всяка променлива, подобна на ndarray на numpy, но с поддръжка на GPU изчисления.
  • Един от популярните методи за изучаване на основите на дълбокото обучение е с набора от данни MNIST.