Tutorial PyTorch: regressione, esempio di classificazione delle immagini
Riepilogo del tutorial di Pytorch
In questo tutorial di Pytorch imparerai tutti i concetti da zero. Questo tutorial copre argomenti da base ad avanzati come la definizione di Pytorch, i vantaggi e gli svantaggi di Pytorch, il confronto, l'installazione, il framework Pytorch, la regressione e la classificazione delle immagini. Questo tutorial su Python è assolutamente gratuito.
Cos'è PyTorch?
PyTorch è una libreria di machine learning open source basata su Torch per l'utilizzo dell'elaborazione del linguaggio naturale Python. È simile a NumPy ma con un potente supporto GPU. Offre grafici computazionali dinamici che puoi modificare mentre sei in movimento con l'aiuto di autograd. PyTorch è anche più veloce di altri framework. È stato sviluppato dall'AI Research Group di Facebook nel 2016.
PyTorch Vantaggi e svantaggi
Di seguito sono riportati i vantaggi e gli svantaggi di PyTorch:
Vantaggi di PyTorch
- Biblioteca semplice
Il codice PyTorch è semplice. È facile da capire e utilizzi immediatamente la libreria. Ad esempio, dai un'occhiata allo snippet di codice seguente:
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
Come accennato in precedenza, è possibile definire facilmente il modello di rete e comprendere rapidamente il codice senza molta formazione.
- Grafico computazionale dinamico
Fonte immagine: esplorazione del deep learning con PyTorch
Pytorch offre il grafico computazionale dinamico (DAG). I grafici computazionali sono un modo per esprimere espressioni matematiche in modelli di grafici o teorie come nodi e spigoli. Il nodo eseguirà l'operazione matematica e il bordo è un tensore che verrà immesso nei nodi e trasporterà l'output del nodo in Tensore.
DAG è un grafico che ha una forma arbitraria ed è in grado di eseguire operazioni tra diversi grafici di input. Ad ogni iterazione viene creato un nuovo grafico. Quindi, è possibile avere la stessa struttura del grafico o creare un nuovo grafico con un'operazione diversa, oppure possiamo chiamarlo grafico dinamico.
- migliori prestazioni
Comunità e ricercatori confrontano e confrontano i framework per vedere quale è più veloce. Un repository GitHub Benchmark su framework e GPU per il deep learning ha riferito che PyTorch è più veloce dell'altro framework in termini di immagini elaborate al secondo.
Come puoi vedere di seguito, i grafici di confronto con vgg16 e resnet152
- Native Python
PyTorch è più basato su Python. Ad esempio, se desideri addestrare un modello, puoi utilizzare il flusso di controllo nativo come il looping e le ricorsioni senza la necessità di aggiungere ulteriori variabili o sessioni speciali per poterli eseguire. Questo è molto utile per il processo di formazione.
Pytorch implementa anche la programmazione imperativa ed è decisamente più flessibile. Quindi è possibile stampare il valore del tensore nel bel mezzo di un processo di calcolo.
Svantaggio di PyTorch
PyTorch richiede applicazioni di terze parti per la visualizzazione. Richiede inoltre un server API per la produzione.
Successivamente in questo tutorial su PyTorch, impareremo la differenza tra PyTorch e TensorFlow.
PyTorch vs. Tensorflusso
Parametro | PyTorch | tensorflow |
---|---|---|
Definizione del modello | Il modello è definito in una sottoclasse e offre un pacchetto facile da usare | Il modello è definito con molti ed è necessario comprenderne la sintassi |
Supporto GPU | Si | Si |
Tipo di grafico | Dinamico | statica |
Strumenti | Nessuno strumento di visualizzazione | È possibile utilizzare lo strumento di visualizzazione Tensorboard |
Comunità | La comunità continua a crescere | Grandi comunità attive |
Installazione di PyTorch
Linux
È semplice installarlo su Linux. Puoi scegliere di utilizzare un ambiente virtuale o installarlo direttamente con accesso root. Digita questo comando nel terminale
pip3 install --upgrade torch torchvision
AWS SageMaker
Sagemaker è una delle piattaforme in Amazon Servizio web che offre un potente motore di machine learning con configurazioni di deep learning preinstallate per consentire a data scientist o sviluppatori di creare, addestrare e distribuire modelli su qualsiasi scala.
Prima apri il file Amazon Sagemaker console e clicca su Crea istanza notebook e compila tutti i dettagli per il tuo notebook.
Passaggio successivo: fai clic su Apri per avviare l'istanza del tuo notebook.
Infine, In Jupyter, Fai clic su Nuovo e scegli conda_pytorch_p36 e sei pronto per utilizzare l'istanza del tuo notebook con Pytorch installato.
Successivamente in questo tutorial su PyTorch, impareremo le nozioni di base sul framework PyTorch.
Nozioni di base sul framework PyTorch
Impariamo i concetti di base di PyTorch prima di approfondire. PyTorch utilizza Tensor per ogni variabile simile a ndarray di Numpy ma con supporto per il calcolo GPU. Qui spiegheremo il modello di rete, la funzione di perdita, Backprop e Optimizer.
Modello di rete
La rete può essere costruita sottoclassando torch.nn. Ci sono 2 parti principali,
- La prima parte è definire i parametri e i livelli che utilizzerai
- La seconda parte è l'attività principale chiamata processo di inoltro che prenderà un input e prevederà l'output.
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()
Come puoi vedere sopra, crei una classe di nn.Module chiamata Model. Contiene 2 livelli Conv2d e un livello Lineare. Il primo strato conv2d prende un input di 3 e una forma di output di 20. Il secondo strato prenderà un input di 20 e produrrà una forma di output di 40. L'ultimo strato è uno strato completamente connesso nella forma di 320 e produrrà un'uscita di 10.
Il processo di inoltro prenderà un input di X e lo inserirà nel livello conv1 ed eseguirà la funzione ReLU,
Allo stesso modo, alimenterà anche il livello conv2. Successivamente, la x verrà rimodellata in (-1, 320) e inserita nello strato FC finale. Prima di inviare l'output, utilizzerai la funzione di attivazione di softmax.
Il processo all'indietro viene definito automaticamente da autograd, quindi è necessario definire solo il processo in avanti.
Funzione di perdita
La funzione di perdita viene utilizzata per misurare quanto bene il modello di previsione è in grado di prevedere i risultati attesi. PyTorch ha già molte funzioni di perdita standard nel modulo torch.nn. Ad esempio, puoi utilizzare la perdita di entropia incrociata per risolvere un problema di classificazione PyTorch multiclasse. È facile definire la funzione di perdita e calcolare le perdite:
loss_fn = nn.CrossEntropyLoss() #training process loss = loss_fn(out, target)
È facile utilizzare il calcolo della funzione di perdita con PyTorch.
Backprop
Per eseguire la propagazione all'indietro, chiami semplicemente los.backward(). L'errore verrà calcolato ma ricorda di cancellare il gradiente esistente con zero_grad()
net.zero_grad() # to clear the existing gradient loss.backward() # to perform backpropragation
Optimizer
torch.optim fornisce algoritmi di ottimizzazione comuni. Puoi definire un ottimizzatore con un semplice passaggio:
optimizer = torch.optim.SGD(net.parameters(), lr = 0.01, momentum=0.9)
È necessario passare i parametri del modello di rete e la velocità di apprendimento in modo che ad ogni iterazione i parametri vengano aggiornati dopo il processo backprop.
Regressione semplice con PyTorch
Impariamo la semplice regressione con gli esempi PyTorch:
Passaggio 1) Creazione del nostro modello di rete
Il nostro modello di rete è un semplice livello lineare con una forma di input e output pari a 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 l'output della rete dovrebbe essere così
Net( (hidden): Linear(in_features=1, out_features=1, bias=True) )
Passaggio 2) Testare i dati
Prima di iniziare il processo di formazione, devi conoscere i nostri dati. Crea una funzione casuale per testare il nostro modello. Y = x3 peccato(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()
Ecco il grafico a dispersione della nostra funzione:
Prima di iniziare il processo di training, è necessario convertire l'array Numpy in variabili supportate da Torch e autograd, come mostrato nell'esempio di regressione PyTorch riportato di seguito.
# 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)
Passaggio 3) Ottimizzatore e perdita
Successivamente, dovresti definire l'ottimizzatore e la funzione di perdita per il nostro processo di formazione.
# Define Optimizer and Loss Function optimizer = torch.optim.SGD(net.parameters(), lr=0.2) loss_func = torch.nn.MSELoss()
Passaggio 4) Formazione
Ora iniziamo il nostro processo di formazione. Con un'epoca di 250, iterarai i nostri dati per trovare il valore migliore per i nostri iperparametri.
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()
Passaggio 5) Risultato
Come puoi vedere di seguito, hai eseguito con successo la regressione PyTorch con una rete neurale. In realtà, ad ogni iterazione, la linea rossa nel grafico si aggiornerà e cambierà la sua posizione per adattarsi ai dati. Ma in questa immagine mostra solo il risultato finale, come mostrato nell'esempio PyTorch qui sotto:
Esempio di classificazione delle immagini con PyTorch
Uno dei metodi popolari per apprendere le basi di apprendimento profondo è con il set di dati MNIST. È il “Hello World” nel deep learning. Il set di dati contiene numeri scritti a mano da 0 a 9 con un totale di 60,000 campioni di addestramento e 10,000 campioni di test già etichettati con la dimensione di 28×28 pixel.
Passaggio 1) Preelaborare i dati
Nel primo passaggio di questo esempio di classificazione PyTorch, caricherai il set di dati utilizzando il modulo torchvision.
Prima di iniziare il processo di formazione, è necessario comprendere i dati. Torchvision caricherà il set di dati e trasformerà le immagini con i requisiti appropriati per la rete come la forma e la normalizzazione delle immagini.
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()
La funzione di trasformazione converte le immagini in tensore e normalizza il valore. La funzione torchvision.transforms.MNIST scaricherà il set di dati (se non è disponibile) nella directory, imposterà il set di dati per l'addestramento, se necessario, ed eseguirà il processo di trasformazione.
Per visualizzare il set di dati, utilizzi data_iterator per ottenere il batch successivo di immagini ed etichette. Utilizzi matplot per tracciare queste immagini e la loro etichetta appropriata. Come potete vedere qui sotto le nostre immagini e le relative etichette.
Passaggio 2) Configurazione del modello di rete
Ora, in questo esempio PyTorch, creerai una semplice rete neurale per la classificazione delle immagini PyTorch.
Qui ti presentiamo un altro modo per creare il modello di rete in PyTorch. Utilizzeremo nn.Sequential per creare un modello sequenza invece di creare una sottoclasse di 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)
Ecco l'output del nostro modello di rete
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() )
Spiegazione della rete
- La sequenza prevede che il primo livello sia un livello Conv2D con una forma di input pari a 1 e una forma di output pari a 10 con una dimensione del kernel pari a 5
- Successivamente, hai un livello MaxPool2D
- Una funzione di attivazione ReLU
- un livello di eliminazione per eliminare i valori di bassa probabilità.
- Quindi un secondo Conv2d con la forma di input pari a 10 dall'ultimo livello e la forma di output pari a 20 con una dimensione del kernel pari a 5
- Successivamente un livello MaxPool2d
- Funzione di attivazione ReLU.
- Successivamente, appiattirai il tensore prima di inserirlo nel livello Lineare
- Il livello lineare mapperà il nostro output sul secondo livello lineare con la funzione di attivazione softmax
Passaggio 3) Addestrare il modello
Prima di iniziare il processo di formazione, è necessario impostare il criterio e la funzione di ottimizzazione.
Per il criterio utilizzerai CrossEntropyLoss. Per l'ottimizzatore, utilizzerai l'SGD con un tasso di apprendimento di 0.001 e uno slancio di 0.9 come mostrato nell'esempio PyTorch di seguito.
import torch.optim as optim criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
Il processo di inoltro prenderà la forma di input e la passerà al primo livello conv2d. Quindi da lì verrà inserito in maxpool2d e infine inserito nella funzione di attivazione ReLU. Lo stesso processo avverrà nel secondo livello conv2d. Successivamente, l'input verrà rimodellato in (-1,320) e inserito nel livello fc per prevedere l'output.
Ora inizierai il processo di formazione. Itererai il nostro set di dati 2 volte o con un'epoca pari a 2 e stamperai la perdita corrente ogni 2000 batch.
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
Ad ogni epoca, l'enumeratore otterrà la successiva tupla di input e le etichette corrispondenti. Prima di fornire l'input al nostro modello di rete, dobbiamo eliminare il gradiente precedente. Ciò è necessario perché dopo il processo all'indietro (processo di backpropagation), il gradiente verrà accumulato invece di essere sostituito. Quindi, calcoleremo le perdite dalla produzione prevista dalla produzione attesa. Successivamente, faremo una backpropagation per calcolare il gradiente e, infine, aggiorneremo i parametri.
Ecco l'output del processo di formazione
[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
Passaggio 4) Testare il modello
Dopo aver addestrato il nostro modello, devi testarlo o valutarlo con altri set di immagini.
Utilizzeremo un iteratore per test_loader e genererà un batch di immagini ed etichette che verranno passate al modello addestrato. L'output previsto verrà visualizzato e confrontato con l'output previsto.
#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()
Sommario
- PyTorch è un software open source basato su Torch machine Learning libreria per elaborazione del linguaggio naturale utilizzando Python.
- Vantaggi di PyTorch: 1) Libreria semplice, 2) Grafico computazionale dinamico, 3) Prestazioni migliori, 4) Nativo Python
- PyTorch utilizza Tensor per ogni variabile simile a ndarray di Numpy ma con supporto per il calcolo GPU.
- Uno dei metodi più diffusi per apprendere le basi del deep learning è il set di dati MNIST.