L'apprentissage est une fonction du réseau neuronal (apprentissage profond). J'ai essayé de comprendre à partir de zéro les calculs du modèle qui sont effectués pour augmenter la valeur prédictive du modèle prédictif. Mis en œuvre sans utiliser de bibliothèque d'apprentissage automatique.
Dans l'article précédent, j'ai résumé les implications de l'apprentissage dans les réseaux de neurones, la fonction de perte nécessaire pour améliorer la précision du modèle et le concept de différenciation. https://qiita.com/Fumio-eisan/items/c4b5b7da5b5976d09504 Cette fois, je voudrais résumer la seconde moitié de l'implémentation au réseau de neurones.
Cette fois aussi, j'ai fait référence au manuel d'apprentissage profond d'O'Reilly. C'est très facile à comprendre. https://www.oreilly.co.jp/books/9784873117584/
Le plan est comme suit.
Dans l'article précédent, nous avons confirmé qu'il est nécessaire de minimiser la fonction de perte afin d'optimiser le modèle. Nous avons également montré que la différenciation des fonctions est le moyen de la minimiser. Pensons maintenant à optimiser les paramètres du modèle en utilisant réellement la différenciation de cette fonction.
En différenciant une fonction, vous pouvez connaître la direction dans laquelle la valeur de cette fonction diminue. La méthode du dégradé avance d'une certaine distance dans la direction du dégradé à partir de l'emplacement actuel. Et cela signifie trouver le même dégradé à la destination et procéder dans le sens du dégradé. ** Aller vers la valeur minimale s'appelle la méthode de descente de gradient, et aller vers la valeur maximale s'appelle la méthode de montée de gradient. ** **
Ce qui précède est une expression mathématique de la méthode du gradient. η représente le nombre de mises à jour et est appelé le ** taux d'apprentissage **. Affiche le nombre de paramètres mis à jour dans un apprentissage. Si ce taux d'apprentissage est trop faible, il faudra du temps pour s'approcher de la valeur minimale. Au contraire, si le taux d'apprentissage est élevé, la valeur minimale peut être dépassée. Par conséquent, vous devez trouver la bonne valeur pour chaque modèle. Je vais effectivement le mettre en œuvre. La fonction est celle utilisée dans la première moitié.
Je voudrais trouver la valeur minimale de cette fonction.
nn.ipynb
def gradient_descent(f,init_x, lr=0.01, step_num=100):
x = init_x
for i in range(step_num):
grad = numerical_gradient(f,x)
x -= lr*grad
return x
def function_2(x):
return x[0]**2+x[1]**2
Maintenant, laissez la valeur initiale être (x0, x1) = (-3,4) et utilisez la méthode du gradient pour trouver la valeur minimale. La vraie valeur minimale est prise lorsque (0,0).
nn.ipynb
init_x = np.array([-3.0,4.0])
gradient_descent(function_2, init_x = init_x, lr =0.1, step_num=100)
array([-6.11110793e-10, 8.14814391e-10])
Lorsque le taux d'apprentissage lr est de 0,1, le résultat ci-dessus est obtenu et on constate que la valeur est presque (0,0). Dans ce cas, on peut dire que l'apprentissage a réussi.
nn.ipynb
init_x = np.array([-3.0,4.0])
gradient_descent(function_2, init_x = init_x, lr =10, step_num=100)
array([-2.58983747e+13, -1.29524862e+12])
Ensuite, voici le cas où le taux d'apprentissage est fixé à 10. La valeur a divergé. Vous pouvez voir que ce n'est pas une bonne expérience d'apprentissage. Cette étude montre que le taux d'apprentissage optimal doit être défini pour chaque modèle.
Appliquez la méthode de recherche du gradient à un réseau de neurones. Dans le réseau neuronal, il est appliqué au gradient de la fonction de perte. Soit L la fonction de perte, et prenons une structure qui se différencie partiellement avec le poids w.
Je souhaite implémenter un réseau neuronal qui exécute la procédure suivante.
Mini lot Certaines données sont extraites aléatoirement des données d'entraînement (mini-batch). Le but est de minimiser la fonction de perte dans ce mini-lot.
Calcul du gradient Trouvez le gradient du paramètre de poids pour réduire la fonction de perte du mini-lot.
Mise à jour des paramètres Met à jour légèrement le paramètre de pondération dans la direction du gradient négatif.
Répéter Répétez les étapes 1 à 3 autant de fois que vous le souhaitez.
Maintenant, je voudrais implémenter un réseau neuronal à deux couches qui a en fait une fonction d'apprentissage. Le diagramme des composants du modèle mis en œuvre cette fois est le suivant.
Lors du réglage des paramètres principalement, cela est décidé par nn.ipynb. De plus, puisque cette fois nous utiliserons l'ensemble de données MNIST, il sera lu à partir de l'URL d'origine de M. Yann et al. Le calcul effectué par le réseau de neurones réel est décrit sur two_layer_net.py. Le réseau est comme illustré dans la figure ci-dessous.
Puisque MNIST est à l'origine des données d'image de 28 x 28 pixels, 28 x 28 = 784 nombres dimensionnels se trouvent dans la première couche d'entrée. Cette fois, le calque masqué est défini sur 100 et le calque de sortie final est défini sur 10 dimensions pour être craché sous forme de 10 types de nombres. Lors de l'exécution de ce calcul, la fonction sigmoïde, qui est la fonction d'activation, et la fonction softmax, qui est utilisée pour obtenir la probabilité finale, sont calculées en lisant les fonctions décrites dans encore une autre functions.py. Remplacez la valeur de sortie obtenue et l'indice correct des données de l'enseignant dans la fonction de perte. Ensuite, calculez avec la méthode numerical_garadient décrite dans gradient.py pour trouver le gradient du paramètre de poids. Afin de mettre à jour le gradient obtenu avec le paramètre de poids suivant, il est décrit de mettre à jour le nn.ipynb d'origine. La série d'opérations est répétée le nombre de fois.
Même si vous calculez et entraînez simplement un réseau neuronal à deux couches, vous devez charger et calculer autant de méthodes. Vous pouvez voir que ce n'est pas le montant que les humains peuvent faire. Vous constaterez également que vous devez comprendre la structure du programme, y compris les classes et les méthodes.
Jetons maintenant un œil aux parties mises à jour des paramètres de poids et du biais.
nn.ipynb
#Mettre à jour les paramètres de poids et le biais
for key in ('W1', 'b1', 'W2', 'b2'):
network.params[key] -= learning_rate * grad[key] #Le fait est que ce signe est négatif
loss = network.loss(x_batch, t_batch)
train_loss_list.append(loss)
Le but est de ** soustraire la valeur obtenue en multipliant le paramètre de poids et le biais W1, W2, b1 et b2 par le gradient (grad [clé]) et le taux d'apprentissage, respectivement. Lorsque le gradient obtenu par différenciation est une valeur positive, se déplacer dans le sens négatif signifie qu'il est soustrait de la valeur minimale. Et si vous essayez d'inverser ce signe et de le rendre positif?
L'axe horizontal est le nombre de calculs et l'axe vertical est la valeur de la fonction de perte. Vous pouvez voir que la valeur a augmenté immédiatement. Si vous écrivez le signe moins, ce sera comme ça.
Vous pouvez voir que la valeur diminue correctement. Vous pouvez désormais créer un réseau de neurones à deux couches sans utiliser la bibliothèque existante d'apprentissage automatique.
Cette fois, nous avons modélisé le calcul et l'apprentissage du réseau de neurones sans utiliser la bibliothèque d'apprentissage automatique. En apprenant le modèle, j'ai compris que le concept de la fonction de perte et le gradient (= différenciation de la fonction) sont les points. J'avais également besoin de combiner des classes et des modules pour effectuer des calculs, ce qui était une expérience d'apprentissage pour Python lui-même.
Le programme complet est stocké ici. https://github.com/Fumio-eisan/nn2layer_20200321