Tutorial do PyTorch

Resumo do tutorial Pytorch

Neste tutorial pytorch, vocรช aprenderรก todos os conceitos do zero. Este tutorial cobre tรณpicos bรกsicos a avanรงados, como definiรงรฃo de pytorch, vantagens e desvantagens de pytorch, comparaรงรฃo, instalaรงรฃo, estrutura pytorch, regressรฃo e classificaรงรฃo de imagens. Este tutorial pytorch รฉ totalmente gratuito.

O que รฉ o PyTorch?

PyTorch รฉ uma biblioteca de aprendizado de mรกquina baseada em Torch de cรณdigo aberto para processamento de linguagem natural usando Python. ร‰ semelhante ao NumPy, mas com suporte poderoso para GPU. Ele oferece grรกficos computacionais dinรขmicos que vocรช pode modificar em qualquer lugar com a ajuda do autograd. PyTorch tambรฉm รฉ mais rรกpido do que alguns outros frameworks. Foi desenvolvido pelo Grupo de Pesquisa de IA do Facebook em 2016.

Vantagens e desvantagens do PyTorch

A seguir estรฃo as vantagens e desvantagens do PyTorch:

Vantagens do PyTorch

  1. Biblioteca Simples
    O cรณdigo PyTorch รฉ simples. ร‰ fรกcil de entender e vocรช usa a biblioteca instantaneamente. Por exemplo, dรช uma olhada no trecho de cรณdigo abaixo:
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

Conforme mencionado acima, vocรช pode definir o modelo de rede facilmente e entender o cรณdigo rapidamente, sem muito treinamento.

  1. Grรกfico Computacional Dinรขmico

Grรกfico Computacional Dinรขmico

Fonte da imagem: Explorando o aprendizado profundo com PyTorch

Pytorch oferece Grรกfico Computacional Dinรขmico (DAG). Grรกficos computacionais sรฃo uma forma de expressar expressรตes matemรกticas em modelos de grafos ou teorias como nรณs e arestas. O nรณ farรก a operaรงรฃo matemรกtica, e a aresta รฉ um Tensor que serรก alimentado nos nรณs e carrega a saรญda do nรณ no Tensor.

DAG รฉ um grรกfico que possui formato arbitrรกrio e รฉ capaz de realizar operaรงรตes entre diferentes grรกficos de entrada. A cada iteraรงรฃo, um novo grรกfico รฉ criado. Assim, รฉ possรญvel ter a mesma estrutura de grรกfico ou criar um novo grรกfico com uma operaรงรฃo diferente, ou podemos chamรก-lo de grรกfico dinรขmico.

  1. Melhor Performance

Comunidades e pesquisadores avaliam e comparam estruturas para ver qual delas รฉ mais rรกpida. Um repositรณrio GitHub Referรชncia em estruturas de aprendizado profundo e GPUs relataram que PyTorch รฉ mais rรกpido que o outro framework em termos de imagens processadas por segundo.

Como vocรช pode ver abaixo, os grรกficos de comparaรงรฃo com vgg16 e resnet152

Vantagens do PyTorch

Vantagens do PyTorch

  1. Nativo Python

PyTorch รฉ mais baseado em python. Por exemplo, se quiser treinar um modelo, vocรช pode usar fluxo de controle nativo, como loops e recursรตes, sem a necessidade de adicionar mais variรกveis โ€‹โ€‹ou sessรตes especiais para poder executรก-los. Isso รฉ muito รบtil para o processo de treinamento.

Pytorch tambรฉm implementa Programaรงรฃo Imperativa e รฉ definitivamente mais flexรญvel. Assim, รฉ possรญvel imprimir o valor do tensor no meio de um processo de computaรงรฃo.

Desvantagem do PyTorch

PyTorch requer aplicativos de terceiros para visualizaรงรฃo. Tambรฉm precisa de um servidor API para produรงรฃo.

A seguir neste tutorial do PyTorch, aprenderemos sobre a diferenรงa entre PyTorch e TensorFlow.

PyTorch vs. Fluxo tensor

