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.
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()
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?".
2020/07/10 Première édition publiée 2020/07/10 Correction de lien de la première partie
Recommended Posts