École Supérieure Privée d’Ingénierie et de Technologies
Resolution Numérique de Problème d’Optimisation par la Méthode de
Descente de Gradient
Module : Analyse Numérique (3A/B) UP Maths Année Universitaire : 2024-2025
Méthode de Descente du Gradient
La méthode de descente du gradient est un algorithme d’optimisation utilisé pour minimiser une fonction
f ( x ). Elle est particulièrement utile dans les problèmes où la fonction à minimiser est différentiable.
Partie I : Théorique
Exercice 1
On considère la fonction :
f ( x, y) = x2 + y2 + 4x + 6y.
1. Calculer ∇ f ( x, y).
La fonction f est différentiable sur R2 dont les dérivées partielles sont données par :
∂f ∂f
( x, y) = 2x + 4, ( x, y) = 2y + 6.
∂x ∂y
Ainsi, le gradient de f est donné par :
∇ f ( x, y) = (2x + 4 , 2y + 6) .
2. Donner la forme générale de l’algorithme de descente de gradient
L’algorithme de descente de gradient est :
( xk+1 , yk+1 ) = ( xk , yk ) − δ(2xk + 4, 2yk + 6),
où δ est le pas.
3. Déterminer les huits premières itérations avec ( x0 , y0 ) = (0, 0) et δ = 0.1.
Première itération :
x0 = 0.000000, y0 = 0.000000, ∇ f ( x0 , y0 ) = (4, 6), f ( x0 , y0 ) = 02 + 02 + 4 × 0 + 6 × 0 = 0.000000.
On applique l’algorithme de descente de gradient :
( x1 , y1 ) = (0, 0) − 0.1(4, 6) = (−0.4, −0.6)
Or ∇ f ( x1 , y1 ) = (2 × (−0.4) + 4, 2 × (−0.6) + 6) = (3.2, 4.8), donc la descente continue.
Page 1/10
Deuxième itération :
x1 = −0.400000, y1 = −0.600000, ∇ f ( x1 , y1 ) = (3.2, 4.8), f ( x1 , y1 ) = (−0.4)2 + (−0.6)2 + 4 ×
(−0.4) + 6 × (−0.6) = 0.16 + 0.36 − 1.6 − 3.6 = −4.680000.
On applique l’algorithme de descente de gradient :
( x2 , y2 ) = (−0.4, −0.6) − 0.1(3.2, 4.8) = (−0.720000, −1.080000)
Or ∇ f ( x2 , y2 ) = (2 × (−0.72) + 4; 2 × (−1.08) + 6) = (2.56; 3.84), donc la descente continue.
k xk yk ∇ f ( xk , yk ) f ( xk , yk )
0 0.000000 0.000000 (4.000000, 6.000000) 0.000000
1 -0.400000 -0.600000 (3.200000, 4.800000) -5.200000
2 -0.720000 -1.080000 (2.560000, 3.840000) -8.320000
3 -0.976000 -1.464000 (2.048000, 3.072000) -10.048000
4 -1.180800 -1.771200 (1.638400, 2.457600) -11.238400
5 -1.344640 -2.016960 (1.310720, 1.966080) -12.090880
6 -1.475712 -2.213568 (1.048576, 1.572864) -12.672704
7 -1.580570 -2.370854 (0.838861, 1.258291) -13.078163
8 -1.664456 -2.496683 (0.671089, 1.006633) -13.362530
Le tableau montre que les valeurs de xk et yk se rapprochent progressivement du minimum théorique
(−2, −3), et la valeur de la fonction f ( xk , yk ) tend vers −13.
4. Refaire l’application avec δ = 0.01 et δ = 0.99. et interpréter l’influence du pas δ sur la convergence.
Pour δ = 0.01, X0 = (0, 0) :
k xk yk ∇ f ( xk , yk ) f ( xk , yk )
0 0.000000 0.000000 (4.000000, 6.000000) 0.000000
1 -0.040000 -0.060000 (3.920000, 5.880000) -0.520000
2 -0.079200 -0.118800 (3.841600, 5.762400) -1.036800
3 -0.117616 -0.176424 (3.764768, 5.646848) -1.540944
4 -0.155259 -0.232888 (3.689473, 5.533311) -2.033152
5 -0.192154 -0.288221 (3.615692, 5.421644) -2.513728
6 -0.228311 -0.342442 (3.543378, 5.311811) -2.983104
7 -0.263744 -0.395570 (3.472510, 5.203775) -3.441600
8 -0.298469 -0.447623 (3.403061, 5.097502) -3.889536
Le tableau montre que les valeurs de xk et yk se rapprochent progressivement du minimum théorique
(−2, −3), mais la convergence est très lente en raison du petit pas δ = 0.01. La valeur de la fonction
f ( xk , yk ) tend vers −13, mais cela nécessiterait un nombre d’itérations beaucoup plus élevé pour s’en
approcher significativement.
Page 2/10
Pour δ = 0.99, X0 = (0, 0) :
k xk yk ∇ f ( xk , yk ) f ( xk , yk )
0 0.000000 0.000000 (4.000000, 6.000000) 0.000000
1 -3.960000 -5.940000 (−3.920000, −5.880000) -39.600000
2 -0.079200 -0.118800 (3.841600, 5.762400) -1.036800
3 -3.881568 -5.822352 (−3.763136, −5.644704) -38.815680
4 -0.155259 -0.232888 (3.689473, 5.533311) -2.033152
5 -3.807885 -5.711828 (−3.615770, −5.423655) -38.078848
6 -0.227892 -0.341838 (3.544216, 5.316324) -2.992550
7 -3.738365 -5.607548 (−3.476730, −5.215096) -37.383654
8 -0.296937 -0.445405 (3.406126, 5.109190) -3.915793
Le tableau montre que les valeurs de xk et yk oscillent autour du minimum théorique (−2, −3) en
raison du pas δ = 0.99, qui est trop grand. Cela empêche une convergence stable, et la valeur de la
fonction f ( xk , yk ) oscille également.
N.B : Pour atteindre une convergence stable, il faudrait bien choisir δ.
Partie II : Pratique
import numpy as np
import sympy as sp
Principe de base
1. Objectif : Minimiser une fonction f(x) en trouvant le point x tel que f ( x ) soit minimal.
2. Idée principale : La méthode utilise le gradient de la fonction pour guider les mises à jour de x vers
le minimum.
Le gradient ∇ f ( x ) indique la direction de la plus forte croissance de f ( x ). Pour minimiser f ( x ), on se
déplace dans la direction opposée au gradient.
Page 3/10
Algorithme
L’algorithme de descente du gradient peut être décrit comme suit :
1. Initialisation : Choisir un point de départ x0 et fixer un pas δ > 0.
2. Mise à jour itérative : À chaque étape k, mettre à jour xk selon la formule :
x k +1 = x k δ ∇ f ( x k )
où :
— xk est la valeur actuelle de x,
— δ est le pas de descente,
— ∇ f ( xk ) est le gradient de f évalué en xk .
3. Condition d’arrêt : Arrêter lorsque :
— Le gradient est suffisamment proche de zéro (||∇ f ( xk )|| < ϵ),
— ou lorsque le nombre maximal d’itérations est atteint.
Choix du pas δ
— Trop petit : Si δ est trop petit, la convergence sera lente.
— Trop grand : Si δ est trop grand, les mises à jour peuvent osciller ou diverger.
— Un choix optimal de δ garantit une convergence rapide et stable.
Exemple en 1D
Pour une fonction f ( x ) en une dimension, la mise à jour devient :
x k +1 = x k − δ · f ′ ( x k )
où f ′ ( xk ) est la dérivée de f par rapport à x.
Par exemple, si f ( x ) = x2 + 3x + 2 :
1. Définir la fonction mathématique f ( x ) = x2 + 3x + 2 en utilisant sympy.
Correction :
x = sp.symbols('x')
f = lambda x : x**2 + 3*x + 2
print("Fonction définie :", f(x))
Résultat :
Fonction définie : x**2 + 3*x + 2
Page 4/10
2. Calculer la dérivée analytique f ′ ( x ).
Correction :
f_prime = sp.Lambda(x, sp.diff(f(x), x))
print("Dérivée f'(x) :", f_prime(x))
Résultat :
Dérivée f'(x) : 2*x + 3
Exercice 1 :
1. Ecrire une fonction ‘gradient_descent’ qui prend en entrée la fonction dérivée f ′ ( x ), le point de départ
x0 , le pas δ, la tolérance pour la norme du gradient ϵ, le nombre maximal d’itérations max_iter.
Cette fonction doit retourner la liste des valeurs de x obtenues à chaque itération ainsi que le nombre
d’itérations lorsque le gradient est suffisamment proche de zéro.
Correction :
#Fonction de descente du gradient avec condition d'arrêt basée sur le gradient
def gradient_descent(f_prime, x0, alpha, epsilon, max_iter):
x_values = [x0] # Liste pour stocker les valeurs de x à chaque itération
current_x = x0
grad = f_prime(current_x).evalf() # Calcul initial du gradient
iterations = 0 # Compteur d'itérations
#Boucle while : continuer tant que la norme du gradient > epsilon
while abs(grad) > epsilon and iterations < max_iter:
# Mise à jour de x
new_x = current_x - alpha * grad
x_values.append(new_x)
# Mettre à jour les variables pour l'itération suivante
current_x = new_x
grad = f_prime(current_x).evalf() # Calcul du gradient
iterations += 1
return x_values, iterations
Page 5/10
2. Tester la fonction ’gradient_descent’ pour f ( x ) = x2 + 3x + 2, x0 = −5, δ = 0.1, ϵ = 1−3 , max_iter =
1000.
Correction :
x0 = -5 # Point de départ
alpha = 0.1 # Taux d'apprentissage
max_iter = 1000 # Nombre maximal d'itérations
epsilon = 1e-3 # Tolérance pour la norme du gradient
x_values, Niter = gradient_descent(f_prime, x0, alpha, epsilon, max_iter)
print("Valeurs de x à chaque itération :", x_values)
print("Nombre d'itérations :", Niter)
Résultat :
Valeurs de x à chaque itération : [-5, -4.3, -3.74, -3.292, ...]
Nombre d'itérations : 40
3. Visualiser la convergence en traçant :
— La fonction f ( x ) sur l’intervalle [−6, 2],
— Les points x obtenus à chaque itération.
Correction :
x_range = np.linspace(-6, 2, 400)
y_range = [f(val) for val in x_range]
plt.figure(figsize=(8, 6))
plt.plot(x_range, y_range, label="$f(x) = x^2 + 3x + 2$", color="blue")
y_values_numeric = [f(val) for val in x_values]
plt.scatter(x_values, y_values_numeric, color="red", label="Points de descente")
plt.title("Descente du Gradient")
plt.xlabel("x")
plt.ylabel("f(x)")
plt.legend()
plt.grid(True)
plt.show()
Page 6/10
Résultat :
Figure 1 – Visualisation de la convergence de la méthode de descente du gradient pour f ( x ) = x2 +
3x + 2.
Exercice 1 (Asynchrone) :
Considérons l’équation suivante :
f ( x ) = x2 − 3x + 3
1. Déterminer le gradient ∇ f ( x ) = f ′ ( x ) (la dérivée de f).
La fonction f est dérivable sur R de gradient :
∇ f ( x ) = f ′ ( x ) = 2x − 3.
2. Appliquer l’algorithme de descente de gradient avec le pas δ = 0.2 et la valeur initial choisi x0 = 2
et donner les six permières itérations à ϵ = 10−4 près.
L’algorithme de descente de gradient est donné par : xk+1 = xk − δ∇ f ( xk ), où δ est le pas.
Pour δ = 0.2 et x0 = 2 :
1ère itération :
x0 = 2.000000, ∇ f ( x0 ) = 2 × 2 − 3 = 1.000000, f ( x0 ) = 22 − 3 × 2 + 3 = 1.000000.
On applique l’algorithme de descente de gradient :
x1 = x0 − δ∇ f ( x0 ) = 2.000000 − 0.2 × 1.000000 = 1.800000.
∇ f ( x1 ) = 2 × 1.800000 − 3 = 0.600000, donc la descente continue.
Page 7/10
2ème itération :
x1 = 1.800000, ∇ f ( x1 ) = 2 × 1.800000 − 3 = 0.600000, f ( x1 ) = 1.8000002 − 3 × 1.800000 + 3 =
0.840000.
On applique l’algorithme de descente de gradient :
x2 = x1 − δ∇ f ( x1 ) = 1.800000 − 0.2 × 0.600000 = 1.680000,
∇ f ( x2 ) = 2 × 1.680000 − 3 = 0.360000, donc la descente continue.
Ainsi sous cette façon nous obtenons les six premières itérations comme indique le tableau suivant :
k xk ∇ f ( xk ) f ( xk )
0 2.000000 2 × 2 − 3 = 1.000000 22 − 3 × 2 + 3 = 1.000000
1 1.800000 2 × 1.80 − 3 = 0.600000 1.802 − 3 × 1.80 + 3 = 0.840000
2 1.680000 2 × 1.68 − 3 = 0.360000 1.682 − 3 × 1.68 + 3 = 0.734400
3 1.608000 2 × 1.608 − 3 = 0.216000 1.6082 − 3 × 1.608 + 3 = 0.673344
4 1.564800 2 × 1.5648 − 3 = 0.129600 1.56482 − 3 × 1.5648 + 3 = 0.639038
5 1.538880 2 × 1.53888 − 3 = 0.077760 1.538882 − 3 × 1.53888 + 3 = 0.619213
6 1.523328 2 × 1.523328 − 3 = 0.046656 1.5233282 − 3 × 1.523328 + 3 = 0.607528
3. Refaire l’application avec un pas δ = 0.08.
1ère itération :
x0 = 2.000000, ∇ f ( x0 ) = 2 × 2 − 3 = 1.000000, f ( x0 ) = 22 − 3 × 2 + 3 = 1.000000.
On applique l’algorithme de descente de gradient :
x1 = x0 − δ∇ f ( x0 ) = 2.000000 − 0.08 × 1.000000 = 1.920000
∇ f ( x1 ) = 2 × 1.920000 − 3 = 0.840000, donc la descente continue.
2ème itération :
x1 = 1.920000, ∇ f ( x1 ) = 2 × 1.920000 − 3 = 0.840000, f ( x1 ) = 1.9200002 − 3 × 1.920000 + 3 =
0.846400.
On applique l’algorithme de descente de gradient :
x2 = x1 − δ∇ f ( x1 ) = 1.920000 − 0.08 × 0.840000 = 1.852800,
∇ f ( x2 ) = 2 × 1.852800 − 3 = 0.705600, donc la descente continue.
Ainsi, sous cette façon, nous obtenons les six premières itérations comme indique le tableau suivant :
k xk ∇ f ( xk ) f ( xk )
0 2.000000 2 × 2 − 3 = 1.000000 22 − 3 × 2 + 3 = 1.000000
1 1.920000 2 × 1.92 − 3 = 0.840000 1.922 − 3 × 1.92 + 3 = 0.846400
2 1.852800 2 × 1.8528 − 3 = 0.705600 1.85282 − 3 × 1.8528 + 3 = 0.722823
3 1.796352 2 × 1.796352 − 3 = 0.592704 1.7963522 − 3 × 1.796352 + 3 = 0.626548
4 1.748936 2 × 1.748936 − 3 = 0.497872 1.7489362 − 3 × 1.748936 + 3 = 0.551989
5 1.709106 2 × 1.709106 − 3 = 0.418212 1.7091062 − 3 × 1.709106 + 3 = 0.494118
6 1.675649 2 × 1.675649 − 3 = 0.351298 1.6756492 − 3 × 1.675649 + 3 = 0.447625
Page 8/10
4. Comparer les résultats et interpréter la différence entre les deux choix de δ.
Avec δ = 0.2, la convergence est plus rapide, mais avec δ = 0.08, la convergence est plus lente. Un
pas trop grand peut entraîner des oscillations, tandis qu’un pas trop petit ralentit la convergence.
Exercice 2 (Asynchrone) :
On considère la fonction suivante :
f ( x, y) = x2 + 3y2
1. Calculer ∇ f ( x, y).
La fonction f est différentiable sur R2 dont le gradient est donné par :
( )
2x
∇ f ( x, y) = .
6y
2. Donner la forme générale de l’algorithme de descente de gradient pour cette fonction avec un pas δ.
L’algorithme de descente de gradient est :
( ) ( ) ( )
x k +1 xk 2xk
= −δ
y k +1 yk 6yk
où δ est le pas.
3. Déterminer les cinq premières itérations avec ( x0 , y0 ) = (1, 1) et le pas δ = 0.2.
1ère itération : ( )
2
x0 = 1.000000, y0 = 1.000000, ∇ f ( x0 , y0 ) = , f ( x0 , y0 ) = 4.000000.
6
On applique l’algorithme de descente de gradient :
( ) ( ) ( ) ( ) ( )
x1 1 2 1 − 0.4 0.600000
= − 0.2 = =
y1 1 6 1 − 1.2 −0.200000
( ) ( )
2 × 0.6 1.2
Or ∇ f ( x1 , y1 ) = = , donc la descente continue.
6 × (−0.2) −1.2
2ème itération : ( )
1.2
x1 = 0.600000, y1 = −0.200000, ∇ f ( x1 , y1 ) = , f ( x1 , y1 ) = 0.480000.
−1.2
On applique l’algorithme de descente de gradient :
( ) ( ) ( ) ( ) ( )
x2 0.6 1.2 0.6 − 0.24 0.360000
= − 0.2 = = .
y2 −0.2 −1.2 −0.2 + 0.24 0.040000
( ) ( )
2 × 0.36 0.72
Or ∇ f ( x2 , y2 ) = = , donc la descente continue.
6 × 0.04 0.24
Page 9/10
Ainsi sous cette façon nous obtenons les cinq premières itérations comme indique le tableau suivant :
k xk yk ∇ f ( xk , yk ) f ( xk , yk )
0 1.000000 1.000000 (2, 6) 4.000000
1 0.600000 -0.200000 (1.2, −1.2) 0.480000
2 0.360000 0.040000 (0.72, 0.24) 0.144000
3 0.216000 -0.008000 (0.432, −0.048) 0.048384
4 0.129600 0.001600 (0.2592, 0.0096) 0.016796
5 0.077760 -0.000320 (0.15552, −0.00192) 0.005878
4. Refaire l’application avec δ = 0.01.
1ère itération : ( ) ( )
2×1 2
x0 = 1.000000, y0 = 1.000000, ∇ f ( x0 , y0 ) = = , f ( x0 , y0 ) = 12 + 3 × 12 = 4.000000.
6×1 6
On applique l’algorithme de descente de gradient :
( ) ( ) ( ) ( ) ( )
x1 1 2 1 − 0.02 0.980000
= − 0.01 = =
y1 1 6 1 − 0.06 0.940000
( ) ( )
2 × 0.98 1.96
Or ∇ f ( x1 , y1 ) = = , donc la descente continue.
6 × 0.94 5.64
2ème itération : ( )
1.96
x1 = 0.980000, y1 = 0.940000, ∇ f ( x1 , y1 ) = , f ( x1 , y1 ) = 0.982 + 3 × 0.942 = 0.9604 +
5.64
2.6508 = 3.611200.
On applique l’algorithme de descente de gradient :
( ) ( ) ( ) ( ) ( )
x2 0.98 1.96 0.98 − 0.0196 0.960400
= − 0.01 = =
y2 0.94 5.64 0.94 − 0.0564 0.883600
( ) ( )
2 × 0.9604 1.9208
Or ∇ f ( x2 , y2 ) = = , donc la descente continue. Ainsi, sous cette façon,
6 × 0.8836 5.3016
nous obtenons les cinq premières itérations comme indique le tableau suivant :
k xk yk ∇ f ( xk , yk ) f ( xk , yk )
0 1.000000 1.000000 (2, 6) 4.000000
1 0.980000 0.940000 (1.96, 5.64) 3.611200
2 0.960400 0.883600 (1.9208, 5.3016) 3.258304
3 0.941192 0.830584 (1.882384, 4.983504) 2.938547
4 0.922368 0.780749 (1.844736, 4.684493) 2.649999
5 0.903921 0.733904 (1.807842, 4.403424) 2.390000
5. Comparer les trajectoires obtenues et expliquer les différences de convergence.
Avec δ = 0.2, la convergence est plus rapide, mais avec δ = 0.01, la convergence est plus lente mais
plus stable. Un pas trop grand peut entraîner des oscillations, tandis qu’un pas trop petit ralentit la
convergence.
Page 10/10