[PYTHON] Geben Sie das Ergebnis der Gradientenabstiegsmethode als Matplotlib-Animation aus

Einführung

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.

Dinge die zu tun sind

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.

Quellcode

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)

Standardausgabe

Gesamtzahl der Schritte: 10792
Mindestwert(Gradientenabstiegsmethode): -0.331667951428822
Mindestwert(f1x =Lösung von 0): -0.3333333333333333

Kommentar

(1) Reduzierung des Arrays

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.

(2) Rufen Sie FuncAnimation () auf

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.

(3) Rufen Sie Animation.save () auf

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.

Animation

gradient_descent.gif

** Dieser Typ ... arbeitet! ** ** **

Es macht viel Spaß zu visualisieren, wie der Algorithmus so funktioniert: erröten :: Herzen:

Referenz

Bücher

Artikel respektieren

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:

Andere

Recommended Posts

Geben Sie das Ergebnis der Gradientenabstiegsmethode als Matplotlib-Animation aus
Geben Sie das Ausgabeergebnis von sklearn.metrics.classification_report als CSV-Datei aus
Denken Sie grob über die Gradientenabstiegsmethode nach
Die Basis der Graphentheorie mit Matplotlib-Animation
Liste der Gradientenabstiegsmethoden (2020)
Ein Memorandum über Warnungen in Pylint-Ausgabeergebnissen
Scraping das Ergebnis von "Schedule-Kun"
Ändern Sie den Stil von matplotlib
Filtern Sie die Ausgabe von tracemalloc
So geben Sie das Ausgabeergebnis des Linux-Befehls man in eine Datei aus
Verarbeiten Sie das Ergebnis von% time,% timeit
Algorithmus für maschinelles Lernen (Gradientenabstiegsmethode)
Extrahieren Sie das Ergebnis des TOP-Befehls mit USER und geben Sie es als CSV aus
Richten Sie die Größe der Farbleiste an der Matplotlib aus
Zählen / überprüfen Sie die Anzahl der Methodenaufrufe.
Sattelpunktsuche mit der Gradientenmethode
Flexible Animationserstellung mit Animation.FuncAnimation von matplotlib
Die Bedeutung von Lint, wie Pythonista denkt
Implementierung von SVM durch probabilistische Gradientenabstiegsmethode
Das Ergebnis der Installation von Python auf Anaconda