Учебное пособие по PyTorch: регрессия, пример классификации изображений

Краткое изложение руководства по Pytorch

В этом уроке по Pytorch вы изучите все concepts с нуля. В этом руководстве рассматриваются базовые и сложные темы, такие как определение pytorch, преимущества и недостатки pytorch, сравнение, установка, структура pytorch, регрессия и классификация изображений. Это руководство по Pytorch абсолютно бесплатно.

Что такое ПиТорч?

PyTorch — это библиотека машинного обучения с открытым исходным кодом на основе Torch для обработки естественного языка с использованием Python. Он похож на NumPy, но с мощной поддержкой графического процессора. Он предлагает динамические вычислительные графики, которые вы можете изменять на ходу с помощью autograd. PyTorch также быстрее некоторых других фреймворков. Он был разработан исследовательской группой Facebook по искусственному интеллекту в 2016 году.

Преимущества и недостатки PyTorch

Фоллоwing преимущества и недостатки 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 предлагает динамический вычислительный граф (DAG). Вычислительные графы — это способ выражения математических выражений в графовых моделях или теориях, таких как узлы и ребра. Узел выполнит математические operaция, а ребро — это тензор, который будет подаваться в узлы и переносить выходные данные узла в тензор.

DAG — это граф, имеющий произвольную форму и способный выполнять operaмежду различными входными графами. На каждой итерации создается новый график. Таким образом, можно иметь ту же структуру графа или создать новый граф с другой operaили мы можем назвать его динамическим графом.

  1. Улучшенная производительность

Сообщества и исследователи оценивают и сравнивают платформы, чтобы определить, какая из них быстрее. Репозиторий GitHub Тест по платформам глубокого обучения и графическим процессорам сообщил, что PyTorch быстрее других фреймворков с точки зрения обработки изображений в секунду.

Как вы можете видеть ниже, графики сравнения с vgg16 и resnet152

Преимущества ПиТорч

Преимущества ПиТорч

  1. Родной Питон

PyTorch больше основан на Python. Например, если вы хотите обучить модель, вы можете использовать собственный поток управления, такой как циклы и рекурсии, без необходимости добавлять дополнительные специальные переменные или сеансы для их запуска. Это очень полезно для тренировочного процесса.

Pytorch также реализует императивное программирование, и оно определенно более гибкое. Таким образом, можно распечатать значение тензора в середине процесса вычислений.

Недостаток PyTorch

PyTorch требует сторонних приложений для визуализации. Для производства также необходим сервер API.

Далее в этом уроке по PyTorch мы узнаем о разнице между PyTorch и TensorFlow.

PyTorch против. Тензорный поток

Параметр PyTorch Tensorflow
Определение модели Модель определена в подклассе и предлагает простой в использовании пакет. Модель определена многими, и вам необходимо понимать синтаксис.
Поддержка GPU Да Да
Тип графика Dynamic статический
Инструменты Нет инструмента визуализации Вы можете использовать инструмент визуализации Tensorboard.
Сообщество Коммуникацияunity все еще растетwing Большие активные сообщества

Установка ПиТорч

Linux

Его легко установить в Linux. Вы можете использовать виртуальную среду или установить ее напрямую с root-доступом. Введите эту команду в терминале

pip3 install --upgrade torch torchvision

AWS Сейджмейкер

Sagemaker — одна из платформ в Amazon Веб-сервис который предлагает мощный механизм машинного обучения с предустановленными конфигурациями глубокого обучения, позволяющий специалистам по данным или разработчикам создавать, обучать и развертывать модели в любом масштабе.

Сначала откройте Amazon Sagemaker консоли, нажмите «Создать экземпляр блокнота» и заполните все поля.tails для вашего блокнота.

AWS Сейджмейкер

Следующий шаг: нажмите «Открыть», чтобы запустить экземпляр блокнота.

AWS Сейджмейкер

Наконец, в Jupyter, Нажмите «Создать» и выберите conda_pytorch_p36, и вы готовы использовать экземпляр блокнота с установленным Pytorch.

Далее в этом руководстве по PyTorch мы узнаем об основах платформы PyTorch.

Основы платформы PyTorch

Давайте изучим основное concepts PyTorch, прежде чем мы углубимся. PyTorch использует Tensor для каждой переменной, аналогичной ndarray в numpy, но с поддержкой вычислений на графическом процессоре. Здесь мы объясним сетевую модель, функцию потерь, Backprop и Оптимизатор.

Сетевая модель

Сеть может быть построена путем создания подкласса 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

Оптимизатор

Torch.optim обеспечивает общую оптимизацию. algorithms. Вы можете определить оптимизатор с помощью простого шага:

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

Вам необходимо передать параметры сетевой модели и скорость обучения, чтобы на каждой итерации параметры обновлялись после процесса обратного распространения.

Простая регрессия с 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 = х3 грех(х)+ 3х+0.8 рэнд(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. Это «Hello World» в глубоком обучении. Набор данных содержит рукописные numbers от 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 и momentum 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, и он сгенерирует пакет изображений и меток, которые будут переданы обученной модели. Прогнозируемый результат будет отображенyed и сравнить с ожидаемым результатом.

#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

Итого

  • PyTorch — это программа Torch с открытым исходным кодом. Машинное обучение библиотека для обработки естественного языка используя Python.
  • Преимущества PyTorch: 1) Простая библиотека, 2) Динамический вычислительный график, 3) Лучшая производительность, 4) Собственный Python
  • PyTorch использует Tensor для каждой переменной, аналогичной ndarray в numpy, но с поддержкой вычислений на графическом процессоре.
  • Один из популярных методов изучения основ глубокого обучения — использование набора данных MNIST.