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.
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.
L'apprentissage dans un modèle consiste à rapprocher la valeur prédite de la bonne réponse ou à augmenter le taux de réponse correct. Prenons l'exemple de la reconnaissance d'image. MNIST, un système de reconnaissance des nombres bien connu, distingue les nombres manuscrits.
Sur cette image, n'importe quel humain peut voir 5 (le cerveau apprend et reconnaît). Ensuite, réfléchissons à ce qui est nécessaire pour créer un algorithme permettant à un ordinateur de reconnaître cela 5. Afin de reconnaître 5 à partir de "l'image" de 5, il est nécessaire de trouver une "quantité de caractéristiques" qui peut être identifiée comme 5 à partir de l'image. La quantité de fonctionnalités est écrite en anglais sous le nom de sélection de fonctionnalités. Traduit littéralement, cela signifie «choisir une caractéristique». Si vous le remplacez par l'image de 5, il aura des fonctionnalités telles que «première barre horizontale», «ligne verticale» et «arc à environ 270 degrés avec la gauche ouverte». Le flux d'extraction de ces quantités de caractéristiques et d'apprentissage des caractéristiques extraites est l'algorithme qui fait reconnaître 5 par l'ordinateur. La fonction de recherche (= extraction) d'entités est appelée un convertisseur. Ces convertisseurs bien connus comprennent SIFT, SURF et HOG. Pour plus d'informations, veuillez visiter l'URL ci-dessous. Cette URL est le matériel de 2011 et semble être une technologie développée depuis les années 2000.
https://www.slideshare.net/lawmn/siftsurf
Ensuite, la quantité de caractéristiques peut être utilisée pour convertir les données d'image en un vecteur, et le vecteur peut être entraîné par une fonction appelée discriminateur utilisée dans l'apprentissage automatique. Les discriminateurs bien connus incluent la machine à vecteurs de support (SVM) et la méthode de proximité K (KNN).
Ici, il est nécessaire de juger et de sélectionner le convertisseur de manière appropriée par "personnes" en fonction des caractéristiques. D'autre part, la gamme couverte par le réseau de neurones comprend également ce convertisseur. En d'autres termes, le convertisseur lui-même qui recherche des fonctionnalités est également un algorithme qui peut être entraîné.
Le concept est illustré ci-dessus. En augmentant la zone que l'ordinateur juge, le réseau neuronal interprète les données données telles qu'elles sont et tente de trouver le modèle du problème. On peut comprendre qu'il s'agit d'un algorithme avec un plus grand sens de l'intelligence artificielle.
Ensuite, je résumerai l'idée de distinguer les données concrètement prédites et les données correctes. Nous introduisons une fonction appelée fonction de perte pour indiquer si elle est proche de la bonne réponse.
La fonction de perte la plus connue est l'erreur quadratique moyenne. Il est exprimé par la formule ci-dessous.
yk indique la sortie du réseau neuronal, tk indique les données de l'enseignant (données de réponse correctes) et k indique le nombre de dimensions (nombre) des données. À partir de la formule, nous pouvons voir que plus les réponses sont correctes, plus cette valeur est petite. J'aimerais l'écrire facilement dans un programme.
nn.ipynb
import numpy as np
def mean_squared_error(y,t):
return 0.5*np.sum((y-t)**2)
t = [0,0,1,0,0,0,0,0,0,0]
y = [0.1,0.1,0.6,0.1,0.1,0,0,0,0,0]
y1 = [0.1,0.1,0.1,0.1,0.6,0,0,0,0,0]
print(mean_squared_error(np.array(y),np.array(t)))
print(mean_squared_error(np.array(y1),np.array(t)))
0.10000000000000003
0.6000000000000001
Les éléments de ce tableau correspondent aux nombres "0", "1" et "2" dans l'ordre à partir du premier index. Où y est la sortie du réseau neuronal. La valeur convertie par la fonction softmax représente la probabilité. On dit que la probabilité de déterminer qu'il s'agit du nombre 2 est de 0,6. De plus, t sont les données des enseignants. En d'autres termes, la bonne réponse est le chiffre 2. Lorsque la somme des carrés des erreurs a été calculée pour chacun des y et y1, y était plus proche. On peut voir que la valeur fournie par y peut exprimer correctement que l'élément avec le nombre 2 a la probabilité la plus élevée.
Une autre fonction d'erreur est l'erreur d'entropie croisée.
log est basé sur la logarithmique naturelle. Puisque tk est l'étiquette de réponse correcte, 1 n'est émis que lorsque la réponse est correcte. Par conséquent, cette fonction est calculée pour produire le logarithme naturel correspondant à l'étiquette de réponse correcte de 1. Voici le résultat de la mise en œuvre réelle.
nn.ipynb
def cross_entropy_error(y,t):
delta = 1e-7
return -np.sum(t*np.log(y+delta))
print(cross_entropy_error(np.array(y),np.array(t)))
print(cross_entropy_error(np.array(y1),np.array(t)))
0.510825457099338
2.302584092994546
Ici, une valeur minute (0,0000001) est ajoutée dans le calcul dans le journal. Ceci est ajouté pour éviter que le calcul ne reste bloqué car il diverge à moins l'infini lorsqu'il devient log (0). En regardant le résultat, si la sortie y de l'étiquette correcte est petite, elle sera de 2,3, mais si la sortie y est élevée, elle sera de 0,5.
La fonction de perte peut être transformée en un modèle avec une précision de prédiction élevée en minimisant la valeur obtenue. Par conséquent, il est nécessaire de trouver un paramètre qui réduit la fonction de perte. À ce stade, le paramètre est mis à jour en utilisant la valeur différenciée de ce paramètre comme indice. La différenciation permet de connaître le gradient de la fonction. Les contenus de base de la différenciation sont omis ici.
Si la valeur de ce gradient est positive, déplacez le paramètre (a sur la figure) dans le sens négatif pour approcher la valeur minimale. Au contraire, si la valeur du gradient est négative, vous pouvez imaginer déplacer le paramètre dans le sens positif pour approcher la valeur minimale.
Maintenant, je voudrais réfléchir à la différenciation des fonctions. Il existe deux approches pour différencier une fonction: (1) la résolution analytique et (2) la résolution discrète (en prenant la différence). Si vous déplacez votre main et le faites par un humain, vous le faites en (1), mais en le résolvant par programme, (2) est pratique. Cette fois, nous mettrons en œuvre le concept de différence centrale illustré dans la figure ci-dessous.
Cette fois, je voudrais trouver la valeur discrètement différenciée de cette fonction.
nn.ipynb
import numpy as np
import matplotlib.pyplot as plt
def numerical_diff(f,x):
h =1e-4 #0.0001
return (f(x+h)-f(x-h))/(2*h)
def function_1(x):
return 0.01*x**2 + 0.1*x
numerical_diff(function_1,5)
0.1999999999990898
La courbe attachée est la fonction d'origine et la ligne droite est le gradient à x = 5.
Ensuite, envisagez d'effectuer une différenciation partielle de la fonction à deux variables illustrée ci-dessous.
Si vous dessinez la fonction d'origine, ce sera un graphique en trois dimensions comme indiqué ci-dessous.
nn.ipynb
def function_2(x):
return x[0]**2 + x[1]**2
La différenciation partielle fait référence à la détermination de la variable à différencier et au traitement d'autres valeurs numériques comme des constantes pour effectuer la différenciation. Différenciez partiellement x0 et trouvez la valeur lorsque x0 = 3, x1 = 4.
nn.ipynb
def function_tmp1(x0):
return x0*x0 +4.0**2.0
numerical_diff(function_tmp1,3.0)
6.00000000000378
Nous la définissons comme une fonction avec une seule variable et différencions cette fonction. Cependant, dans ce cas, il est nécessaire d'effectuer un traitement tel que l'affectation de valeurs autres que les valeurs utilisées comme variables une par une. Considérez que vous voulez différencier x0 et x1 ensemble. Cela peut être mis en œuvre comme suit:
nn.ipynb
def numerical_gradient(f,x):
h =1e-4
grad = np.zeros_like(x)
for idx in range(x.size):
tmp_val =x[idx]
x[idx] =tmp_val + h
fxh1 = f(x)
x[idx] = tmp_val -h
fxh2 = f(x)
grad[idx] = (fxh1-fxh2)/(2*h)
x[idx] = tmp_val
return grad
numerical_gradient(function_2,np.array([3.0,4.0]))
array([6., 8.])
J'ai expliqué plus tôt que cette valeur différenciée indique le gradient de la fonction d'origine. En outre, envisagez de tracer cette valeur différenciée sous forme de vecteur. Pour plus de commodité, il est illustré ci-dessous avec un signe moins.
Vous pouvez voir que la flèche pointe vers (x0, x1) = (0,0). Cela conduit à améliorer la précision du modèle en trouvant la valeur minimale dans la discussion de la fonction de perte. ** Il s'avère que cette opération différentielle permet de trouver la valeur minimale de la fonction de perte, conduisant à l'optimisation du modèle! ** **
Cette fois, j'ai avancé au point de comprendre que cette opération différentielle conduit à une amélioration de la précision du modèle. En regardant le contenu de l'apprentissage, qui est le cœur du réseau neuronal, j'ai approfondi ma compréhension. Dans la seconde moitié de l'article, j'aimerais bien comprendre l'apprentissage en procédant réellement à l'implémentation sur le réseau neuronal.
La seconde moitié est là. https://qiita.com/Fumio-eisan/items/7507d8687ca651ab301d