In [34]:
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np
import numpy.linalg
In [35]:
def f(x):
return x**4 - 11 * x**3 + 41 * x**2 -61 * x + 30
x = np.linspace(0, 6, 1000)
y = f(x)
In [36]:
plt.grid()
plt.plot(x, y)
Out[36]:
[<matplotlib.lines.Line2D at 0xffff44fd1650>]
Descente de gradient¶
In [37]:
def df(x):
return 4 * x**3 - 33 * x**2 + 82 * x - 61
dy = df(x)
In [38]:
def tangente(x0):
x = np.linspace(x0 - .2, x0 + .2, 100)
y = df(x0) * (x - x0) + f(x0)
return x, y
In [39]:
x0 = 5.8
xt, yt = tangente(x0)
plt.grid()
plt.plot(x, y)
plt.plot(xt, yt)
plt.scatter(x0, f(x0), c='red')
Out[39]:
<matplotlib.collections.PathCollection at 0xffff4568f1d0>
In [40]:
df(x0)
Out[40]:
84.92799999999983
In [41]:
x0 = 5.8
xt0, yt0 = tangente(x0)
x1 = x0 - df(x0)
xt1, yt1 = tangente(x1)
plt.grid()
plt.plot(x, y)
plt.plot(xt0, yt0)
plt.plot(xt1, yt1)
plt.scatter(x0, f(x0), c='red')
plt.scatter(x1, f(x1), c='red')
Out[41]:
<matplotlib.collections.PathCollection at 0xffff44d3f810>
In [42]:
eta = .001
x0 = 5.8
xt0, yt0 = tangente(x0)
x1 = x0 - eta * df(x0)
xt1, yt1 = tangente(x1)
plt.grid()
plt.plot(x, y)
plt.plot(xt0, yt0)
plt.plot(xt1, yt1)
plt.scatter(x0, f(x0), c='red')
plt.scatter(x1, f(x1), c='black')
Out[42]:
<matplotlib.collections.PathCollection at 0xffff44df2210>
In [43]:
eta = .001
x0 = 5.8
x1 = x0 - eta * df(x0)
x2 = x1 - eta * df(x1)
xt0, yt0 = tangente(x0)
xt1, yt1 = tangente(x1)
xt2, yt2 = tangente(x2)
plt.grid()
plt.plot(x, y)
plt.plot(xt0, yt0)
plt.plot(xt1, yt1)
plt.plot(xt2, yt2)
plt.scatter(x0, f(x0), c='red')
plt.scatter(x1, f(x1), c='black')
plt.scatter(x2, f(x2), c='green')
Out[43]:
<matplotlib.collections.PathCollection at 0xffff44e07190>
In [44]:
def myplot(x_current):
plt.plot(x, y)
#xt, yt = tangente(x_current)
#plt.plot(xt, yt)
plt.scatter(x_current,f(x_current))
In [48]:
eta = .001
nb = 1000 #1000 #300# 200 #100 #20
x_current = 5.8
for i in range(nb):
x_current = x_current - eta * df(x_current)
myplot(x_current)
print('argmin: ', x_current)
print('f(argmin): ', f(x_current))
print('df(argmin): ', df(x_current))
argmin: 4.326345463688797 f(argmin): -6.91409678876613 df(argmin): 6.972925348236458e-09
In [49]:
eta = .001
epsilon = .000001 #.00001 #.0001 #0.001 #.01
x_prec = 5.8
x_current = x_prec - eta * df(x_prec)
while np.abs(x_prec - x_current) > epsilon:
x_prec = x_current
x_current = x_current - eta * df(x_current)
myplot(x_current)
print('argmin: ', x_current)
print('f(argmin): ', f(x_current))
print('df(argmin): ', df(x_current))
argmin: 4.326391329571001 f(argmin): -6.914096766604757 df(argmin): 0.0009663666136248139
In [66]:
eta = .001
epsilon = .000001 #.00001 #.0001 #0.001 #.01
nb_iter = 1
x_prec = 5.8
x_current = x_prec - eta * df(x_prec)
while np.abs(x_prec - x_current) > epsilon:
x_prec = x_current
x_current = x_current - eta * df(x_current)
nb_iter += 1
myplot(x_current)
print('argmin: ', x_current)
print('f(argmin): ', f(x_current))
print('df(argmin): ', df(x_current))
print('nombre iterations :' , nb_iter)
argmin: 4.326391329571001 f(argmin): -6.914096766604757 df(argmin): 0.0009663666136248139 nombre iterations : 444
Momentum¶
In [51]:
eta = .001
epsilon = .000001 #.00001 #.0001 #0.001 #.01
nb_iter = 1
x_prec = 0.1
x_current = x_prec - eta * df(x_prec)
while np.abs(x_prec - x_current) > epsilon:
x_prec = x_current
x_current = x_current - eta * df(x_current)
nb_iter += 1
myplot(x_current)
print('argmin: ', x_current)
print('f(argmin): ', f(x_current))
print('df(argmin): ', df(x_current))
print('nombre iterations :' , nb_iter)
argmin: 1.3926745528353317 f(argmin): -1.3827490934356135 df(argmin): -0.0009807664520309345 nombre iterations : 651
In [58]:
eta = .001
epsilon = .000001 #.00001 #.0001 #0.001 #.01
gamma = .95 #.95 #.9 #.5 #.3 #.2# .1
nb_iter = 1
x_prec = .1
v = 0
v = gamma * v + eta * df(x_prec)
x_current = x_prec - v
while np.abs(x_prec - x_current) > epsilon:
x_prec = x_current
v = gamma * v + eta * df(x_prec)
x_current = x_prec - v
nb_iter += 1
myplot(x_current)
plt.grid()
print('argmin: ', x_current)
print('f(argmin): ', f(x_current))
print('df(argmin): ', df(x_current))
print('nombre iterations :' , nb_iter)
argmin: 4.326557609325511 f(argmin): -6.91409631460516 df(argmin): 0.004470423289546943 nombre iterations : 349
In [ ]:
Approximation de la dérivée¶
Si on connait l'expression de $f$ :¶
In [59]:
def approx_derivative(f, x, h=1e-5):
return (f(x + h) - f(x - h)) / (2*h)
In [68]:
def f(x):
return x**4 - 11 * x**3 + 41 * x**2 -61 * x + 30
def df(x):
return 4 * x**3 - 33 * x**2 + 82 * x - 61
x = np.linspace(0, 6, 1000)
y_f = f(x)
y_df = df(x)
y_approx = approx_derivative(f, x, h=1e-10)
In [69]:
plt.plot(x, y_f, label="f(x)")
plt.scatter(x, y_approx, marker='x', label="f'(x) approximée")
plt.plot(x, y_df, label="f'(x)")
plt.legend()
plt.grid()
In [22]:
plt.scatter(x, y_f, label="f(x)")
plt.scatter(x, y_approx, label="f'(x) approximée", marker='x', c='red')
plt.scatter(x, y_df, label="f'(x)", marker='+', c='yellow')
plt.legend()
plt.grid()
Si on n'a que des donées :¶
In [70]:
# data :
x = np.linspace(0, 6, 100)
y = f(x) # Attention, on ne connaît pas f, on ne connaît que des réalisations de f
In [71]:
# Approximation de la dérivée par différences finies
dy_centered = (y[2:] - y[:-2]) / (x[2:] - x[:-2]) # centrée
x_centered = x[1:-1]
# Comparaison avec la dérivée exacte
y_exact = df(x)
plt.scatter(x, y_exact, marker='x', label="f'(x)")
plt.plot(x_centered, dy_centered, c='red', label="différence centrée")
plt.legend()
plt.show()
In [ ]: