[PYTHON] Sortie du résultat de la méthode de descente de dégradé sous forme d'animation matplotlib

introduction

Suite de Dernière fois [Introduction aux mathématiques à partir de Python](https://www.amazon.co.jp/Python%E3%81%8B%E3%] 82% 89% E3% 81% FA% E3% 81% 98% E3% 82% 81% E3% 82% 8B% E6% 95% B0% E5% AD% A6% E5% 85% A5% E9% 96% Série 80-Amit-Saha / dp / 4873117682). Cette fois

Est impliqué.

Dans l'explication du livre, le résultat est tracé avec matplotlib et sorti sur une image (image fixe, bien sûr), mais je voulais voir comment l'algorithme de descente de gradient fonctionne avec l'animation. Donc cette fois, j'ai essayé de le sortir en animation gif. La méthode ascendante de gradient et la méthode descendante de gradient sont uniquement incluses dans le code et ne seront pas expliquées.

Choses à faire

Tout d'abord, trouvez la valeur minimale de la fonction à l'aide de la méthode de descente de gradient. Ensuite, sortez l'animation au format gif pour visualiser comment la valeur diminue à chaque étape.

Cette fois

f(x) = 3x^2 + 2x

Trouvez la valeur minimale de la fonction quadratique.

Code source

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 =Découvrez s'il a une solution de 0.
  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  #Valeur initiale de la méthode de descente de gradient

  d = Derivative(f, x).doit()

  # gradient_descent()Renvoie la valeur minimale obtenue par la méthode de descente de gradient et la valeur de x à chaque étape.
  var_min, X_traversed = gradient_descent(var0, d, x)

  print('Nombre total d'étapes: {0}'.format(len(X_traversed)))
  print('valeur minimum(Méthode de descente de gradient): {0}'.format(var_min))
  print('valeur minimum(f1x =Solution de 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)

Sortie standard

Nombre total d'étapes: 10792
valeur minimum(Méthode de descente de gradient): -0.331667951428822
valeur minimum(f1x =Solution de 0): -0.3333333333333333

Commentaire

(1) Réduction du réseau

X = X_traversed[::100]

X_traversed est un tableau qui contient toutes les valeurs de x à chaque étape de la méthode de descente la plus raide.

Le nombre total d'étapes len (X_traversed) est de 10792. Si vous dessinez une image à 10 ips, ou 10 images par seconde, il faudra environ 1 079 secondes pour terminer l'animation. Pour réduire cela à quelques secondes d'animation, nous générons un nouveau tableau x qui prend tous les 100 éléments du tableau résultant X_traversed et l'utilisons pour créer l'animation.

Cette méthode exclut l'élément stocké à la fin de X_traversed, c'est-à-dire la valeur de x correspondant à la valeur minimale. Cependant, je fais des compromis car je pense que ce n'est pas grave si je peux saisir l'atmosphère avec l'animation.

(2) Appel FuncAnimation ()

Appelez FuncAnimation () [matplotlib.animation.Animation](http://matplotlib.org/ api / _as_gen / matplotlib.animation.Animation.html # matplotlib.animation.Animation) Création d'un objet.

Les arguments sont les suivants.

argument La description
fig L'origine du grapheFigureobjet.
draw_frame Une fonction appelée pour chaque image. dessiner_Le numéro de l'image est automatiquement passé au premier argument de l'image.
fargs draw_La valeur passée après le deuxième argument de frame.
frames Le nombre d'images dans l'animation.

(3) Appelez Animation.save ()

Appelez Animation.save () et enregistrez réellement l'animation.

En spécifiant ʻimagemagick pour l'argument writer` ici, nous avons pu produire une animation gif. Cependant, on suppose que ImageMagick est installé sur votre machine. J'utilise macOS, mais je n'ai pas installé ImageMagick, je l'ai donc installé avec Homebrew.

$ brew install imagemagick

Aucun autre réglage n'a été effectué.

animation

gradient_descent.gif

** Ce mec ... fonctionne! ** **

C'est très amusant de visualiser le fonctionnement de l'algorithme comme ceci: blush :: hearts:

référence

Livres

Respect de l'article

Si vous voulez voir les plus forts et les plus forts, je vous recommande l'article Explication de ce qu'est la méthode de descente de gradient stochastique en utilisant Python. Faire: + 1: Il est compatible vers le haut. J'étais aussi fortement motivé pour produire une telle animation. Merci: priez :: scintille:

Autre

Recommended Posts

Sortie du résultat de la méthode de descente de dégradé sous forme d'animation matplotlib
Afficher le résultat de sortie de sklearn.metrics.classification_report sous forme de fichier CSV
Pensez grossièrement à la méthode de descente de gradient
La base de la théorie des graphes avec l'animation matplotlib
Liste des méthodes de descente de gradient (2020)
Un mémorandum sur les avertissements dans les résultats de sortie de pylint
Grattage du résultat de "Schedule-kun"
Changer le style de matplotlib
Filtrer la sortie de tracemalloc
Comment afficher le résultat de sortie de la commande man Linux dans un fichier
Traiter le résultat de% time,% timeit
Algorithme d'apprentissage automatique (méthode de descente de gradient)
Extraire le résultat de la commande TOP avec USER et le sortir au format CSV
Alignez la taille de la barre de couleurs avec matplotlib
Compter / vérifier le nombre d'appels de méthode.
Recherche de points de selle à l'aide de la méthode du gradient
Création d'animation flexible à l'aide de l'animation.FuncAnimation de matplotlib
L'importance de Lint comme le pense Pythonista
Implémentation de SVM par méthode de descente de gradient probabiliste
Le résultat de l'installation de python sur Anaconda