Fortsetzung von Letztes Mal [Einführung in die Mathematik ab Python](https://www.amazon.co.jp/Python%E3%81%8B%E3% 82% 89% E3% 81% AF% E3% 81% 98% E3% 82% 81% E3% 82% 8B% E6% 95% B0% E5% AD% A6% E5% 85% A5% E9% 96% Serie 80-Amit-Saha / dp / 4873117682). Diesmal
Ist involviert.
In der Erklärung im Buch wird das Ergebnis mit matplotlib aufgezeichnet und als Bild ausgegeben (natürlich Standbild), aber ich wollte sehen, wie der Algorithmus für den Gradientenabstieg mit Animation funktioniert. Also habe ich diesmal versucht, es als GIF-Animation auszugeben. Die Gradientenaufstiegsmethode und die Gradientenabstiegsmethode sind nur im Code enthalten und werden nicht erläutert.
Ermitteln Sie zunächst den Mindestwert der Funktion mithilfe der Gradientenabstiegsmethode. Als nächstes wird die Animation im GIF-Format ausgegeben, um zu visualisieren, wie der Wert mit jedem Schritt abnimmt.
Diesmal
f(x) = 3x^2 + 2x
Finden Sie den Minimalwert der quadratischen Funktion.
gradient_descent.py
from sympy import Derivative, Symbol, sympify, solve
from numpy import arange
import matplotlib.pyplot as plt
import matplotlib.animation as ani
def gradient_descent(x0, f1x, x, epsilon=1e-6, step_size=1e-4):
# f1x =Finden Sie heraus, ob es eine Lösung von 0 hat.
if not solve(f1x):
return
x_old = x0
x_new = x_old - step_size * f1x.subs({x: x_old}).evalf()
X_traversed = []
while abs(x_old - x_new) > epsilon:
X_traversed.append(x_new)
x_old = x_new
x_new = x_old - step_size * f1x.subs({x: x_old}).evalf()
return x_new, X_traversed
def draw_graph(f, x):
X = arange(-1, 1, 0.01)
Y = [f.subs({x: x_val}) for x_val in X]
plt.plot(X, Y)
def draw_frame(i, x, X, Y):
plt.clf()
draw_graph(f, x)
plt.scatter(X[i], Y[i], s=20, alpha=0.8)
if __name__ == '__main__':
x = Symbol('x')
f = 3 * x ** 2 + 2 * x
var0 = 0.75 #Anfangswert der Gradientenabstiegsmethode
d = Derivative(f, x).doit()
# gradient_descent()Gibt den durch die Gradientenabstiegsmethode erhaltenen Mindestwert und den Wert von x bei jedem Schritt zurück.
var_min, X_traversed = gradient_descent(var0, d, x)
print('Gesamtzahl der Schritte: {0}'.format(len(X_traversed)))
print('Mindestwert(Gradientenabstiegsmethode): {0}'.format(var_min))
print('Mindestwert(f1x =Lösung von 0): {0}'.format(float(solve(d)[0])))
X = X_traversed[::100] # (1)
Y = [f.subs({x: x_val}) for x_val in X]
fig = plt.figure(figsize=(6.5, 6.5))
anim = ani.FuncAnimation(fig, draw_frame, fargs=(x, X, Y), frames=len(X)) # (2)
anim.save('gradient_descent.gif', writer='imagemagick', fps=10) # (3)
Gesamtzahl der Schritte: 10792
Mindestwert(Gradientenabstiegsmethode): -0.331667951428822
Mindestwert(f1x =Lösung von 0): -0.3333333333333333
X = X_traversed[::100]
"X_traversed" ist ein Array, das alle Werte von "x" bei jedem Schritt der Methode mit dem steilsten Abstieg enthält.
Die Gesamtzahl der Schritte "len (X_traversed)" beträgt 10.792. Wenn Sie Bilder mit 10 Bildern pro Sekunde oder 10 Bildern pro Sekunde zeichnen, dauert es ungefähr 1.079 Sekunden, um die Animation zu beenden. Um dies auf einige Sekunden Animation zu reduzieren, generieren wir ein neues Array "x", das alle 100 Elemente des resultierenden Arrays "X_traversed" verwendet und zum Erstellen der Animation verwendet.
Diese Methode schließt das am Ende von X_traversed gespeicherte Element aus, dh den Wert von x, der dem Mindestwert entspricht. Ich mache jedoch Kompromisse, weil ich denke, dass es in Ordnung ist, wenn ich die Atmosphäre mit Animation erfassen kann.
Rufen Sie FuncAnimation () matplotlib.animation.Animation auf. api / _as_gen / matplotlib.animation.Animation.html # matplotlib.animation.Animation) Erstellen eines Objekts.
Die Argumente sind wie folgt.
Streit | Erläuterung |
---|---|
fig | Der Ursprung des DiagrammsFigureObjekt. |
draw_frame | Eine Funktion, die für jeden Frame aufgerufen wird. zeichnen_Die Frame-Nummer wird automatisch an das erste Argument des Frames übergeben. |
fargs | draw_Der Wert, der nach dem zweiten Argument von frame übergeben wird. |
frames | Die Anzahl der Frames in der Animation. |
Rufen Sie Animation.save () auf und speichern Sie die Animation tatsächlich.
Durch Angabe von "imagemagick" für das Argument "writer" konnten wir eine GIF-Animation ausgeben. Es wird jedoch davon ausgegangen, dass ImageMagick auf Ihrem Computer installiert ist. Ich verwende macOS, aber ImageMagick war nicht installiert, daher habe ich es mit Homebrew installiert.
$ brew install imagemagick
Es wurden keine weiteren Einstellungen vorgenommen.
** Dieser Typ ... arbeitet! ** ** **
Es macht viel Spaß zu visualisieren, wie der Algorithmus so funktioniert: erröten :: Herzen:
Wenn Sie die stärkeren und stärkeren sehen möchten, empfehle ich den Artikel Erklärung der stochastischen Gradientenabstiegsmethode mit Python. Do: + 1: Es ist aufwärtskompatibel. Ich war auch stark motiviert, eine solche Animation auszugeben. Danke: bete :: funkelt:
Recommended Posts