Exemple d'implémentation de l'algorithm du gradient ("gradient descent") en python pour trouver un minimum local:
Test avec une fonction à une dimension

from scipy import miscimport matplotlib.pyplot as pltimport numpy as np#----------------------------------------------------------------------------------------## Function Definitiondef fonction(x):return 3*x*x+2*x+1#----------------------------------------------------------------------------------------## Plot functionx = np.arange(-2.0, 2.0, 0.01)y = fonction(x)plt.plot(x, y,'r-')#plt.show()#----------------------------------------------------------------------------------------## Gradient Descentalpha = 0.1 # learning ratenb_max_iter = 100 # Nb max d'iterationeps = 0.0001 # stop conditionx0 = 1.5 # start pointy0 = fonction(x0)plt.scatter(x0, fonction(x0))cond = eps + 10.0 # start with cond greater than eps (assumption)nb_iter = 0tmp_y = y0while cond > eps and nb_iter < nb_max_iter:x0 = x0 - alpha * misc.derivative(fonction, x0)y0 = fonction(x0)nb_iter = nb_iter + 1cond = abs( tmp_y - y0 )tmp_y = y0print x0,y0,condplt.scatter(x0, y0)plt.title("Gradient Descent Python (1d test)")plt.grid()plt.savefig("gradient_descent_1d_python.png", bbox_inches='tight')plt.show()
Test avec une fonction à deux dimensions

from scipy import miscimport matplotlib.pyplot as pltimport numpy as npimport math#----------------------------------------------------------------------------------------## Functiondef fonction(x1,x2):return - 1.0 * math.exp(-x1**2 - x2**2);def partial_derivative(func, var=0, point=[]):args = point[:]def wraps(x):args[var] = xreturn func(*args)return misc.derivative(wraps, point[var], dx = 1e-6)#----------------------------------------------------------------------------------------## Plot Functionx1 = np.arange(-2.0, 2.0, 0.1)x2 = np.arange(-2.0, 2.0, 0.1)xx1,xx2 = np.meshgrid(x1,x2);z = - 1.0 * np.exp(-xx1**2 - xx2**2);h = plt.contourf(x1,x2,z)#plt.show()#----------------------------------------------------------------------------------------## Gradient Descentalpha = 0.1 # learning ratenb_max_iter = 100 # Nb max d'iterationeps = 0.0001 # stop conditionx1_0 = 1.0 # start pointx2_0 = 1.5z0 = fonction(x1_0,x2_0)plt.scatter(x1_0,x2_0)cond = eps + 10.0 # start with cond greater than eps (assumption)nb_iter = 0tmp_z0 = z0while cond > eps and nb_iter < nb_max_iter:tmp_x1_0 = x1_0 - alpha * partial_derivative(fonction, 0, [x1_0,x2_0])tmp_x2_0 = x2_0 - alpha * partial_derivative(fonction, 1, [x1_0,x2_0])x1_0 = tmp_x1_0x2_0 = tmp_x2_0z0 = fonction(x1_0,x2_0)nb_iter = nb_iter + 1cond = abs( tmp_z0 - z0 )tmp_z0 = z0print x1_0,x2_0,condplt.scatter(x1_0, x2_0)plt.title("Gradient Descent Python (2d test)")plt.savefig("gradiend_descent_2d_python.png", bbox_inches='tight')plt.show()
Test avec une fonction à trois dimensions

from scipy import miscimport matplotlib.pyplot as pltimport numpy as npimport math#----------------------------------------------------------------------------------------## Functionglobal x1_sphereglobal x2_sphereglobal x3_spherex1_sphere = 1.5x2_sphere = 2.5x3_sphere = 0.5def fonction(x1,x2,x3):r1 = x1 - x1_spherer2 = x2 - x2_spherer3 = x3 - x3_spherereturn r1*r1 + r2*r2 + r3*r3 ;def partial_derivative(func, var=0, point=[]):args = point[:]def wraps(x):args[var] = xreturn func(*args)return misc.derivative(wraps, point[var], dx = 1e-6)#----------------------------------------------------------------------------------------## Plot Functionx1 = np.arange(0.0, 3.0, 0.1)x2 = np.arange(0.0, 3.0, 0.1)x3 = np.arange(0.0, 3.0, 0.1)dim_x1 = x1.shape[0]dim_x2 = x2.shape[0]dim_x3 = x3.shape[0]print dim_x1z2 = np.zeros((dim_x1,dim_x2))z3 = np.zeros((dim_x1,dim_x3))for i in np.arange(dim_x1):for j in np.arange(dim_x2):r1 = x1[i] - x1_spherer2 = x2[j] - x2_spherer3 = 0.0 - x3_spherez2[i,j] = r1*r1 + r2*r2 + r3*r3h = plt.contourf(x1,x2,z2)plt.savefig("gradient_descent_3d_python_x1_x2", bbox_inches='tight')plt.close()for i in np.arange(dim_x1):for j in np.arange(dim_x3):r1 = x1[i] - x1_spherer2 = 0.0 - x2_spherer3 = x3[j] - x3_spherez3[i,j] = r1*r1 + r2*r2 + r3*r3h = plt.contourf(x1,x3,z3)plt.savefig("gradient_descent_3d_python_x1_x3", bbox_inches='tight')#----------------------------------------------------------------------------------------## Gradient Descentalpha = 0.1 # learning ratenb_max_iter = 100 # Nb max d'iterationeps = 0.0001 # stop conditionx1_0 = 0.0 # start pointx2_0 = 0.5x3_0 = 0.0z0 = fonction(x1_0,x2_0,x3_0)plt.scatter(x1_0,x3_0)cond = eps + 10.0 # start with cond greater than eps (assumption)nb_iter = 0tmp_z0 = z0while cond > eps and nb_iter < nb_max_iter:tmp_x1_0 = x1_0 - alpha * partial_derivative(fonction, 0, [x1_0,x2_0,x3_0])tmp_x2_0 = x2_0 - alpha * partial_derivative(fonction, 1, [x1_0,x2_0,x3_0])tmp_x3_0 = x3_0 - alpha * partial_derivative(fonction, 2, [x1_0,x2_0,x3_0])x1_0 = tmp_x1_0x2_0 = tmp_x2_0x3_0 = tmp_x3_0z0 = fonction(x1_0,x2_0,x3_0)nb_iter = nb_iter + 1cond = abs( tmp_z0 - z0 )tmp_z0 = z0print x1_0,x2_0,x3_0,condplt.scatter(x3_0, x1_0)plt.title("Gradient Descent Python (3d test)")plt.savefig("gradient_descent_23_python.png", bbox_inches='tight')plt.show()
Références
| Liens | Site |
|---|---|
| Algorithme du gradient | wikipedia |