Parรขmetro PyTorch Tensorflow
Definiรงรฃo de Modelo O modelo รฉ definido em uma subclasse e oferece pacotes fรกceis de usar O modelo รฉ definido com muitos e vocรช precisa entender a sintaxe
Suporte GPU Sim Sim
Tipo de Grรกfico Dinรขmico Estรกtico
Ferramentas Nenhuma ferramenta de visualizaรงรฃo Vocรช pode usar a ferramenta de visualizaรงรฃo Tensorboard
Comunidade A comunidade continua crescendo Grandes comunidades ativas

Instalando o PyTorch

Linux

ร‰ simples instalรก-lo no Linux. Vocรช pode optar por usar um ambiente virtual ou instalรก-lo diretamente com acesso root. Digite este comando no terminal

pip3 install --upgrade torch torchvision

AWS SageMaker

Sagemaker รฉ uma das plataformas em Amazon Serviรงo de internet que oferece um poderoso mecanismo de aprendizado de mรกquina com configuraรงรตes de aprendizado profundo prรฉ-instaladas para cientistas de dados ou desenvolvedores criarem, treinarem e implantarem modelos em qualquer escala.

Primeiro abra o Amazon Sรกbio console e clique em Criar instรขncia de notebook e preencha todos os detalhes do seu notebook.

AWS SageMaker

Prรณxima etapa, clique em Abrir para iniciar sua instรขncia de notebook.

AWS SageMaker

Finalmente, em Jupyter, Clique em Novo e escolha conda_pytorch_p36 e vocรช estarรก pronto para usar sua instรขncia de notebook com o Pytorch instalado.

A seguir neste tutorial do PyTorch, aprenderemos sobre os fundamentos da estrutura PyTorch.

Noรงรตes bรกsicas da estrutura PyTorch

Vamos aprender os conceitos bรกsicos do PyTorch antes de nos aprofundarmos. PyTorch usa Tensor para cada variรกvel semelhante ao ndarray do numpy, mas com suporte para computaรงรฃo GPU. Aqui explicaremos o modelo de rede, funรงรฃo de perda, Backprop e Optimizer.

Modelo de rede

A rede pode ser construรญda subclassificando torch.nn. Existem 2 partes principais,

  1. A primeira parte รฉ definir os parรขmetros e camadas que vocรช utilizarรก
  2. A segunda parte รฉ a tarefa principal chamada processo forward que receberรก uma entrada e preverรก a saรญda.
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()

Como vocรช pode ver acima, vocรช cria uma classe de nn.Module chamada Model. Ele contรฉm 2 camadas Conv2d e uma camada Linear. A primeira camada conv2d recebe uma entrada de 3 e o formato de saรญda de 20. A segunda camada receberรก uma entrada de 20 e produzirรก um formato de saรญda de 40. A รบltima camada รฉ uma camada totalmente conectada no formato de 320 e produzirรก uma saรญda de 10.

O processo de encaminhamento pegarรก uma entrada de X e a alimentarรก na camada conv1 e executarรก a funรงรฃo ReLU,

Da mesma forma, tambรฉm alimentarรก a camada conv2. Depois disso, o x serรก remodelado em (-1, 320) e alimentado na camada FC final. Antes de enviar a saรญda, vocรช usarรก a funรงรฃo de ativaรงรฃo softmax.

O processo de retrocesso รฉ definido automaticamente pelo autograd, portanto, vocรช sรณ precisa definir o processo de encaminhamento.

Funรงรฃo de perda

A funรงรฃo de perda รฉ usada para medir quรฃo bem o modelo de previsรฃo รฉ capaz de prever os resultados esperados. PyTorch jรก possui muitas funรงรตes de perda padrรฃo no mรณdulo torch.nn. Por exemplo, vocรช pode usar a perda de entropia cruzada para resolver um problema de classificaรงรฃo PyTorch multiclasse. ร‰ fรกcil definir a funรงรฃo de perda e calcular as perdas:

loss_fn = nn.CrossEntropyLoss()

#training process
loss = loss_fn(out, target)

ร‰ fรกcil usar seu prรณprio cรกlculo de funรงรฃo de perda com PyTorch.

Apoio traseiro

