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.
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.
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)
Nombre total d'étapes: 10792
valeur minimum(Méthode de descente de gradient): -0.331667951428822
valeur minimum(f1x =Solution de 0): -0.3333333333333333
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.
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. |
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é.
** Ce mec ... fonctionne! ** **
C'est très amusant de visualiser le fonctionnement de l'algorithme comme ceci: blush :: hearts:
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:
Recommended Posts