Bonjour. Je suis un nouvel employé d'une certaine société informatique. Ici, j'ai utilisé Pytorch, une bibliothèque d'apprentissage automatique open source, pour décrire un programme d'apprentissage de modèle de régression pour la prédiction des ondes sinusoïdales comme exemple. (Ce n'est pas une prévision chronologique ... j'aimerais bientôt faire une prévision chronologique.)
Alors que le chainer se déplace vers le pytorch Il était tard, mais je l'ai écrit parce que je voulais rattraper cette fois. Il décrit également les points qui m'ont fait me sentir différent.
C'est comme la migration de pytorch de l'article suivant que j'ai écrit plus tôt. [Maintenant, apprenons attentivement les ondes de péché avec le chainer] 1
Si vous avez des suggestions ou des questions, n'hésitez pas à les laisser dans la section commentaires.
Le code est sur le GitHub ci-dessous. kazu-ojisan/NN-pytorch_PredictSinWave
macOS Catalina 10.15.3 conda 4.7.12 python 3.7.6 (Créer un environnement virtuel avec conda) pytorch 1.4.0
L'installation de pytorch est tuée en quelques secondes. Si vous sélectionnez votre propre environnement sur le site officiel ci-dessous, Il affichera la commande d'installation. [Pytorch -Site officiel-] 3
--Couche intermédiaire: 2 couches (nombre d'unités: 10) --Fonction d'activation: ReLU
Vous trouverez ci-dessous les URL auxquelles j'ai fait référence pour la mise en œuvre.
Le module pytorch est OK tant que ce qui suit est importé au minimum.
test.py
import numpy as np #Tableau
import time #temps
from matplotlib import pyplot as plt #Graphique
import os #Pour créer un dossier
# pytorch
import torch as T
import torch.nn as nn #configuration de couche
import torch.nn.functional as F #Fonction d'activation
from torch import optim #Fonction d'optimisation
Un simple jeu de données y = sin (x) (x, y).
python
# y=sin(x)Créer N ensembles de données de
def get_data(N, Nte):
x = np.linspace(0, 2 * np.pi, N+Nte)
#Divisez en données d'entraînement et en données de test
ram = np.random.permutation(N+Nte)
x_train = np.sort(x[ram[:N]])
x_test = np.sort(x[ram[N:]])
t_train = np.sin(x_train)
t_test = np.sin(x_test)
return x_train, t_train, x_test, t_test
La seule différence avec le chainer est qu'il remplace le module sans aucune différence particulière. Le type de données géré par pytorch est "Type Tensor", donc la conversion est nécessaire. (Type valable dans le chainer)
.py
class SIN_NN(nn.Module):
def __init__(self, h_units, act):
super(SIN_NN, self).__init__()
self.l1=nn.Linear(1, h_units[0])
self.l2=nn.Linear(h_units[0], h_units[1])
self.l3=nn.Linear(h_units[1], 1)
if act == "relu":
self.act = F.relu
elif act == "sig":
self.act = F.sigmoid
def __call__(self, x, t):
x = T.from_numpy(x.astype(np.float32).reshape(x.shape[0],1))
t = T.from_numpy(t.astype(np.float32).reshape(t.shape[0],1))
y = self.forward(x)
return y, t
def forward(self, x):
h = self.act(self.l1(x))
h = self.act(self.l2(h))
h = self.l3(h)
return h
J'ai senti la différence avec Chainer (plus de détails plus tard) (1) model.parameter () est requis comme premier argument de la fonction d'optimisation (2) Puisque MSE est défini dans Class, il ne peut être utilisé que si une instance est créée. ③ Basculer entre le mode apprentissage et le mode test par "model.train ()" et "model.eval ()" (Il n'y a pas de problème même si ce n'est pas cette fois.) ④ L'extension du modèle est ".pt" ou ".pth"
.py
def training(N, Nte, bs, n_epoch, h_units, act):
#Obtenez l'ensemble de données
x_train, t_train, x_test, t_test = get_data(N, Nte)
x_test_torch = T.from_numpy(x_test.astype(np.float32).reshape(x_test.shape[0],1))
t_test_torch = T.from_numpy(t_test.astype(np.float32).reshape(t_test.shape[0],1))
#Configuration du modèle
model = SIN_NN(h_units, act)
optimizer = optim.Adam(model.parameters())
MSE = nn.MSELoss()
#baie de stockage de perte
tr_loss = []
te_loss = []
#Créer un annuaire
if os.path.exists("Results/{}/Pred".format(act)) == False:
os.makedirs("Results/{}/Pred".format(act))
#Mesurer le temps
start_time = time.time()
print("START")
#Boucle pour le nombre d'apprentissage
for epoch in range(1, n_epoch + 1):
model.train()
perm = np.random.permutation(N)
sum_loss = 0
for i in range(0, N, bs):
x_batch = x_train[perm[i:i + bs]]
t_batch = t_train[perm[i:i + bs]]
optimizer.zero_grad()
y_batch, t_batch = model(x_batch, t_batch)
loss = MSE(y_batch, t_batch)
loss.backward()
optimizer.step()
sum_loss += loss.data * bs
#Calculer la moyenne des erreurs d'apprentissage
ave_loss = sum_loss / N
tr_loss.append(ave_loss)
#Erreur de test
model.eval()
y_test_torch = model.forward(x_test_torch)
loss = MSE(y_test_torch, t_test_torch)
te_loss.append(loss.data)
#Enregistrer le modèle entraîné
T.save(model, "Results/model.pt")
model.parameters () stocke les poids et le nombre d'unités, qui sont des informations sur le modèle. Document officiel: [model.parameters ()] 9 Si vous essayez de sortir en fonction du document, il sera imprimé comme suit.
$ python exportModelParam.py
<class 'torch.Tensor'> torch.Size([10, 1])
<class 'torch.Tensor'> torch.Size([10])
<class 'torch.Tensor'> torch.Size([10, 10])
<class 'torch.Tensor'> torch.Size([10])
<class 'torch.Tensor'> torch.Size([1, 10])
<class 'torch.Tensor'> torch.Size([1])
La documentation officielle pour "MSE Loss" de Pytorch et "mean_squared_error" de Chainer a du sens. Pytorch:Pytorch -SOURCE CODE FOR TORCH.NN.MODULES.LOSS-
MSELoss.py
class MSELoss(_Loss):
Chainer:Chainer -mean_squared_error.py-
mean_squared_error.py
def mean_squared_error(x0, x1):
Si vous le mettez en mode test avec .eval, l'abandon et la normalisation par lots seront désactivés et ce sera une spécification de test. Ce code n'utilise pas Dropout ou Batch Normalization, il fonctionne donc de la même manière sans cela. Cependant, si vous envisagez d'utiliser pytorch à l'avenir, je pense qu'il vaut mieux ajouter une habitude d'écrire.
Voir ci-dessous. Tutorials > Saving and Loading Models
Graphique d'erreur
Graphique de prédiction des données de test epoch:20 epoch:200
Trouble Shooting
Le code est sur le GitHub ci-dessous. kazu-ojisan/NN-pytorch_PredictSinWave
Selon les informations, il était assez similaire au chainer. J'ai senti que Pytorch était bien équipé. Si vous avez des suggestions, n'hésitez pas à les laisser dans la section commentaires car elles manquent encore de compréhension.
Recommended Posts