Para realizar a retropropagaรงรฃo, basta chamar los.backward(). O erro serรก calculado, mas lembre-se de limpar o gradiente existente com zero_grad()

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

Optimizer

O torch.optim fornece algoritmos de otimizaรงรฃo comuns. Vocรช pode definir um otimizador com uma etapa simples:

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

Vocรช precisa passar os parรขmetros do modelo de rede e a taxa de aprendizado para que a cada iteraรงรฃo os parรขmetros sejam atualizados apรณs o processo backprop.

Regressรฃo Simples com PyTorch

Vamos aprender regressรฃo simples com exemplos do PyTorch:

Etapa 1) Criando nosso modelo de rede

Nosso modelo de rede รฉ uma camada linear simples com formato de entrada e saรญda 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)

E a saรญda da rede deveria ser assim

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

Etapa 2) Dados de teste

Antes de iniciar o processo de treinamento, vocรช precisa conhecer nossos dados. Vocรช cria uma funรงรฃo aleatรณria para testar nosso modelo. Y = x3 sen(x)+ 3x+0.8 rands(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()

Aqui estรก o grรกfico de dispersรฃo da nossa funรงรฃo:

Grรกfico de dispersรฃo de regressรฃo simples com PyTorch

Antes de iniciar o processo de treinamento, vocรช precisa converter a matriz numpy em variรกveis โ€‹โ€‹โ€‹โ€‹suportadas pelo Torch e autograd, conforme mostrado no exemplo de regressรฃo PyTorch abaixo.

# 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)

Etapa 3) Otimizador e Perda

A seguir, vocรช deve definir o Otimizador e a Funรงรฃo de Perda para nosso processo de treinamento.

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

Etapa 4) Treinamento

Agora vamos iniciar nosso processo de treinamento. Com uma รฉpoca de 250, vocรช irรก iterar nossos dados para encontrar o melhor valor para nossos hiperparรขmetros.

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()

Etapa 5) Resultado

Como vocรช pode ver abaixo, vocรช executou com sucesso a regressรฃo PyTorch com uma rede neural. Na verdade, a cada iteraรงรฃo, a linha vermelha no grรกfico serรก atualizada e mudarรก de posiรงรฃo para se ajustar aos dados. Mas nesta imagem, ela mostra apenas o resultado final conforme mostrado no exemplo PyTorch abaixo:

Grรกfico de dispersรฃo do resultado da regressรฃo simples

Exemplo de classificaรงรฃo de imagens com PyTorch

Um dos mรฉtodos populares para aprender o bรกsico de deep learning estรก com o conjunto de dados MNIST. ร‰ o โ€œHello Worldโ€ no aprendizado profundo. O conjunto de dados contรฉm nรบmeros manuscritos de 0 a 9 com o total de 60,000 amostras de treinamento e 10,000 amostras de teste jรก rotuladas com o tamanho de 28ร—28 pixels.

Classificaรงรฃo de imagens com PyTorch

Etapa 1) Prรฉ-processar os dados

Na primeira etapa deste exemplo de classificaรงรฃo PyTorch, vocรช carregarรก o conjunto de dados usando o mรณdulo torchvision.

Antes de iniciar o processo de treinamento, vocรช precisa compreender os dados. O Torchvision carregarรก o conjunto de dados e transformarรก as imagens com os requisitos apropriados para a rede, como formato e normalizaรงรฃo das imagens.

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()

A funรงรฃo transform converte as imagens em tensor e normaliza o valor. A funรงรฃo torchvision.transforms.MNIST, irรก baixar o conjunto de dados (se nรฃo estiver disponรญvel) no diretรณrio, definir o conjunto de dados para treinamento se necessรกrio e fazer o processo de transformaรงรฃo.

Para visualizar o conjunto de dados, vocรช usa o data_iterator para obter o prรณximo lote de imagens e rรณtulos. Vocรช usa matplot para plotar essas imagens e seus rรณtulos apropriados. Como vocรช pode ver abaixo nossas imagens e seus rรณtulos.

Exemplo de classificaรงรฃo de imagens com PyTorch

Etapa 2) Configuraรงรฃo do modelo de rede

