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
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.
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.
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()
La couleur du graphique semble être spécifiée par le paramètre cmap. matplotlib color example code
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.
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)
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.
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()
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.
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.
Un très résumé de matplotlib Python 3: Comment écrire un graphique 3D mplot3d tutorial matplotlib color example code matplotlib axes.plot