[PYTHON] [Tutoriel PyTorch ⑤] Apprentissage de PyTorch avec des exemples (Partie 1)

introduction

Ceci est le 5ème volet de PyTorch Tutoriel officiel après Dernière fois. Cette fois, nous allons procéder à Apprendre PyTorch avec des exemples.

Learning PyTorch with Examples

Ce didacticiel vous présentera deux fonctionnalités principales de PyTorch via un exemple de code.

Le réseau (modèle) géré par l'exemple de code est composé de 3 couches (couche d'entrée, couche cachée x 1, couche de sortie). La fonction d'activation utilise ReLU.

  1. Tensor

1.1. Warm-up: numpy

Avant PyTorch, implémentez d'abord le réseau en utilisant numpy. Numpy n'a pas de fonctionnalités pour l'apprentissage en profondeur, les dégradés, Vous pouvez créer un réseau neuronal simple en l'implémentant manuellement.

import numpy as np

#N: taille du lot
# D_in: Nombre de dimensions d'entrée
#H: nombre de dimensions du calque caché
# D_out: nombre de dimensions de sortie
N, D_in, H, D_out = 64, 1000, 100, 10

#Créer une entrée aléatoire et des données sur les enseignants
x = np.random.randn(N, D_in)
y = np.random.randn(N, D_out)

#Initialisez le poids avec une valeur aléatoire
w1 = np.random.randn(D_in, H)
w2 = np.random.randn(H, D_out)

learning_rate = 1e-6
for t in range(500):
    #Propagation vers l'avant:Calcule la valeur prévue y avec la valeur de poids actuelle
    h = x.dot(w1)
    h_relu = np.maximum(h, 0)
    y_pred = h_relu.dot(w2)

    #Calcule et génère la perte
    loss = np.square(y_pred - y).sum()
    print(t, loss)

    #En référence à la valeur de perte, calculez le gradient des poids w1 et w2 par rétro-propagation.
    grad_y_pred = 2.0 * (y_pred - y)
    grad_w2 = h_relu.T.dot(grad_y_pred)
    grad_h_relu = grad_y_pred.dot(w2.T)
    grad_h = grad_h_relu.copy()
    grad_h[h < 0] = 0
    grad_w1 = x.T.dot(grad_h)

    #Mettez à jour le poids.
    w1 -= learning_rate * grad_w1
    w2 -= learning_rate * grad_w2

Lorsque vous exécutez ce code, vous pouvez voir que la valeur de la perte a diminué et que l'apprentissage progresse.

1.2. PyTorch: Tensors

Numpy ne peut pas être calculé à l'aide du GPU, mais le Tensor de PyTorch peut utiliser le GPU pour accélérer les calculs numériques. Tensor peut également calculer des dégradés, mais pour l'instant, implémentons-le manuellement, comme dans l'exemple numpy ci-dessus.

import torch


dtype = torch.float
device = torch.device("cpu")
# device = torch.device("cuda:0") #Décommentez ici pour exécuter sur le GPU.

#N: taille du lot
# D_in: Nombre de dimensions d'entrée
#H: nombre de dimensions du calque caché
# D_out: nombre de dimensions de sortie
N, D_in, H, D_out = 64, 1000, 100, 10

#Créer une entrée aléatoire et des données sur les enseignants
x = torch.randn(N, D_in, device=device, dtype=dtype)
y = torch.randn(N, D_out, device=device, dtype=dtype)

#Initialisez le poids avec une valeur aléatoire
w1 = torch.randn(D_in, H, device=device, dtype=dtype)
w2 = torch.randn(H, D_out, device=device, dtype=dtype)

learning_rate = 1e-6
for t in range(500):
    #Propagation vers l'avant:Calcule la valeur prévue y avec la valeur de poids actuelle
    h = x.mm(w1)
    h_relu = h.clamp(min=0)
    y_pred = h_relu.mm(w2)

    #Calcule et génère la perte
    loss = (y_pred - y).pow(2).sum().item()
    if t % 100 == 99:
        print(t, loss)

    #En référence à la valeur de perte, calculez le gradient des poids w1 et w2 par rétro-propagation.
    grad_y_pred = 2.0 * (y_pred - y)
    grad_w2 = h_relu.t().mm(grad_y_pred)
    grad_h_relu = grad_y_pred.mm(w2.t())
    grad_h = grad_h_relu.clone()
    grad_h[h < 0] = 0
    grad_w1 = x.t().mm(grad_h)

    #Mettre à jour les poids en utilisant la méthode de descente de gradient
    w1 -= learning_rate * grad_w1
    w2 -= learning_rate * grad_w2

Même avec ce code, vous pouvez voir que la valeur de la perte a diminué et que l'apprentissage progresse.

  1. Autograd

2.1. PyTorch: Tensors and autograd

Dans l'exemple ci-dessus, nous avons implémenté manuellement la propagation avant et arrière, mais vous pouvez utiliser le package autograd de PyTorch pour automatiser le calcul de la rétropropagation.

-Set requires_grad = True pour la variable (Tensor) pour laquelle vous voulez calculer le gradient. ・ Exécuter en arrière () Ces deux peuvent automatiser le calcul de rétropropagation.

import torch

dtype = torch.float
device = torch.device("cpu")
# device = torch.device("cuda:0") #Décommentez ici pour exécuter sur le GPU.

#N: taille du lot
# D_in: Nombre de dimensions d'entrée
#H: nombre de dimensions du calque caché
# D_out: nombre de dimensions de sortie
N, D_in, H, D_out = 64, 1000, 100, 10

#Créez un Tensor aléatoire pour contenir les données d'entrée et de l'enseignant.
# require_grad =Définissez sur False pour indiquer que le dégradé n'a pas besoin d'être calculé.
x = torch.randn(N, D_in, device=device, dtype=dtype)
y = torch.randn(N, D_out, device=device, dtype=dtype)

#Créez un Tensor aléatoire qui contient les poids.
# requires_grad =La valeur True indique que le dégradé sera calculé.
w1 = torch.randn(D_in, H, device=device, dtype=dtype, requires_grad=True)
w2 = torch.randn(H, D_out, device=device, dtype=dtype, requires_grad=True)

learning_rate = 1e-6
for t in range(500):
    #Propagation vers l'avant:Calculer la valeur prévue y en utilisant l'arithmétique de Tensor
    #Valeur intermédiaire h car la rétropropagation n'est pas calculée manuellement_relu n'a pas besoin d'être conservé
    y_pred = x.mm(w1).clamp(min=0).mm(w2)

    #Calculer et afficher les pertes à l'aide des opérations de Tensor
    #La perte est la forme (1,) Tenseur
    # loss.item()Obtient la valeur scalaire contenue dans la perte
    loss = (y_pred - y).pow(2).sum()
    if t % 100 == 99:
        print(t, loss.item())

    #Utilisez autograd pour calculer la rétropropagation
    # backward()A besoin_grad =Calcule la pente de perte pour tous les tenseurs qui sont vrais
    #Après cet appel, w1.grad et w2.grad est w1 respectivement,Devient un Tensor qui détient le gradient de w2
    loss.backward()

    #Mettez à jour manuellement les poids en utilisant la méthode de descente la plus raide
    #Exiger pour le poids_grad =Parce qu'il y a vrai, torche.no_grad()Empêche la mise à jour du graphique de calcul avec
    # torch.optim.Vous pouvez faire de même avec SGD
    with torch.no_grad():
        w1 -= learning_rate * w1.grad
        w2 -= learning_rate * w2.grad

        #Après avoir mis à jour les poids, définissez manuellement le dégradé sur zéro
        w1.grad.zero_()
        w2.grad.zero_()

Bien que pas dans le didacticiel, illustrons le graphique de calcul de rétropropagation. Les graphiques de calcul peuvent être illustrés en utilisant torchviz. Si vous utilisez colaboratory, vous devez l'installer.

!pip install torchviz

PyTorch: une petite modification de l'exemple de code Tensors. Arrêtez la boucle pour que le gradient ne soit calculé qu'une seule fois.

#Créer une entrée aléatoire et des données sur les enseignants
x = torch.randn(N, D_in, device=device, dtype=dtype)
y = torch.randn(N, D_out, device=device, dtype=dtype)

#Initialisez le poids avec une valeur aléatoire
w1 = torch.randn(D_in, H, device=device, dtype=dtype, requires_grad=True)
w2 = torch.randn(H, D_out, device=device, dtype=dtype, requires_grad=True)

#Propagation vers l'avant:Calcule la valeur prévue y avec la valeur de poids actuelle
h = x.mm(w1)
h_relu = h.clamp(min=0)
y_pred = h_relu.mm(w2)

#Calcule et génère la perte
loss = (y_pred - y).pow(2).sum().item()

#En référence à la valeur de perte, calculez le gradient des poids w1 et w2 par rétro-propagation.
grad_y_pred = 2.0 * (y_pred - y)
grad_w2 = h_relu.t().mm(grad_y_pred)
grad_h_relu = grad_y_pred.mm(w2.t())
grad_h = grad_h_relu.clone()
grad_h[h < 0] = 0
grad_w1 = x.t().mm(grad_h)

Diagrammez le graphe de calcul avec make_dot de torchviz. Illustre la propagation vers l'avant et le gradient. param_dict n'est pas obligatoire, mais il vous permet d'écrire des noms de variables dans le diagramme.

#Le graphe de calcul de la propagation vers l'avant est illustré.
from torchviz import make_dot
param_dict = {'w1': w1, 'w2': w2}
make_dot(loss, param_dict)

#Le graphique de calcul du gradient de w1 est affiché.
make_dot(grad_w1, param_dict)

#Le graphique de calcul du gradient de w2 est affiché.
make_dot(grad_w2, param_dict)

Le graphique de calcul est ci-dessous.

PyTorch_Tensors_make_dot.png

De même, modifiez l'exemple de code dans PyTorch: Tensors et autograd afin que le gradient ne soit calculé qu'une seule fois. La spécification de create_graph = True à l'exécution () préserve le graphe dérivé.

import torch

#Créez un Tensor aléatoire pour contenir les données d'entrée et de l'enseignant.
# require_grad =Définissez sur False pour indiquer que le dégradé n'a pas besoin d'être calculé.
x = torch.randn(N, D_in, device=device, dtype=dtype)
y = torch.randn(N, D_out, device=device, dtype=dtype)

#Créez un Tensor aléatoire qui contient les poids.
# requires_grad =La valeur True indique que le dégradé sera calculé.
w1 = torch.randn(D_in, H, device=device, dtype=dtype, requires_grad=True)
w2 = torch.randn(H, D_out, device=device, dtype=dtype, requires_grad=True)

#Propagation vers l'avant:Calculer la valeur prévue y en utilisant l'arithmétique de Tensor
#Valeur intermédiaire h car la rétropropagation n'est pas calculée manuellement_relu n'a pas besoin d'être conservé
y_pred = x.mm(w1).clamp(min=0).mm(w2)

#Calculer et afficher les pertes à l'aide des opérations de Tensor
#La perte est la forme (1,) Tenseur
# loss.item()Obtient la valeur scalaire contenue dans la perte
loss = (y_pred - y).pow(2).sum()

#Utilisez autograd pour calculer la rétropropagation
# backward()A besoin_grad =Calcule la pente de perte pour tous les tenseurs qui sont vrais
#Après cet appel, w1.grad et w2.grad est w1 respectivement,Devient un Tensor qui détient le gradient de w2
loss_backward = loss.backward(create_graph=True)

De même, le gradient calculé par propagation directe et autograde est illustré.

#Le graphe de calcul de la propagation vers l'avant est illustré.
param_dict = {'w1': w1, 'w2': w2}
make_dot(loss, param_dict)

#Le graphique de calcul du gradient de w1 est affiché.
make_dot(w1.grad, param_dict)

#Le graphique de calcul du gradient de w2 est affiché.
make_dot(w2.grad, param_dict)

La propagation vers l'avant est la même. La forme de la rétropropagation est légèrement différente, mais vous pouvez voir que le calcul de la rétropropagation se fait automatiquement par autograd.