Agora, neste exemplo do PyTorch, vocรช criarรก uma rede neural simples para classificaรงรฃo de imagens do PyTorch.

Aqui, apresentamos outra maneira de criar o modelo de rede no PyTorch. Usaremos nn.Sequential para criar um modelo de sequรชncia em vez de criar uma subclasse de 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)

Aqui estรก o resultado do nosso modelo de rede

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()
)

Explicaรงรฃo da rede

  1. A sequรชncia รฉ que a primeira camada รฉ uma camada Conv2D com formato de entrada 1 e formato de saรญda 10 com tamanho de kernel 5
  2. Em seguida, vocรช tem uma camada MaxPool2D
  3. Uma funรงรฃo de ativaรงรฃo ReLU
  4. uma camada Dropout para eliminar valores de baixa probabilidade.
  5. Em seguida, um segundo Conv2d com formato de entrada 10 da รบltima camada e formato de saรญda 20 com tamanho de kernel 5
  6. Em seguida, uma camada MaxPool2d
  7. Funรงรฃo de ativaรงรฃo ReLU.
  8. Depois disso, vocรช achatarรก o tensor antes de alimentรก-lo na camada Linear
  9. A Camada Linear mapearรก nossa saรญda na segunda camada Linear com funรงรฃo de ativaรงรฃo softmax

Etapa 3) Treine o modelo

Antes de iniciar o processo de treinamento, รฉ necessรกrio configurar o critรฉrio e a funรงรฃo do otimizador.

Para o critรฉrio, vocรช usarรก CrossEntropyLoss. Para o Otimizador, vocรช usarรก o SGD com uma taxa de aprendizado de 0.001 e um impulso de 0.9, conforme mostrado no exemplo PyTorch abaixo.

import torch.optim as optim

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

O processo de encaminhamento pegarรก o formato de entrada e o passarรก para a primeira camada conv2d. A partir daรญ, ele serรก alimentado no maxpool2d e finalmente colocado na funรงรฃo de ativaรงรฃo ReLU. O mesmo processo ocorrerรก na segunda camada conv2d. Depois disso, a entrada serรก remodelada em (-1,320) e alimentada na camada fc para prever a saรญda.

Agora, vocรช iniciarรก o processo de treinamento. Vocรช irรก iterar em nosso conjunto de dados 2 vezes ou com uma รฉpoca de 2 e imprimir a perda atual a cada lote de 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

Em cada รฉpoca, o enumerador obterรก a prรณxima tupla de entrada e os rรณtulos correspondentes. Antes de alimentarmos nosso modelo de rede com a entrada, precisamos limpar o gradiente anterior. Isso รฉ necessรกrio porque apรณs o processo reverso (processo de retropropagaรงรฃo), o gradiente serรก acumulado em vez de substituรญdo. Em seguida, calcularemos as perdas da produรงรฃo prevista a partir da produรงรฃo esperada. Depois disso, faremos uma retropropagaรงรฃo para calcular o gradiente e, por fim, atualizaremos os parรขmetros.

Aqui estรก o resultado do processo de treinamento

[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

Etapa 4) Teste o modelo

Depois de treinar nosso modelo, vocรช precisa testar ou avaliar outros conjuntos de imagens.

Usaremos um iterador para test_loader, e ele gerarรก um lote de imagens e rรณtulos que serรฃo passados โ€‹โ€‹para o modelo treinado. A saรญda prevista serรก exibida e comparada com a saรญda esperada.

#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()

Exemplo de classificaรงรฃo de imagens com PyTorch

Resumo

  • PyTorch รฉ um Torch de cรณdigo aberto baseado Machine Learning biblioteca para processamento de linguagem natural utilizando Python.
  • Vantagens do PyTorch: 1) Biblioteca Simples, 2) Grรกfico Computacional Dinรขmico, 3) Melhor Desempenho, 4) Nativo Python
  • PyTorch usa Tensor para cada variรกvel semelhante ao ndarray do numpy, mas com suporte para computaรงรฃo GPU.
  • Um dos mรฉtodos populares para aprender os fundamentos do aprendizado profundo รฉ com o conjunto de dados MNIST.

Resuma esta postagem com: