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
- 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.
- 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.
- 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
- 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.
Étape suivante, cliquez sur Ouvrir pour lancer votre instance de notebook.
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,
- La première partie consiste à définir les paramètres et les calques que vous utiliserez
- 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 :
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 :
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.
É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.
É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
- 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.
- Ensuite, vous avez une couche MaxPool2D
- Une fonction d'activation ReLU
- une couche Dropout pour supprimer les valeurs de faible probabilité.
- 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
- Ensuite une couche MaxPool2d
- Fonction d'activation ReLU.
- Après cela, vous aplatirez le tenseur avant de l'insérer dans le calque linéaire.
- 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()
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.