Tutorial PyTorch: regressão, exemplo de classificação de imagens
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
- 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.
- 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.
- 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
- 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.
Próxima etapa, clique em Abrir para iniciar sua instância de notebook.
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,
- A primeira parte é definir os parâmetros e camadas que você utilizará
- 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:
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:
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.
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.
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
- 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
- Em seguida, você tem uma camada MaxPool2D
- Uma função de ativação ReLU
- uma camada Dropout para eliminar valores de baixa probabilidade.
- Em seguida, um segundo Conv2d com formato de entrada 10 da última camada e formato de saída 20 com tamanho de kernel 5
- Em seguida, uma camada MaxPool2d
- Função de ativação ReLU.
- Depois disso, você achatará o tensor antes de alimentá-lo na camada Linear
- 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()
Resumo
- PyTorch é um Torch de código aberto baseado Machine Learning biblioteca para processamento de linguagem natural utilização 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.