PyTorch_Tensorsandautograd_make_dot.png

2.2. PyTorch: Defining new autograd functions

Dans PyTorch, vous pouvez définir votre propre fonction (opérateur) en définissant une sous-classe de torch.autograd.Function. Implémentez les deux méthodes suivantes dans la sous-classe.

Dans cet exemple, nous définissons un réseau à deux niveaux avec notre propre fonction, ce qui signifie la fonction ReLU.

import torch

class MyReLU(torch.autograd.Function):
    """
    torch.autograd.Fonction de sous-classe et
En mettant en œuvre des chemins vers l'avant et vers l'arrière qui fonctionnent avec Tensors
Vous pouvez implémenter votre propre fonction d'autogradation personnalisée.
    """

    @staticmethod
    def forward(ctx, input):
        """
Dans la passe avant, il reçoit le Tensor contenant l'entrée et
Renvoie le Tensor contenant la sortie.
ctx est un objet pour les calculs de rétropropagation.
        ctx.save_for_Utilisez la méthode inverse
Vous pouvez mettre en cache des objets.
        """
        ctx.save_for_backward(input)
        return input.clamp(min=0)

    @staticmethod
    def backward(ctx, grad_output):
        """
En arrière, il reçoit un Tensor contenant le gradient de perte par rapport à la sortie.
Vous devez calculer le gradient de perte pour l'entrée.
        """
        input, = ctx.saved_tensors
        grad_input = grad_output.clone()
        grad_input[input < 0] = 0
        return grad_input


dtype = torch.float
device = torch.device("cpu")
# device = torch.device("cuda:0") #Décommentez ici pour exécuter sur le GPU.

#N: taille du lot
# D_in: Nombre de dimensions d'entrée
#H: nombre de dimensions du calque caché
# D_out: nombre de dimensions de sortie
N, D_in, H, D_out = 64, 1000, 100, 10

#Créez un Tensor aléatoire pour contenir les données d'entrée et de l'enseignant.
x = torch.randn(N, D_in, device=device, dtype=dtype)
y = torch.randn(N, D_out, device=device, dtype=dtype)

#Créez un Tensor aléatoire qui contient les poids.
w1 = torch.randn(D_in, H, device=device, dtype=dtype, requires_grad=True)
w2 = torch.randn(H, D_out, device=device, dtype=dtype, requires_grad=True)

learning_rate = 1e-6
for t in range(500):
    #Pour appliquer une fonction, une fonction.Utilisez la méthode Apply.
    relu = MyReLU.apply

    #Propagation vers l'avant:Calculez la valeur prévue y à l'aide d'une fonction d'autogradation personnalisée
    y_pred = relu(x.mm(w1)).mm(w2)

    #Calculer et afficher la perte
    loss = (y_pred - y).pow(2).sum()
    if t % 100 == 99:
        print(t, loss.item())

    #Utilisez autograd pour calculer la rétropropagation
    loss.backward()

    #Mettre à jour les poids en utilisant la méthode de descente la plus raide
    with torch.no_grad():
        w1 -= learning_rate * w1.grad
        w2 -= learning_rate * w2.grad

        #Après avoir mis à jour les poids, définissez manuellement le dégradé sur zéro
        w1.grad.zero_()
        w2.grad.zero_()

Visualisons également la fonction d'origine. Comme auparavant, assurez-vous qu'il n'est traité qu'une seule fois.

#Créez un Tensor aléatoire pour contenir les données d'entrée et de l'enseignant.
x = torch.randn(N, D_in, device=device, dtype=dtype)
y = torch.randn(N, D_out, device=device, dtype=dtype)

#Créez un Tensor aléatoire qui contient les poids.
w1 = torch.randn(D_in, H, device=device, dtype=dtype, requires_grad=True)
w2 = torch.randn(H, D_out, device=device, dtype=dtype, requires_grad=True)

#Pour appliquer une fonction, une fonction.Utilisez la méthode Apply.
relu = MyReLU.apply

#Propagation vers l'avant:Calculez la valeur prévue y à l'aide d'une fonction d'autogradation personnalisée
y_pred = relu(x.mm(w1)).mm(w2)

