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>]
No description has been provided for this image

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>
No description has been provided for this image
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>
No description has been provided for this image
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>
No description has been provided for this image
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>
No description has been provided for this image
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
No description has been provided for this image
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
No description has been provided for this image
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
No description has been provided for this image

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
No description has been provided for this image
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
No description has been provided for this image
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()
No description has been provided for this image
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()
No description has been provided for this image
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()
No description has been provided for this image
In [ ]: