[PYTHON] Mémo d'auto-apprentissage "Deep Learning from scratch" (partie 8) J'ai dessiné le graphique du chapitre 6 avec matplotlib

En lisant "Deep Learning from scratch" (écrit par Yasuki Saito, publié par O'Reilly Japan), je noterai les sites auxquels j'ai fait référence. Partie 7 ← → Partie 9

Même si vous lisez le chapitre 5 Méthode de propagation inversée des erreurs, honnêtement, il semble que vous ne comprenez pas

Cependant, cette méthode rend le calcul du gradient très rapide, Je comprends les avantages de la modularisation et de la mise en œuvre en tant que «couche».

A partir de P162, un programme d'apprentissage utilisant la méthode de propagation de retour d'erreur est répertorié, mais pour l'exécuter, les programmes avec diverses définitions listées sur P142 et les versions ultérieures sont également nécessaires.

Dans le chapitre 6, que faites-vous de cela sur le chemin de ce point? Il m'a expliqué ce que je pensais ...

Ce n'est pas parce que vous expliquez que vous pouvez le comprendre.

Dans un tel cas, vous devez essayer diverses choses car vous pouvez soit maintenir ce que vous comprenez et avancer, soit quel que soit le contenu du livre.

Pour le moment, j'ai dessiné un schéma de P169.

6-1.jpg

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np

def function_2(x, y):
    return x**2/20 + y**2

# x,Plage de coordonnées de y
x = np.arange(-10.0, 10.0, 0.1)
y = np.arange(-10.0, 10.0, 0.1)
# x,Données de grille de y
X, Y = np.meshgrid(x, y)
#Définir la valeur de la fonction définie
Z = function_2(X, Y)

#Ajouter une figure
fig = plt.figure(figsize=(10.0, 8.0))
#Créer un axe tridimensionnel
ax = fig.add_subplot(111, projection='3d')
#Définir l'étiquette de l'axe
ax.set_title("Graphique 6-1 f(x,y)=x**2/20+y**2", size = 14)
ax.set_xlabel("x", size = 14)
ax.set_ylabel("y", size = 14)
ax.set_zlabel("f(x, y)", size = 14)
#Définir l'échelle de l'axe
ax.set_xticks([-10.0, -5.0, 0.0, 5.0, 10.0])
ax.set_yticks([-10.0, -5.0, 0.0, 5.0, 10.0])
ax.set_zticks([0.0, 20.0, 40.0, 60.0, 80.0, 100.0])
#dessin
ax.plot_wireframe(X, Y, Z)
#ax.plot_surface(X, Y, Z, rstride=1, cstride=1)
#ax.contour3D(X,Y,Z)
#ax.contourf3D(X,Y,Z)
#ax.scatter3D(np.ravel(X),np.ravel(Y),np.ravel(Z))
plt.show()

Si vous modifiez le plot_wireframe, le dessin sera différent.

En recherchant diverses choses, j'ai trouvé quelque chose comme ça. Vous pouvez faire pivoter le graphique dessiné et le voir dans différentes directions.

import numpy as np
import matplotlib
#Il semble que le backend de matplotlib soit défini, mais je ne sais pas ce que cela signifie.
#Cependant, après avoir ajouté cette ligne, le graphique s'ouvrira dans une fenêtre séparée.
matplotlib.use('TkAgg')

#for plotting
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

def function_2(x, y):
    return x**2/20 + y**2

x = np.arange(-10.0, 10.0, 0.1)
y = np.arange(-10.0, 10.0, 0.1)

X, Y = np.meshgrid(x, y)
Z = function_2(X, Y)

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
surf = ax.plot_surface(X, Y, Z, cmap='bwr', linewidth=0)
fig.colorbar(surf)
ax.set_title("Surface Plot")
fig.show()

6-2.jpg

La couleur du graphique semble être spécifiée par le paramètre cmap. matplotlib color example code

La ligne de contour ressemble à ceci

6-3.jpg

import matplotlib.pyplot as plt
import numpy as np

def function_2(x, y):
    return x**2/20 + y**2

x = np.arange(-10.0, 10.0, 0.1)
y = np.arange(-10.0, 10.0, 0.1)
h = np.arange(0., 100.0, 1.0)
X, Y = np.meshgrid(x, y)
Z = function_2(X, Y)

plt.figure()
plt.contour(X, Y, Z, levels=h)
plt.xlim([-10, 10])
plt.ylim([-10, 10])
plt.show()

contour (position sur l'axe x, position sur l'axe y, hauteur sur les coordonnées, niveaux = [spécifier la hauteur pour tracer la ligne]) Étant donné que les incréments de valeur des tableaux x et y sont définis sur 0,1, les lignes sont lisses, mais leur affichage prend du temps. Si vous définissez ceci sur 1.0, il sera affiché immédiatement, mais les lignes sont inégales. Pour h, spécifiez la hauteur à laquelle vous souhaitez tracer une ligne. Dans l'exemple, une ligne est dessinée une à une de 0 à 100.

Diagramme vectoriel dégradé

6-4.jpg

import matplotlib.pyplot as plt
import numpy as np

def _numerical_gradient_no_batch(f, x):
    h = 1e-4  # 0.0001
    grad = np.zeros_like(x)
    
    for idx in range(x.size):
        tmp_val = x[idx]
        x[idx] = float(tmp_val) + h
        fxh1 = f(x)  # f(x+h)
        
        x[idx] = tmp_val - h 
        fxh2 = f(x)  # f(x-h)
        grad[idx] = (fxh1 - fxh2) / (2*h)
        
        x[idx] = tmp_val  #Restaurer la valeur
    return grad

def numerical_gradient(f, X):
    if X.ndim == 1:
        return _numerical_gradient_no_batch(f, X)
    else:
        grad = np.zeros_like(X)
        for idx, x in enumerate(X):
            grad[idx] = _numerical_gradient_no_batch(f, x)
        return grad

def function_2(x):
    return (x[0]**2/20+x[1]**2)

x = np.arange(-10.0, 10.0, 1.)
y = np.arange(-10.0, 10.0, 1.)
h = np.arange(0., 100.0, 10.0)
X, Y = np.meshgrid(x, y)

X = X.flatten()
Y = Y.flatten()
grad = numerical_gradient(function_2, np.array([X, Y]).T).T
    
plt.figure()
plt.quiver(X, Y, -grad[0], -grad[1],  angles="xy",color="#666666")
plt.xlim([-10, 10])
plt.ylim([-5, 5])
plt.xlabel('x')
plt.ylabel('y')
plt.grid()
plt.draw()
plt.show()

Je viens de changer function_2 dans gradient_2d.py dans le dossier ch04. carquois (position sur l'axe des x, position sur l'axe des y, pente sur l'axe des x, pente sur l'axe des y)

Schéma du chemin de mise à jour de l'optimisation

6-5.jpg

import matplotlib.pyplot as plt
import numpy as np

def numerical_gradient(f, x):
    h = 1e-4 # 0.0001
    grad = np.zeros_like(x)
    
    it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
    while not it.finished:
        idx = it.multi_index
        tmp_val = x[idx]
        x[idx] = tmp_val + h
        fxh1 = f(x) # f(x+h)
        
        x[idx] = tmp_val - h 
        fxh2 = f(x) # f(x-h)
        grad[idx] = (fxh1 - fxh2) / (2*h)
        
        x[idx] = tmp_val #Restaurer la valeur
        it.iternext()   
        
    return grad

def  adagrad(x, lr, grad, v, moment):
    v += grad * grad
    x -= lr * grad / (np.sqrt(v) + 1e-7)
    return x, v

def  momentum(x, lr, grad, v, moment):
    v = moment*v - lr*grad
    x += v
    return x, v

def sgd(x, lr, grad, v = None, moment = None):
    x -= lr * grad
    return x, v

def gradient_descent(opt, f, init_x, lr=0.01, step_num=100, moment=0.9):
    x = init_x
    x_history = []
    v = 0
    for i in range(step_num):
        x_history.append( x.copy() )
        grad = numerical_gradient(f, x)
        x, v = opt(x, lr, grad, v, moment)
    return np.array(x_history)

def function_1(x, y):
    return x**2/20 + y**2

def function_2(x):
    return (x[0]**2/20+x[1]**2)

x = np.arange(-10.0, 10.0, 0.1)
y = np.arange(-10.0, 10.0, 0.1)
h = np.arange(0., 10.0, 1.0)
X, Y = np.meshgrid(x, y)
Z = function_1(X, Y)

plt.figure()
plt.contour(X, Y, Z, levels=h)

init_x = np.array([-7.0, 2.0])
x_history = gradient_descent(sgd, function_2, init_x, lr=0.9, step_num=100)
#x_history = gradient_descent(momentum, function_2, init_x, lr=0.2, step_num=20, moment=0.9)
#x_history = gradient_descent(adagrad, function_2, init_x, lr=0.9, step_num=100)

plt.plot(x_history[:,0], x_history[:,1],'-ro')
plt.xlim([-10, 10])
plt.ylim([-10, 10])
plt.xlabel('x')
plt.ylabel('y')
plt.grid()
plt.show()

Dans le cas de SGD, si le coefficient d'apprentissage lr n'est pas réglé correctement, il ne sera pas en zigzag comme dans l'exemple. Si c'est 1.0, ce sera en zigzag, mais il ne convergera pas vers 0. S'il est inférieur ou égal à 0,7, il convergera vers 0 avant que le zigzag ne devienne perceptible. 0.9 est le graphique le plus approprié.

Dans le cas de l'élan, si vous n'ajustez pas la valeur du moment ainsi que le coefficient d'apprentissage lr, ce ne sera pas comme l'exemple du livre.

Schéma du chemin de mise à jour d'optimisation 3D

w6-9.jpg

import numpy as np
import matplotlib
matplotlib.use('TkAgg')

def numerical_gradient(f, x):
    h = 1e-4 # 0.0001
    grad = np.zeros_like(x)

    it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
    while not it.finished:
        idx = it.multi_index
        tmp_val = x[idx]
        x[idx] = tmp_val + h
        fxh1 = f(x) # f(x+h)

        x[idx] = tmp_val - h 
        fxh2 = f(x) # f(x-h)
        grad[idx] = (fxh1 - fxh2) / (2*h)

        x[idx] = tmp_val #Restaurer la valeur
        it.iternext()   

    return grad

def  adagrad(x, lr, grad, v, moment):
    v += grad * grad
    x -= lr * grad / (np.sqrt(v) + 1e-7)
    return x, v

def  momentum(x, lr, grad, v, moment):
    v = moment*v - lr*grad
    x += v
    return x, v

def sgd(x, lr, grad, v = None, moment = None):
    x -= lr * grad
    return x, v

def gradient_descent(opt, f, init_x, lr=0.01, step_num=100, moment=0.9):
    x = init_x
    x_history = []
    v = 0
    for i in range(step_num):
        w = x.tolist()
        z = f(x)
        w.append(z)
        x_history.append( w )
        grad = numerical_gradient(f, x)
        x, v = opt(x, lr, grad, v, moment)
    return np.array(x_history)

def function_1(x, y):
    return x**2/20 + y**2

def function_2(x):
    return (x[0]**2/20+x[1]**2)


#for plotting
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

x = np.arange(-8.0, 8.0, .1)
y = np.arange(-4.0, 4.0, .1)

X, Y = np.meshgrid(x, y)
Z = function_1(X, Y)

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
surf = ax.plot_surface(X, Y, Z, cmap='bwr', linewidth=0)

init_x = np.array([-7.0, 2.0])
x_history = gradient_descent(sgd, function_2, init_x, lr=0.9, step_num=100)
#x_history = gradient_descent(momentum, function_2, init_x, lr=0.2, step_num=20, moment=0.9)
#x_history = gradient_descent(adagrad, function_2, init_x, lr=0.9, step_num=100)
ax.plot(x_history[:,0], x_history[:,1], x_history[:,2],'-ro')

fig.colorbar(surf)
ax.set_title("Surface Plot")
fig.show()

Il y a une copie de tableau

Dans la définition de gradient_descent x_history.append( x.copy() ) Il est devenu. Cela signifie "faire une copie du même contenu que x et l'ajouter à x_history". x_history.append( x ) Écrit signifie "ajouter l'emplacement mémoire référencé par le nom x à x_history", et lorsque le contenu de x est réécrit, le contenu de x_history est également réécrit. La même chose se produit avec l'affectation a = x. Cela semble être "quelque chose" dans le tableau python et est expliqué à divers endroits.

nditer itérateur?

Il semble qu'il existe une fonction appelée np.nditer (x, flags = ['multi_index'], op_flags = ['readwrite']) dans la définition de numerical_gradient, puis elle est utilisée pour contrôler la boucle. Si vous ne savez pas, imprimez le contenu de la boucle et vérifiez-la.

x = np.array([[-7.0, 2.0],[-6., 1.],[-5., 0.]])
it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
while not it.finished:
    idx = it.multi_index
    print("x[" + str(idx) + "] : " + str(x[idx]))
    it.iternext()  

x[(0, 0)] : -7.0 x[(0, 1)] : 2.0 x[(1, 0)] : -6.0 x[(1, 1)] : 1.0 x[(2, 0)] : -5.0 x[(2, 1)] : 0.0

Je vois. Maintenant, changez un peu l'entrée

x = np.array([[-7.0, 2.0,-6.],[1., -5., 0.]])
it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
while not it.finished:
    idx = it.multi_index
    print("x[" + str(idx) + "] : " + str(x[idx]))
    it.iternext()   

x[(0, 0)] : -7.0 x[(0, 1)] : 2.0 x[(0, 2)] : -6.0 x[(1, 0)] : 1.0 x[(1, 1)] : -5.0 x[(1, 2)] : 0.0

Même si le nombre d'éléments et les dimensions de x changent, il peut être traité sans changer le code du programme.

Ceci est la fin du chapitre 6, section 1. Je jouais juste avec le dessin de graphes, mais j'ai appris les tableaux et la grammaire python. J'ai pu comprendre le contenu de quelles variables les gradients ont été agrégés et comment ils ont été dessinés sur le graphique.

Site référencé

Un très résumé de matplotlib Python 3: Comment écrire un graphique 3D mplot3d tutorial matplotlib color example code matplotlib axes.plot

Partie 7 ← → Partie 9

Glossaire illisible

Recommended Posts

Mémo d'auto-apprentissage "Deep Learning from scratch" (partie 8) J'ai dessiné le graphique du chapitre 6 avec matplotlib
Mémo d'auto-apprentissage "Deep Learning from scratch" (partie 12) Deep learning
"Deep Learning from scratch" Mémo d'auto-apprentissage (n ° 14) Exécutez le programme du chapitre 4 sur Google Colaboratory
"Deep Learning from scratch" Mémo d'auto-apprentissage (n ° 16) J'ai essayé de créer SimpleConvNet avec Keras
"Deep Learning from scratch" Mémo d'auto-apprentissage (n ° 17) J'ai essayé de créer DeepConvNet avec Keras
[Mémo d'apprentissage] Le Deep Learning fait de zéro [Chapitre 7]
Deep learning / Deep learning made from scratch Chapitre 6 Mémo
[Mémo d'apprentissage] Deep Learning fait de zéro [Chapitre 5]
[Mémo d'apprentissage] Le Deep Learning fait de zéro [Chapitre 6]
Deep learning / Deep learning made from scratch Chapitre 7 Mémo
[Mémo d'apprentissage] Deep Learning fait de zéro [~ Chapitre 4]
Mémo d'auto-apprentissage "Deep Learning from scratch" (glossaire illisible)
Mémo d'auto-apprentissage «Deep Learning from scratch» (10) Classe MultiLayerNet
Mémo d'auto-apprentissage «Deep Learning from scratch» (n ° 11) CNN
[Deep Learning from scratch] J'ai implémenté la couche Affine
Deep Learning from scratch La théorie et la mise en œuvre de l'apprentissage profond appris avec Python Chapitre 3
Un amateur a trébuché dans le Deep Learning à partir de zéro Note: Chapitre 1
Un amateur a trébuché dans le Deep Learning à partir de zéro Note: Chapitre 7
Un amateur a trébuché dans le Deep Learning à partir de zéro Note: Chapitre 5
Mémo d'auto-apprentissage «Deep Learning from scratch» (n ° 18) One! Miaou! Grad-CAM!
Un amateur a trébuché dans le Deep Learning à partir de zéro.
Un amateur a trébuché dans le Deep Learning à partir de zéro Note: Chapitre 2
J'ai essayé d'implémenter Perceptron Part 1 [Deep Learning from scratch]
Mémo d'auto-apprentissage "Deep Learning from scratch" (n ° 15) Tutoriel pour débutants TensorFlow
Deep learning / Deep learning from scratch 2 Chapitre 4 Mémo
Deep learning / Deep learning made from scratch Chapitre 3 Mémo
Deep Learning / Deep Learning à partir de Zero 2 Chapitre 5 Mémo
Deep Learning / Deep Learning à partir de Zero 2 Chapitre 7 Mémo
Deep Learning / Deep Learning à partir de Zero 2 Chapitre 8 Mémo
Deep learning / Deep learning made from scratch Chapitre 5 Mémo
Deep learning / Deep learning made from scratch Chapitre 4 Mémo
Deep learning / Deep learning from scratch 2 Chapitre 3 Mémo
Deep Learning / Deep Learning à partir de Zero 2 Chapitre 6 Mémo
Un mémo lors de l'exécution de l'exemple de code de Deep Learning créé à partir de zéro avec Google Colaboratory
Mémo d'auto-apprentissage "Deep Learning from scratch" (n ° 13) Essayez d'utiliser Google Colaboratory
Mémo d'auto-apprentissage «Deep Learning from scratch» (n ° 10-2) Valeur initiale du poids
"Deep Learning from scratch" avec Haskell (inachevé)
Deep Learning from scratch ① Chapitre 6 "Techniques liées à l'apprentissage"
[Mémo d'apprentissage] Apprentissage profond à partir de zéro ~ Mise en œuvre de l'abandon ~
J'ai eu la date du riz du pub de Kagawa et j'ai dessiné un graphique
Préparez l'environnement pour le livre O'Reilly "Deep Learning from scratch" avec apt-get (Debian 8)
[Python] [Traitement du langage naturel] J'ai essayé le Deep Learning ❷ fait de toutes pièces en japonais ①
Version Lua Deep Learning from scratch Part 5.5 [Rendre les fichiers pkl disponibles dans Lua Torch]
Apprentissage profond à partir de zéro
Apprendre en profondeur à partir des bases mathématiques Partie 2 (pendant la fréquentation)
[Deep Learning from scratch] J'ai essayé d'expliquer le décrochage
Python vs Ruby "Deep Learning from scratch" Chapitre 3 Graphique de la fonction step, fonction sigmoid, fonction ReLU
Python vs Ruby "Deep Learning from scratch" Chapitre 1 Graphique de la fonction sin et de la fonction cos
[Partie 4] Utilisez le Deep Learning pour prévoir la météo à partir d'images météorologiques
Apprentissage profond à partir de zéro 1 à 3 chapitres
[Partie 1] Utilisez le Deep Learning pour prévoir la météo à partir d'images météorologiques
[Partie 3] Utilisez le Deep Learning pour prévoir la météo à partir d'images météorologiques
Un amateur a trébuché dans le Deep Learning ❷ fait à partir de zéro Note: Chapitre 5
Chapitre 3 Réseau de neurones Ne découpez que les bons points de Deeplearning à partir de zéro
Un amateur a trébuché dans le Deep Learning ❷ fait à partir de zéro Note: Chapitre 2
Créez un environnement pour "Deep Learning from scratch" avec Docker
[Partie 2] Utilisez le Deep Learning pour prévoir la météo à partir d'images météorologiques
Un amateur a trébuché dans le Deep Learning ❷ fait à partir de zéro Note: Chapitre 4