Tutoriel PyTorch : régression, exemple de classification d'images

Résumé du didacticiel Pytorch

Dans ce didacticiel pytorch, vous apprendrez tous les concepts à partir de zéro. Ce didacticiel couvre des sujets de base à avancés tels que la définition de pytorch, les avantages et les inconvénients de pytorch, la comparaison, l'installation, le framework pytorch, la régression et la classification d'images. Ce tutoriel pytorch est absolument gratuit.

Qu'est-ce que PyTorch ?

PyTorch est une bibliothèque open source d'apprentissage automatique basée sur Torch pour le traitement du langage naturel à l'aide de Python. Il est similaire à NumPy mais avec un puissant support GPU. Il propose des graphiques informatiques dynamiques que vous pouvez modifier en déplacement à l'aide d'Autograd. PyTorch est également plus rapide que certains autres frameworks. Il a été développé par l'IA Research Group de Facebook en 2016.

Avantages et inconvénients de PyTorch

Voici les avantages et les inconvénients de PyTorch :

Avantages de PyTorch

  1. Bibliothèque simplifiée
    Le code PyTorch est simple. C'est facile à comprendre et vous utilisez la bibliothèque instantanément. Par exemple, jetez un œil à l’extrait de code ci-dessous :
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

Comme mentionné ci-dessus, vous pouvez définir facilement le modèle de réseau et comprendre le code rapidement sans trop de formation.

  1. Graphique informatique dynamique

Graphique informatique dynamique

Source de l'image : Explorer l'apprentissage profond avec PyTorch

Pytorch propose un graphique informatique dynamique (DAG). Les graphiques informatiques sont un moyen d'exprimer des expressions mathématiques dans des modèles graphiques ou des théories telles que les nœuds et les arêtes. Le nœud effectuera l'opération mathématique et le bord est un tenseur qui sera introduit dans les nœuds et acheminera la sortie du nœud dans le tenseur.

DAG est un graphique qui a une forme arbitraire et capable d'effectuer des opérations entre différents graphiques d'entrée. À chaque itération, un nouveau graphique est créé. Ainsi, il est possible d’avoir la même structure de graphe ou de créer un nouveau graphe avec une opération différente, ou encore on peut l’appeler un graphe dynamique.

  1. Meilleures performances

Les communautés et les chercheurs évaluent et comparent les frameworks pour voir lequel est le plus rapide. Un dépôt GitHub Benchmark sur les frameworks de Deep Learning et les GPU a signalé que PyTorch est plus rapide que l'autre framework en termes d'images traitées par seconde.

Comme vous pouvez le voir ci-dessous, les graphiques de comparaison avec vgg16 et resnet152

Avantages de PyTorch

Avantages de PyTorch

  1. Originaire Python

PyTorch est davantage basé sur Python. Par exemple, si vous souhaitez entraîner un modèle, vous pouvez utiliser un flux de contrôle natif tel que les boucles et les récursions sans avoir besoin d'ajouter des variables ou des sessions plus spéciales pour pouvoir les exécuter. Ceci est très utile pour le processus de formation.

Pytorch implémente également la programmation impérative, et elle est nettement plus flexible. Ainsi, il est possible d'imprimer la valeur du tenseur au milieu d'un processus de calcul.

Inconvénient de PyTorch

PyTorch nécessite des applications tierces pour la visualisation. Il a également besoin d'un serveur API pour la production.

Ensuite, dans ce didacticiel PyTorch, nous découvrirons la différence entre PyTorch et TensorFlow.

PyTorch contre. Flux tensoriel

Paramètres PyTorch Tensorflow
Définition du modèle Le modèle est défini dans une sous-classe et propose un package facile à utiliser Le modèle est défini avec plusieurs et vous devez comprendre la syntaxe
Prise en charge du GPU Oui Oui
Type de graphique Dynamique Statique
Outils Aucun outil de visualisation Vous pouvez utiliser l'outil de visualisation Tensorboard
Communauté La communauté continue de s'agrandir De grandes communautés actives

Installer PyTorch

Linux

Il est simple de l'installer sous Linux. Vous pouvez choisir d'utiliser un environnement virtuel ou de l'installer directement avec un accès root. Tapez cette commande dans le terminal

pip3 install --upgrade torch torchvision

AWS Sagemaker

Sagemaker est l'une des plateformes de Amazon Service Web qui offre un puissant moteur d'apprentissage automatique avec des configurations d'apprentissage en profondeur préinstallées permettant aux scientifiques des données ou aux développeurs de créer, former et déployer des modèles à n'importe quelle échelle.

Ouvrez d'abord le Amazon Faiseur de sauge console et cliquez sur Créer une instance de notebook et remplissez tous les détails de votre notebook.

AWS Sagemaker

Étape suivante, cliquez sur Ouvrir pour lancer votre instance de notebook.

AWS Sagemaker

Enfin, dans Jupyter, Cliquez sur Nouveau et choisissez conda_pytorch_p36 et vous êtes prêt à utiliser votre instance de notebook avec Pytorch installé.

Ensuite, dans ce didacticiel PyTorch, nous découvrirons les bases du framework PyTorch.

Bases du framework PyTorch

Apprenons les concepts de base de PyTorch avant de plonger en profondeur. PyTorch utilise Tensor pour chaque variable similaire au ndarray de numpy mais avec prise en charge du calcul GPU. Ici, nous expliquerons le modèle de réseau, la fonction de perte, Backprop et Optimizer.

Modèle de réseau

Le réseau peut être construit en sous-classant torch.nn. Il y a 2 parties principales,

  1. La première partie consiste à définir les paramètres et les calques que vous utiliserez
  2. La deuxième partie est la tâche principale appelée processus avancé qui prendra une entrée et prédira la sortie.
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()

Comme vous pouvez le voir ci-dessus, vous créez une classe de nn.Module appelée Model. Il contient 2 calques Conv2d et un calque linéaire. La première couche conv2d prend une entrée de 3 et la forme de sortie de 20. La deuxième couche prendra une entrée de 20 et produira une forme de sortie de 40. La dernière couche est une couche entièrement connectée en forme de 320 et produira une sortie de 10.

Le processus forward prendra une entrée de X et la transmettra à la couche conv1 et exécutera la fonction ReLU,

De même, il alimentera également la couche conv2. Après cela, le x sera remodelé en (-1, 320) et alimentera la couche FC finale. Avant d'envoyer la sortie, vous utiliserez la fonction d'activation softmax.

Le processus en arrière est automatiquement défini par autograd, il vous suffit donc de définir le processus en avant.

Fonction de perte

La fonction de perte est utilisée pour mesurer dans quelle mesure le modèle de prédiction est capable de prédire les résultats attendus. PyTorch possède déjà de nombreuses fonctions de perte standard dans le module torch.nn. Par exemple, vous pouvez utiliser la perte d'entropie croisée pour résoudre un problème de classification PyTorch multi-classe. Il est facile de définir la fonction de perte et de calculer les pertes :

loss_fn = nn.CrossEntropyLoss()

#training process
loss = loss_fn(out, target)

Il est facile d'utiliser votre propre calcul de fonction de perte avec PyTorch.

Contre-propriété

Pour effectuer la rétropropagation, vous appelez simplement los.backward(). L'erreur sera calculée mais n'oubliez pas d'effacer le dégradé existant avec zero_grad()

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

Optimizer

Le torch.optim fournit des algorithmes d’optimisation courants. Vous pouvez définir un optimiseur en une étape simple :

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

Vous devez transmettre les paramètres du modèle de réseau et le taux d'apprentissage afin qu'à chaque itération, les paramètres soient mis à jour après le processus de backprop.

Régression simple avec PyTorch

Apprenons la régression simple avec des exemples PyTorch :

Étape 1) Création de notre modèle de réseau

Notre modèle de réseau est une simple couche linéaire avec une forme d'entrée et de sortie de 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)

Et la sortie réseau devrait être comme ça

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

Étape 2) Tester les données

Avant de commencer le processus de formation, vous devez connaître nos données. Vous créez une fonction aléatoire pour tester notre modèle. Oui = x3 péché(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()

Voici le nuage de points de notre fonction :

Nuage de points de régression simple avec PyTorch

Avant de commencer le processus de formation, vous devez convertir le tableau numpy en variables prises en charge par Torch et autograd, comme indiqué dans l'exemple de régression PyTorch ci-dessous.

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

Étape 3) Optimiseur et perte

Ensuite, vous devez définir l'optimiseur et la fonction de perte pour notre processus de formation.

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

Étape 4) Formation

Commençons maintenant notre processus de formation. Avec une époque de 250, vous itérerez nos données pour trouver la meilleure valeur pour nos hyperparamètres.

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

Étape 5) Résultat

Comme vous pouvez le voir ci-dessous, vous avez effectué avec succès une régression PyTorch avec un réseau neuronal. En fait, à chaque itération, la ligne rouge du tracé sera mise à jour et changera de position pour s'adapter aux données. Mais dans cette image, il ne vous montre que le résultat final, comme le montre l'exemple PyTorch ci-dessous :

Diagramme de dispersion du résultat de la régression simple

Exemple de classification d'images avec PyTorch

L'une des méthodes populaires pour apprendre les bases de l'apprentissage en profondeur est avec l'ensemble de données MNIST. C'est le « Hello World » dans le deep learning. L'ensemble de données contient des nombres manuscrits de 0 à 9 avec un total de 60,000 10,000 échantillons d'apprentissage et 28 28 échantillons de test déjà étiquetés avec une taille de × pixels.