#Calculer et afficher la perte
loss = (y_pred - y).pow(2).sum()

#Utilisez autograd pour calculer la rétropropagation
loss.backward(create_graph=True)

PyTorch_Definingnewautogradfunctions_make_dot.png

At-il un graphique de calcul similaire?

Continuer

Cela fait longtemps, alors j'aimerais diviser PyTorch: nn dans la deuxième partie.

Histoire

2020/05/27 Première édition publiée

Recommended Posts

[Tutoriel PyTorch ⑤] Apprentissage de PyTorch avec des exemples (Partie 2)
[Tutoriel PyTorch ⑤] Apprentissage de PyTorch avec des exemples (Partie 1)
[Exemple d'amélioration de Python] Apprentissage de Python avec Codecademy
Prédire la demande de puissance avec l'apprentissage automatique, partie 2
J'ai essayé d'implémenter DeepPose avec PyTorch PartⅡ
Apprentissage automatique avec Pytorch sur Google Colab
Report_Apprentissage approfondi (partie 2)
Report_Apprentissage approfondi (partie 1)
Jouez avec PyTorch
Report_Apprentissage approfondi (partie 2)
Validation croisée avec PyTorch
À partir de PyTorch
Apprentissage automatique à partir de Python Personal Memorandum Part2
Apprentissage automatique à partir de Python Personal Memorandum Part1
Résumé du didacticiel d'apprentissage automatique
Machine learning facile avec AutoAI (partie 4) Jupyter Notebook
Utilisez RTX 3090 avec PyTorch
Apprendre Python avec ChemTHEATER 03
"Orienté objet" appris avec python
Apprendre Python avec ChemTHEATER 05-1
[Tutoriel PyTorch ①] Qu'est-ce que PyTorch?
Apprendre Python avec ChemTHEATER 02
[Tutoriel PyTorch ⑦] Visualisation des modèles, des données et de la formation avec Tensorboard
Installer la diffusion de la torche avec PyTorch 1.7
[Tutoriel PyTorch ③] RÉSEAUX NEURAUX
Mémo du didacticiel FastAPI, partie 1
Apprentissage automatique pour apprendre avec Nogisaka 46 et Keyakizaka 46 Partie 1 Introduction
Ingénierie des fonctionnalités pour l'apprentissage automatique à partir de la partie 3 Échelle collaborative de Google
Traitement d'image avec Python (partie 2)
L'apprentissage automatique appris avec Pokemon
Etudier Python avec freeCodeCamp part1
Images en bordure avec python Partie 1
Apprenez librosa avec un tutoriel 1
Essayez l'apprentissage en profondeur avec TensorFlow
Essayez Auto Encoder avec Pytorch
Python: Apprentissage supervisé: Hyper Paramètres Partie 1
Apprentissage amélioré à partir de Python
À propos de l'apprentissage avec Google Colab
Apprentissage automatique avec Python! Préparation
[Tutoriel PyTorch ④] FORMATION D'UN CLASSIFICATEUR
Apprentissage profond du noyau avec Pyro
Lancez-vous avec Django! ~ Tutoriel ④ ~
Tutoriel [PyTorch] (version japonaise) ② ~ AUTOGRAD ~
Etudier Python avec freeCodeCamp part2
Implémenter le GPU PyTorch + avec Docker
Traitement d'image avec Python (partie 1)
Lancez-vous avec Django! ~ Tutoriel ⑥ ~
L'apprentissage le plus rapide sous Linux avec AWS
Traitement d'image avec Python (3)
PyTorch avec AWS Lambda [importation Lambda]
Python: apprentissage supervisé: Hyper Paramètre partie 2
Tutoriel [PyTorch] (version japonaise) ① ~ Tensol ~
Grattage avec Selenium + Python Partie 2
[Tutoriel PyTorch ②] Autograd: différenciation automatique
Tutoriel sur le réseau neuronal (CNN) de Pytorch 1.3.1.
Prédiction de la moyenne Nikkei avec Pytorch
Effectuer un fractionnement stratifié avec PyTorch
Commencer avec l'apprentissage automatique Python