Dans le précédent «Introduction au Deep Learning (1) -Understanding and using Chainer-», nous avons résumé comment utiliser Chainer. .. Si vous suivez la référence, vous découvrirez comment l'utiliser. Lorsque j'étudie l'apprentissage automatique, j'assume un problème de régression simple et je décide moi-même que je peux le comprendre et l'utiliser lorsque je peux créer un modèle de prédiction pour celui-ci.
Par conséquent, cette fois, spécifiquement, nous allons générer des données pour une fonction sin non linéaire et effectuer une régression non linéaire en utilisant un modèle construit avec Chainer. Si vous avez terminé toutes les étapes jusqu'à ce point, vous pourrez peut-être comprendre même si vous passez à la version avancée telle que la discrimination d'image.
・ Système d'exploitation: Mac OS X EL Capitan (10.11.5) · Python 2.7.12: Anaconda 4.1.1 (x86_64) ・ Chainer 1.12.0
Comme le montre l'image ci-dessous, construisez un modèle de régression non linéaire capable de capturer parfaitement la fonction sin.
MyChain.py
# -*- coding: utf-8 -*-
from chainer import Chain
import chainer.links as L
import chainer.functions as F
class MyChain(Chain):
def __init__(self):
super(MyChain, self).__init__(
l1 = L.Linear(1, 100),
l2 = L.Linear(100, 30),
l3 = L.Linear(30, 1)
)
def predict(self, x):
h1 = F.relu(self.l1(x))
h2 = F.relu(self.l2(h1))
return self.l3(h2)
example.py
# -*- coding: utf-8 -*-
#Calcul numérique lié
import math
import random
import numpy as np
import matplotlib.pyplot as plt
# chainer
from chainer import Chain, Variable
import chainer.functions as F
import chainer.links as L
from chainer import optimizers
from MyChain import MyChain
#Graine aléatoire fixe
random.seed(1)
#Génération d'échantillons de données
#La fonction sin comme fonction vraie
x, y = [], []
for i in np.linspace(-3,3,100):
x.append([i])
y.append([math.sin(i)]) #Vraie fonction
#Déclarer à nouveau comme variable de chaîne
x = Variable(np.array(x, dtype=np.float32))
y = Variable(np.array(y, dtype=np.float32))
#Déclarer le modèle NN
model = MyChain()
#Calcul de la fonction de perte
#Erreur auto-quadrillée dans la fonction de perte(MSE)utilisation
def forward(x, y, model):
t = model.predict(x)
loss = F.mean_squared_error(t, y)
return loss
#optimiseur de chaîne
#Adam est utilisé pour l'algorithme d'optimisation
optimizer = optimizers.Adam()
#Passer les paramètres du modèle à l'optimiseur
optimizer.setup(model)
#Répéter l'apprentissage des paramètres
for i in range(0,1000):
loss = forward(x, y, model)
print(loss.data) #Afficher le MSE actuel
optimizer.update(forward, x, y, model)
#terrain
t = model.predict(x)
plt.plot(x.data, y.data)
plt.scatter(x.data, t.data)
plt.grid(which='major',color='gray',linestyle='-')
plt.ylim(-1.5, 1.5)
plt.xlim(-4, 4)
plt.show()
Générez des données sur les enseignants pour créer ce modèle de régression non linéaire. Cette fois, nous utiliserons la fonction sin avec 1 entrée et 1 sortie.
#Génération d'échantillons de données
#La fonction sin comme fonction vraie
x, y = [], []
for i in np.linspace(-3,3,100):
x.append([i])
y.append([math.sin(i)]) #Vraie fonction
#Déclarer à nouveau comme variable de chaîne
x = Variable(np.array(x, dtype=np.float32))
y = Variable(np.array(y, dtype=np.float32))
Créez un modèle de Deep Learning avec Chainer. Cette fois, nous avons une structure à quatre couches composée d'une couche d'entrée, d'une couche cachée 1, d'une couche cachée 2 et d'une couche de sortie. J'ai décidé le nombre de nœuds de manière appropriée (j'ai écrit précédent ici, mais c'est une expérience et une intuition). Si vous êtes intéressé, vous pouvez modifier la valeur ici. La raison pour laquelle il y a deux couches cachées est que lorsque je suis revenu à une couche, les caractéristiques n'étaient pas bien capturées, alors je l'ai encore augmentée.
MyChain.py
# -*- coding: utf-8 -*-
from chainer import Chain
import chainer.links as L
import chainer.functions as F
class MyChain(Chain):
def __init__(self):
super(MyChain, self).__init__(
l1 = L.Linear(1, 100),
l2 = L.Linear(100, 30),
l3 = L.Linear(30, 1)
)
def predict(self, x):
h1 = F.relu(self.l1(x))
h2 = F.relu(self.l2(h1))
return self.l3(h2)
Le fait est que vous utilisez relu pour la fonction d'activation. Il n'y a pas si longtemps, il était standard d'utiliser la fonction sigmoïde pour cette fonction d'activation, mais récemment, lors de l'apprentissage des paramètres par la méthode de propagation d'erreur, le problème que le taux d'apprentissage diminue à mesure qu'il va vers l'arrière. Il semble que relu soit souvent utilisé pour éviter. Je ne connais ce domaine que par le ressenti, donc j'ai besoin d'étudier un peu plus. Il existe divers autres articles de commentaires sur la fonction d'activation, veuillez donc les consulter. Référence: [Machine learning] J'expliquerai en essayant le framework d'apprentissage profond Chainer.
J'ai essayé de voir ce qui se passait dans une situation où je n'avais pas du tout appris. Je pense que vous pourrez saisir le ressenti général en regardant non seulement le résultat final mais aussi les progrès.
##Déclarer le modèle NN
model = MyChain()
#terrain
t = model.predict(x)
plt.plot(x.data, y.data)
plt.scatter(x.data, t.data)
plt.grid(which='major',color='gray',linestyle='-')
plt.ylim(-1.5, 1.5)
plt.xlim(-4, 4)
plt.show()
Dans la situation non apprise, vous pouvez voir que les caractéristiques de la fonction vraie ne sont pas du tout capturées.
Pour entraîner les paramètres, définissez d'abord la fonction de perte. Cette fois, nous utiliserons l'erreur quadratique moyenne (MSE) comme fonction de perte.
{\rm MSE} = \dfrac{1}{N} \sum_{n=1}^{N} \left( \hat{y}_{n} - y_{n} \right)^{2}
#Calcul de la fonction de perte
#Erreur auto-quadrillée dans la fonction de perte(MSE)utilisation
def forward(x, y, model):
t = model.predict(x)
loss = F.mean_squared_error(t, y)
return loss
En définissant cette fonction de perte, Chainer peut calculer automatiquement le gradient de l'optimiseur.
#optimiseur de chaîne
#Adam est utilisé pour l'algorithme d'optimisation
optimizer = optimizers.Adam()
#Passer les paramètres du modèle à l'optimiseur
optimizer.setup(model)
#Mise à jour du dégradé
optimizer.update(forward, x, y, model)
C'est la fin du flux de base.
En répétant plusieurs fois le précédent ```optimizer.update () '' ``, il convergera vers un bon paramètre. Cette fois, les données des enseignants sont entraînées plusieurs fois avec les mêmes données, mais à l'origine, en tant que données par lots, certaines sont extraites de l'échantillon de population, elles sont formées en tant que données d'enseignants et un autre échantillon est regroupé au cycle suivant. Le flux consiste à les utiliser comme données.
#Répéter l'apprentissage des paramètres
for i in range(0,1000):
loss = forward(x, y, model)
print(loss.data) #Afficher le MSE actuel
optimizer.update(forward, x, y, model)
Vous pouvez voir que l'erreur auto-quadrillée diminue à mesure que l'apprentissage est répété. Après avoir terminé la formation, j'ai pu me rapprocher de la fonction de manière très fluide.
Nous vous attendons pour nous suivre! Qiita: Carat Yoshizaki twitter:@carat_yoshizaki Blog Hatena: Blog Carat COO Page d'accueil: Carat
Service de professeur à domicile "Kikagaku" où vous pouvez apprendre l'apprentissage automatique en tête à tête N'hésitez pas à nous contacter si vous êtes intéressé par "Kikagaku" où vous pouvez apprendre "mathématiques → programmation → application Web" à la fois.
Recommended Posts