Classification d'images avec PyTorch

Étape 1) Prétraiter les données

Dans la première étape de cet exemple de classification PyTorch, vous chargerez l'ensemble de données à l'aide du module torchvision.

Avant de commencer le processus de formation, vous devez comprendre les données. Torchvision chargera l'ensemble de données et transformera les images avec les exigences appropriées pour le réseau telles que la forme et la normalisation des images.

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 fonction de transformation convertit les images en tenseur et normalise la valeur. La fonction torchvision.transforms.MNIST téléchargera l'ensemble de données (s'il n'est pas disponible) dans le répertoire, définira l'ensemble de données pour la formation si nécessaire et effectuera le processus de transformation.

Pour visualiser l'ensemble de données, vous utilisez le data_iterator pour obtenir le prochain lot d'images et d'étiquettes. Vous utilisez matplot pour tracer ces images et leur étiquette appropriée. Comme vous pouvez le voir ci-dessous nos images et leurs étiquettes.

Exemple de classification d'images avec PyTorch

Étape 2) Configuration du modèle de réseau

Maintenant, dans cet exemple PyTorch, vous allez créer un réseau neuronal simple pour la classification d'images PyTorch.

Ici, nous vous présentons une autre façon de créer le modèle de réseau dans PyTorch. Nous utiliserons nn.Sequential pour créer un modèle de séquence au lieu de créer une sous-classe 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)

Voici le résultat de notre modèle de réseau

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

Explication du réseau

  1. La séquence est que la première couche est une couche Conv2D avec une forme d'entrée de 1 et une forme de sortie de 10 avec une taille de noyau de 5.
  2. Ensuite, vous avez une couche MaxPool2D
  3. Une fonction d'activation ReLU
  4. une couche Dropout pour supprimer les valeurs de faible probabilité.
  5. Puis un deuxième Conv2d avec la forme d'entrée de 10 de la dernière couche et la forme de sortie de 20 avec une taille de noyau de 5
  6. Ensuite une couche MaxPool2d
  7. Fonction d'activation ReLU.
  8. Après cela, vous aplatirez le tenseur avant de l'insérer dans le calque linéaire.
  9. La couche linéaire mappera notre sortie sur la deuxième couche linéaire avec la fonction d'activation softmax

Étape 3) Former le modèle

Avant de démarrer le processus de formation, il est nécessaire de configurer la fonction de critère et d'optimisation.

Pour le critère, vous utiliserez le CrossEntropyLoss. Pour l'optimiseur, vous utiliserez le SGD avec un taux d'apprentissage de 0.001 et un élan de 0.9, comme indiqué dans l'exemple PyTorch ci-dessous.

import torch.optim as optim

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

Le processus avancé prendra la forme d'entrée et la transmettra à la première couche conv2d. Ensuite, à partir de là, il sera introduit dans maxpool2d et enfin mis dans la fonction d'activation ReLU. Le même processus se produira dans la deuxième couche conv2d. Après cela, l'entrée sera remodelée en (-1,320 ) et alimentera la couche fc pour prédire la sortie.

Maintenant, vous allez commencer le processus de formation. Vous parcourrez notre ensemble de données 2 fois ou avec une époque de 2 et imprimerez la perte actuelle tous les 2000 lots.

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

À chaque époque, l'énumérateur obtiendra le prochain tuple d'entrée et les étiquettes correspondantes. Avant d'alimenter notre modèle de réseau, nous devons effacer le gradient précédent. Ceci est nécessaire car après le processus inverse (processus de rétropropagation), le gradient sera accumulé au lieu d'être remplacé. Ensuite, nous calculerons les pertes de la production prévue à partir de la production attendue. Après cela, nous ferons une rétropropagation pour calculer le gradient, et enfin, nous mettrons à jour les paramètres.

Voici le résultat du processus de formation

[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

Étape 4) Testez le modèle

Après avoir entraîné notre modèle, vous devez tester ou évaluer avec d'autres ensembles d'images.

Nous utiliserons un itérateur pour le test_loader, et il générera un lot d'images et d'étiquettes qui seront transmises au modèle entraîné. La sortie prévue sera affichée et comparée à la sortie attendue.

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

Exemple de classification d'images avec PyTorch

Résumé

  • PyTorch est un logiciel open source basé sur Torch Machine Learning bibliothèque pour traitement du langage naturel en utilisant Python.
  • Avantages de PyTorch : 1) Bibliothèque simple, 2) Graphique informatique dynamique, 3) Meilleures performances, 4) Natif Python
  • PyTorch utilise Tensor pour chaque variable similaire au ndarray de numpy mais avec prise en charge du calcul GPU.
  • L'une des méthodes les plus populaires pour apprendre les bases de l'apprentissage profond consiste à utiliser l'ensemble de données MNIST.