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

introduction

Ceci est le 5ème volet de PyTorch Tutoriel officiel après Dernière fois. Ceci est la deuxième partie de Apprendre PyTorch avec des exemples. Partie 1 est ici.

  1. nn module

3.1. PyTorch: nn

Vous ne pouvez pas modéliser un réseau de neurones avec autograd seul. Le package nn est utilisé pour construire le modèle. Le package nn comprend également une classe Sequential qui définit les couches d'entrée, masquées et de sortie, ainsi qu'une fonction de perte. L'exemple ci-dessous utilise le package nn pour implémenter un réseau à deux niveaux.

import torch

#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 d'enseignant
x = torch.randn(N, D_in)
y = torch.randn(N, D_out)

# Use the nn package to define our model as a sequence of layers. nn.Sequential
# is a Module which contains other Modules, and applies them in sequence to
# produce its output. Each Linear Module computes output from input using a
# linear function, and holds internal Tensors for its weight and bias.

#Utilisez le package nn pour définir le modèle comme une série de couches.
# nn.Sequential applique les autres modules en séquence pour générer le modèle.
#Linear utilise des fonctions linéaires pour calculer la sortie de l'entrée et les poids et biais
#Tenez le tenseur interne.
model = torch.nn.Sequential(
    torch.nn.Linear(D_in, H),
    torch.nn.ReLU(),
    torch.nn.Linear(H, D_out),
)

#Le package nn comprend également une fonction de perte.
#Cette fois, nous utiliserons l'erreur quadratique moyenne (MSE) comme fonction de perte.
loss_fn = torch.nn.MSELoss(reduction='sum')

learning_rate = 1e-4
for t in range(500):
    #Propagation directe: calcule la valeur prévue y en transmettant x au modèle.
    #Le module de classe de base__call__Pour remplacer l'opérateur
    #Il peut être appelé comme une fonction.
    #Dans ce cas, passez le tenseur de données d'entrée au module et générez le tenseur de données de sortie.
    y_pred = model(x)

    #Calcule et sort la perte.
    #Passer la valeur prédite de y et le tenseur des données de l'enseignant à la fonction de perte
    #Renvoie le tenseur contenant la perte.
    loss = loss_fn(y_pred, y)
    if t % 100 == 99:
        print(t, loss.item())

    #Définissez le dégradé sur zéro avant de calculer la rétropropagation.
    model.zero_grad()

    #Rétropropagation: calcule le gradient de perte.
    #En interne, les paramètres du module nécessitent_grad =Parce que c'est vrai
    #Calculez le gradient de tous les paramètres.
    loss.backward()

    #Mettez à jour les poids en utilisant la méthode de descente de gradient probabiliste.

    with torch.no_grad():
        for param in model.parameters():
            param -= learning_rate * param.grad

3.2. PyTorch: optim

Jusqu'à présent, j'ai calculé et mis à jour moi-même les poids du modèle comme suit:

param -= learning_rate * param.grad

Cette méthode de calcul est appelée méthode de descente de gradient stochastique. Il existe d'autres moyens de calculer les poids de modèle (optimer), et vous pouvez utiliser des algorithmes plus avancés tels que AdaGrad, RMSProp et Adam. Le package optim de PyTorch possède une variété d'algorithmes d'optimisation. L'exemple suivant définit le modèle dans le package nn comme dans l'exemple ci-dessus, mais utilise l'algorithme Adam dans le package optim pour mettre à jour les pondérations.

import torch

#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 d'enseignant
x = torch.randn(N, D_in)
y = torch.randn(N, D_out)

#Utilisez le package nn pour définir le modèle et la fonction de perte.
model = torch.nn.Sequential(
    torch.nn.Linear(D_in, H),
    torch.nn.ReLU(),
    torch.nn.Linear(H, D_out),
)
loss_fn = torch.nn.MSELoss(reduction='sum')

#Utilisez le package optim pour définir un algorithme d'optimisation (optimiseur) qui met à jour les pondérations des modèles.
#Nous utiliserons Adam ici.
#Le package optim contient de nombreux autres algorithmes d'optimisation.
#Le premier argument du constructeur Adam spécifie quel Tensor mettre à jour.
learning_rate = 1e-4
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
for t in range(500):
    #Propagation directe: calcule la valeur prévue y en transmettant x au modèle.
    y_pred = model(x)

    #Calcule et sort la perte.
    loss = loss_fn(y_pred, y)
    if t % 100 == 99:
        print(t, loss.item())

    #Mettre à zéro tous les gradients de la variable (poids) à mettre à jour avant de calculer la rétropropagation.
    #Cela est dû au fait que le dégradé est accumulé (non écrasé) à chaque appel en arrière.
    optimizer.zero_grad()

    #Rétropropagation: calcule le gradient de perte.
    loss.backward()

    #Les paramètres sont mis à jour lorsque vous appelez la fonction d'étape de l'optimiseur.
    optimizer.step()

3.3. PyTorch: Custom nn Modules

Si vous souhaitez créer un modèle complexe, vous pouvez sous-classer nn.Module. Vous pouvez définir votre propre module en remplaçant la fonction forward dans la sous-classe et en écrivant le processus de renvoi du Tensor de sortie depuis l'entrée Tensor. Dans cet exemple, nous allons implémenter un réseau à deux niveaux en tant que sous-classe de module personnalisé.

import torch

class TwoLayerNet(torch.nn.Module):
    def __init__(self, D_in, H, D_out):
        """
Dans le constructeur, deux nn.Instancier un module linéaire
Affectez-les en tant que variables membres.
        """
        super(TwoLayerNet, self).__init__()
        self.linear1 = torch.nn.Linear(D_in, H)
        self.linear2 = torch.nn.Linear(H, D_out)

    def forward(self, x):
        """
La fonction avant doit renvoyer un Tensor de sortie basé sur le Tensor d'entrée.
Vous pouvez utiliser les modules définis dans le constructeur.
        """
        h_relu = self.linear1(x).clamp(min=0)
        y_pred = self.linear2(h_relu)
        return y_pred


#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 d'enseignant
x = torch.randn(N, D_in)
y = torch.randn(N, D_out)

#Construire un modèle en instanciant le module de réseau neuronal défini ci-dessus
model = TwoLayerNet(D_in, H, D_out)

#Fonction de perte et algorithme d'optimisation(optimiseur)Est défini.
#Modèle d'argument SGD.parameters()Est membre de la classe définie
#2 nn.Il contient également les paramètres du module linéaire.
criterion = torch.nn.MSELoss(reduction='sum')
optimizer = torch.optim.SGD(model.parameters(), lr=1e-4)
for t in range(500):
    #Propagation directe: calcule la valeur prévue y en passant x au modèle.
    y_pred = model(x)

    #Calcule et sort la perte.
    loss = criterion(y_pred, y)
    if t % 100 == 99:
        print(t, loss.item())

    #Définissez le dégradé sur zéro, calculez la rétropropagation et mettez à jour les poids.
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

3.4. PyTorch: Control Flow + Weight Sharing

Implémentez un modèle spécial comme exemple de graphique dynamique et de partage de poids. Le réseau ReLU suivant calcule en sélectionnant un nombre aléatoire de 0 à 3 avec la fonction avant et en partageant le même poids entre plusieurs couches cachées. Implémentez ce modèle en tant que sous-classe de module.

import random
import torch


class DynamicNet(torch.nn.Module):
    def __init__(self, D_in, H, D_out):
        """
Dans le constructeur, les trois nn utilisés dans la fonction forward.Instance linéaire(Couche d'entrée, couche cachée, couche de sortie)Créer un.
        """
        super(DynamicNet, self).__init__()
        self.input_linear = torch.nn.Linear(D_in, H)
        self.middle_linear = torch.nn.Linear(H, H)
        self.output_linear = torch.nn.Linear(H, D_out)

    def forward(self, x):
        """
La fonction avant sélectionne au hasard une valeur de 0 à 3 fois.
        middle_Réutilisez le module linéaire plusieurs fois pour calculer le traitement des couches masquées.

Puisque l'autograd est un graphe de calcul dynamique, il est construit pendant la propagation vers l'avant.
Par conséquent, vous pouvez écrire un traitement Python normal tel que des boucles et des instructions conditionnelles dans la fonction forward.

Vous pouvez utiliser le même module plusieurs fois lors de la définition d'un graphe de calcul.
Il s'agit d'une amélioration par rapport à Lua Torch, où chaque module ne pouvait être utilisé qu'une seule fois.
        """
        h_relu = self.input_linear(x).clamp(min=0)
        for _ in range(random.randint(0, 3)):
            h_relu = self.middle_linear(h_relu).clamp(min=0)
            print(str(_))
        print(h_relu.size())
        y_pred = self.output_linear(h_relu)
        return y_pred


#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 d'enseignant
x = torch.randn(N, D_in)
y = torch.randn(N, D_out)

#Construire un modèle en instanciant le module de réseau neuronal défini ci-dessus
model = DynamicNet(D_in, H, D_out)

#Créez une fonction de perte et un optimiseur.
#Ce modèle est formé par la méthode habituelle de descente de gradient stochastique(Converger)C'est difficile, alors spécifiez l'élan.
criterion = torch.nn.MSELoss(reduction='sum')
optimizer = torch.optim.SGD(model.parameters(), lr=1e-4, momentum=0.9)
for t in range(500):
    #Propagation directe: calcule la valeur prévue y en transmettant x au modèle.
    y_pred = model(x)

    #Calcule et sort la perte.
    loss = criterion(y_pred, y)
    if t % 100 == 99:
        print(t, loss.item())

    #Définissez le dégradé sur zéro, calculez la rétropropagation et mettez à jour les poids.
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

À la fin

C'est le contenu du cinquième tutoriel de PyTorch, "Apprendre PyTorch avec des exemples". J'ai pu approfondir ma compréhension des packages autograd, torch.nn et torch.optim.

La prochaine fois, j'aimerais continuer avec le sixième tutoriel "Qu'est-ce que torch.nn vraiment?".

Histoire

2020/07/10 Première édition publiée 2020/07/10 Correction de lien de la première partie

Recommended Posts

[Tutoriel PyTorch ⑤] Apprentissage de PyTorch avec des exemples (Partie 2)
[Tutoriel PyTorch ⑤] Apprentissage de PyTorch avec des exemples (Partie 1)
Démineur d'apprentissage automatique avec PyTorch
Essayez l'apprentissage en profondeur avec TensorFlow Partie 2
[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
"Orienté objet" appris avec python
[Tutoriel PyTorch ①] Qu'est-ce que PyTorch?
Apprendre Python avec ChemTHEATER 02
bac à sable avec neo4j partie 10
Tutoriel CIFAR-10 avec Keras
Apprendre Python avec ChemTHEATER 01
[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
Essayez l'apprentissage en profondeur avec TensorFlow
Lancez-vous avec Django! ~ Tutoriel ⑤ ~
Grattage avec Selenium + Python Partie 1
Essayez Auto Encoder avec Pytorch
Python: Apprentissage supervisé: Hyper Paramètres Partie 1
Apprentissage amélioré à partir de Python
Essayez d'implémenter XOR avec PyTorch
À 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 ~
Essayez le Deep Learning avec FPGA
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
Résolution de Nampre avec Python (partie 2)
Prédiction de la moyenne Nikkei avec Pytorch 2
Traitement d'image avec Python (3)
PyTorch avec AWS Lambda [importation Lambda]