Descente de Gradient

L'algorithme d'optimisation au cœur de l'apprentissage automatique

Qu'est-ce que la descente de gradient ?

La descente de gradient est un algorithme d'optimisation fondamental utilisé pour entraîner les réseaux de neurones et la plupart des modèles d'apprentissage automatique. Son objectif est de minimiser une fonction de coût en ajustant itérativement les paramètres du modèle.

Imaginez que vous êtes sur une montagne dans le brouillard et que vous voulez descendre au point le plus bas. Vous ne pouvez voir que quelques mètres autour de vous. La descente de gradient consiste à faire de petits pas dans la direction de la plus grande pente descendante.

Visualisation 3D de la descente de gradient

Illustration de la descente de gradient sur une surface 3D. L'algorithme suit la pente descendante pour atteindre le minimum global.
Source: Wikimedia Commons (Domaine Public)

Visualisation Interactive

Cette visualisation montre comment la descente de gradient trouve le minimum d'une fonction. La balle rouge représente la position actuelle des paramètres, se déplaçant vers le minimum.

💡 Essayez α > 1.0 pour voir les oscillations!

Itération: 0

Position (x): 0.00

Coût f(x): 0.00

Gradient ∂f/∂x: 0.00

Fonction de coût f(x) = x² + 2x + 1
Position actuelle
Minimum global

Les Mathématiques

1. Fonction de Coût

Mesure l'erreur du modèle :

J(θ) = (1/2m) Σ(h(x) - y)²

où θ sont les paramètres, h(x) la prédiction, y la vraie valeur

2. Calcul du Gradient

Dérivée partielle de la fonction de coût :

∂J/∂θ = (1/m) Σ(h(x) - y) · x

Indique la direction et l'amplitude du changement

3. Mise à Jour

Ajustement des paramètres :

θ := θ - α · ∂J/∂θ

α est le taux d'apprentissage (learning rate)

4. Répétition

Itérer jusqu'à convergence :

|∂J/∂θ| < ε

ε est le seuil de tolérance (ex: 0.001)

L'Algorithme Étape par Étape

1

Initialisation

Commencer avec des paramètres aléatoires θ

θ = random_values()
2

Prédiction

Calculer la sortie du modèle avec les paramètres actuels

prediction = model(X, θ)
3

Calcul de l'Erreur

Mesurer l'écart entre prédiction et réalité

error = prediction - y_true
4

Calcul du Gradient

Déterminer la direction de descente

gradient = ∂J/∂θ
5

Mise à Jour

Ajuster les paramètres dans la direction opposée au gradient

θ = θ - α × gradient
6

Convergence

Répéter jusqu'à ce que le changement soit minimal

if |gradient| < ε: stop

L'Importance du Taux d'Apprentissage (α)

🐌

Trop Petit

α = 0.001

  • Convergence très lente
  • Beaucoup d'itérations nécessaires
  • Risque de rester bloqué
  • Temps d'entraînement long

Optimal

α = 0.01 - 0.1

  • Convergence efficace
  • Nombre d'itérations raisonnable
  • Bon équilibre vitesse/stabilité
  • Généralement le meilleur choix
⚠️

Trop Grand

α = 0.5+

  • Oscillations autour du minimum
  • Risque de divergence
  • Peut manquer le minimum
  • Entraînement instable

Variantes de la Descente de Gradient

Batch Gradient Descent

📊

Utilise toutes les données à chaque itération

Avantages
  • Convergence stable
  • Gradient précis
Inconvénients
  • Très lent sur grands datasets
  • Beaucoup de mémoire requise
for all training examples: update θ

Stochastic Gradient Descent (SGD)

🎲

Utilise un exemple aléatoire à la fois

Avantages
  • Très rapide
  • Peu de mémoire
  • Peut échapper aux minimums locaux
Inconvénients
  • Chemin bruyant
  • Convergence instable
for each example: update θ

Mini-Batch Gradient Descent

Utilise de petits groupes de données (ex: 32-256)

Avantages
  • Meilleur équilibre
  • Utilise efficacement le GPU
  • Convergence stable et rapide
Inconvénients
  • Nécessite de choisir la taille du batch
for each mini-batch: update θ

✓ Choix le plus courant en pratique

Optimiseurs Avancés

Des variantes modernes de la descente de gradient qui améliorent la vitesse et la stabilité de la convergence.

Momentum

Accumule un vecteur de vélocité dans les directions de descente persistantes

v = β·v + ∇θ
θ = θ - α·v
Accélère la convergence et réduit les oscillations

AdaGrad

Adapte le taux d'apprentissage pour chaque paramètre

θ = θ - α/(√G + ε)·∇θ
Bon pour les données éparses

RMSprop

Moyenne mobile exponentielle des gradients au carré

E[g²] = γ·E[g²] + (1-γ)·g²
θ = θ - α/(√E[g²] + ε)·g
Résout le problème de diminution d'AdaGrad

En Pratique

🎯

Hyperparamètres Typiques

  • Learning Rate : 0.001 - 0.1
  • Batch Size : 32 - 256
  • Epochs : 10 - 1000+
  • Optimizer : Adam (β₁=0.9, β₂=0.999)
💡

Conseils

  • Commencer avec Adam et learning rate = 0.001
  • Utiliser learning rate decay
  • Normaliser les données d'entrée
  • Surveiller les courbes de perte
⚠️

Problèmes Courants

  • Explosion du gradient : Gradient clipping
  • Disparition du gradient : ReLU, Batch Norm
  • Minimums locaux : Momentum, SGD noise
  • Overfitting : Régularisation, Dropout
🔧

Debugging

  • Perte augmente → learning rate trop élevé
  • Perte stagne → learning rate trop bas
  • Gradients = 0 → vanishing gradient
  • Gradients = NaN → exploding gradient

Implémentation en Python

Descente de Gradient Simple

import numpy as np

def gradient_descent(X, y, learning_rate=0.01, epochs=1000):
    """
    Implémentation simple de la descente de gradient
    """
    m, n = X.shape
    theta = np.zeros(n)  # Initialisation

    for epoch in range(epochs):
        # Prédiction
        predictions = X @ theta

        # Calcul de l'erreur
        errors = predictions - y

        # Calcul du gradient
        gradient = (1/m) * X.T @ errors

        # Mise à jour des paramètres
        theta = theta - learning_rate * gradient

        # Calcul de la perte (optionnel)
        loss = (1/(2*m)) * np.sum(errors**2)

        if epoch % 100 == 0:
            print(f"Epoch {epoch}, Loss: {loss:.4f}")

    return theta

Avec PyTorch (Adam)

import torch
import torch.nn as nn
import torch.optim as optim

# Définir le modèle
model = nn.Linear(10, 1)

# Fonction de coût
criterion = nn.MSELoss()

# Optimiseur Adam
optimizer = optim.Adam(model.parameters(), lr=0.001)

# Boucle d'entraînement
for epoch in range(100):
    # Forward pass
    outputs = model(X_train)
    loss = criterion(outputs, y_train)

    # Backward pass et optimisation
    optimizer.zero_grad()  # Réinitialiser les gradients
    loss.backward()        # Calculer les gradients
    optimizer.step()       # Mettre à jour les paramètres

    if epoch % 10 == 0:
        print(f'Epoch [{epoch}/100], Loss: {loss.item():.4f}')

Résumé

🎯

Objectif : Minimiser la fonction de coût en ajustant les paramètres

📐

Principe : Suivre la direction opposée au gradient (pente descendante)

Formule clé : θ := θ - α · ∇J(θ)

🎚️

Learning Rate : Paramètre crucial qui contrôle la taille des pas

🔄

Variantes : Batch, SGD, Mini-batch (le plus utilisé)

🚀

En pratique : Adam est l'optimiseur le plus populaire