Während ich "Deep Learning von Grund auf neu" lese (geschrieben von Yasuki Saito, veröffentlicht von O'Reilly Japan), werde ich die Websites notieren, auf die ich verwiesen habe. Teil 7 ← → Teil 9
Diese Methode macht die Berechnung des Gradienten jedoch sehr schnell, Ich verstehe die Vorteile der Modularisierung und Implementierung als "Schicht".
Ab P162 wird ein Lernprogramm aufgelistet, das die Fehlerrückvermehrungsmethode verwendet. Um dies auszuführen, sind jedoch auch die Programme mit verschiedenen Definitionen erforderlich, die auf P142 und höher aufgeführt sind.
Nur weil du es erklärst, heißt das nicht, dass du es verstehen kannst.
In einem solchen Fall müssen Sie verschiedene Dinge ausprobieren, weil Sie entweder gedrückt halten können, was Sie verstehen und weitermachen, oder was auch immer der Inhalt des Buches ist.
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,Koordinatenbereich von y
x = np.arange(-10.0, 10.0, 0.1)
y = np.arange(-10.0, 10.0, 0.1)
# x,Gitterdaten von y
X, Y = np.meshgrid(x, y)
#Stellen Sie den Wert der definierten Funktion ein
Z = function_2(X, Y)
#Figur hinzufügen
fig = plt.figure(figsize=(10.0, 8.0))
#Erstellen Sie eine dreidimensionale Achse
ax = fig.add_subplot(111, projection='3d')
#Achsenbeschriftung einstellen
ax.set_title("Abbildung 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)
#Achsenskala einstellen
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])
#Zeichnung
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()
Wenn Sie den plot_wireframe ändern, unterscheidet sich die Zeichnung.
Während ich verschiedene Dinge recherchierte, fand ich so etwas. Sie können das gezeichnete Diagramm drehen und aus verschiedenen Richtungen anzeigen.
import numpy as np
import matplotlib
#Es scheint, dass das Backend von matplotlib festgelegt ist, aber ich weiß nicht, was es bedeutet.
#Nach dem Hinzufügen dieser Linie wird das Diagramm jedoch in einem separaten Fenster geöffnet.
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()
Die Farbe des Diagramms scheint durch den Parameter cmap angegeben zu werden. 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()
Kontur (Position auf der x-Achse, Position auf der y-Achse, Höhe auf Koordinaten, Ebenen = [Höhe für Plotlinie angeben]) Da die Wertinkremente der Arrays x und y auf 0,1 eingestellt sind, sind die Linien glatt, die Anzeige dauert jedoch einige Zeit. Wenn Sie dies auf 1.0 setzen, wird es sofort angezeigt, aber die Linien sind ungleichmäßig. Geben Sie für h die Höhe an, in der Sie eine Linie zeichnen möchten. Im Beispiel wird eine Linie nacheinander von 0 bis 100 gezeichnet.
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 #Stellen Sie den Wert wieder her
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()
Ich habe gerade function_2 in gradient_2d.py im Ordner ch04 geändert. Köcher (Position auf der x-Achse, Position auf der y-Achse, Neigung in der x-Achse, Neigung in der y-Achse)
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 #Stellen Sie den Wert wieder her
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()
Wenn im Fall von SGD der Lernkoeffizient lr nicht richtig eingestellt ist, ist er nicht wie im Beispiel im Zickzack. Wenn es 1.0 ist, ist es Zickzack, aber es konvergiert nicht gegen 0. Wenn es 0,7 oder weniger ist, konvergiert es gegen 0, bevor der Zickzack wahrnehmbar wird. 0,9 ist der am besten geeignete Graph.
Wenn Sie im Moment des Impulses nicht den Wert des Moments sowie den Lernkoeffizienten lr anpassen, entspricht dies nicht dem Beispiel im Buch.
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 #Stellen Sie den Wert wieder her
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()
In der Definition von gradient_descent x_history.append( x.copy() ) Es ist geworden. Dies bedeutet "Erstellen Sie ein Duplikat des gleichen Inhalts wie x und fügen Sie es zu x_history hinzu". x_history.append( x ) Geschrieben bedeutet "den Speicherort, auf den der Name x verweist, zu x_history hinzufügen", und wenn der Inhalt von x neu geschrieben wird, wird auch der Inhalt von x_history neu geschrieben. Das gleiche passiert mit der Zuordnung a = x. Dies scheint "etwas" im Python-Array zu sein und wird an verschiedenen Stellen erklärt.
Es scheint, dass es in der Definition von numerischer_gradient eine Funktion namens np.nditer (x, flags = ['multi_index'], op_flags = ['readwrite']) gibt, die dann zur Steuerung der Schleife verwendet wird. Wenn Sie es nicht wissen, drucken Sie den Inhalt der Schleife aus und überprüfen Sie ihn.
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
Das war's. Ändern Sie nun die Eingabe ein wenig
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
Selbst wenn sich die Anzahl der Elemente und Dimensionen von x ändern, kann es verarbeitet werden, ohne den Code des Programms zu ändern.
Dies ist das Ende von Kapitel 6, Abschnitt 1. Ich habe nur mit dem Zeichnen von Grafiken gespielt, aber ich habe etwas über Arrays und Python-Grammatik gelernt. Ich konnte verstehen, in welchen Variablen die Gradienten aggregiert wurden und wie sie in der Grafik gezeichnet wurden.
Eine sehr Zusammenfassung von matplotlib Python 3: So schreiben Sie ein 3D-Diagramm mplot3d tutorial matplotlib color example code matplotlib axes.plot
Recommended Posts