ML Learning Hub
Apprentissage par Renforcementavancé

Apprentissage par Renforcement

Un agent apprend en faisant — maximiser la récompense cumulée par interaction essai-erreur

Formalisme MDP, équations de Bellman, Q-learning, DQN, gradients de politique (REINFORCE) et PPO — avec visualisation interactive de la convergence Q.

55 min
12 diagrammes
8 Concepts Couverts

Prérequis

Probability & Statistics
Neural Networks
Calculus & Optimization

Concepts Couverts

MDPBellman EquationQ-LearningDQNPolicy GradientPPORLHFExploration vs Exploitation

Formules Clés

Équation de Bellman

Valeur Q optimale : récompense immédiate + meilleure valeur future actualisée. La cible récursive vers laquelle Q-learning converge

Mise à Jour Q-Learning

Déplacer l'estimation actuelle vers la cible Bellman par le pas α (apprentissage par différence temporelle)

Gradient de Politique (REINFORCE)

Augmenter la probabilité des actions ayant mené à des retours élevés, diminuer pour les actions à faible retour

Objectif PPO avec Clipping

Optimisation Politique Proximale : clip le rapport de mise à jour de la politique pour rester dans [1-ε, 1+ε] — entraînement stable en grands lots

Simulation Interactive

Loading visualization…
🎯

Apprendre en Faisant — le Paradigme RL

motivation

L'apprentissage supervisé a besoin d'exemples étiquetés. L'apprentissage par renforcement n'a besoin que d'un signal de récompense — feedback sur la qualité d'une action. C'est ainsi que les humains apprennent à marcher, jouer à des jeux et conduire : par la pratique, le feedback et l'amélioration progressive de la stratégie. Succès du RL : AlphaGo a battu le champion du monde de Go (2016) — entraîné par RL après pré-entraînement supervisé. Le raffinement de structure d'AlphaFold utilise une optimisation de type RL. ChatGPT / GPT-4 utilise RLHF (Reinforcement Learning from Human Feedback) pour aligner les sorties du modèle avec les préférences humaines. Les systèmes de manipulation robotique (Boston Dynamics, Figure AI) entraînent des politiques en simulation puis les transfèrent sur du matériel réel.

AlphaZero de DeepMind a appris aux échecs, au Go et au Shogi à un niveau surhumain en 24 heures de jeu en solo — aucune partie humaine enregistrée, pur RL à partir de jeu aléatoire et de la récompense de victoire.

💡

Le Cadre RL : Agent, Environnement, MDP

intuition

**Processus de Décision de Markov (MDP) :** (S, A, T, R, γ) — États S, Actions A, Fonction de transition T(s'|s,a), Récompense R(s,a,s'), escompte γ∈[0,1]. **Agent :** À chaque pas de temps t, observe l'état sₜ, prend l'action aₜ selon la politique π(aₜ|sₜ), reçoit la récompense rₜ. **Objectif :** Trouver la politique π* qui maximise le retour actualisé attendu Gₜ = Σᵢ γⁱrₜ₊ᵢ. **Fonction Q(s,a) :** Retour attendu en commençant de l'état s, prenant l'action a, puis suivant la politique optimale. Si on connaissait Q*, on choisirait toujours argmax_a Q*(s,a). **Distinction clé :** Le RL sans modèle (Q-learning, PPO) apprend directement par interaction sans connaître T. Le RL avec modèle (Dyna, MuZero) apprend un modèle du monde T̂ et planifie en imagination.

Le facteur d'escompte γ contrôle la myopie : γ=0,99 fait que l'agent se soucie des récompenses 100 pas dans le futur ; γ=0 est purement gourmand. La plupart des problèmes nécessitent γ∈[0,95, 0,999].

⚙️

Q-Learning : Tabulaire et Profond (DQN)

algorithm
1

Initialisez la table Q : Q(s,a)=0 pour toutes les paires état-action (tabulaire) ou le réseau Q de paramètres θ (DQN).

2

Pour chaque épisode : réinitialisez l'environnement, observez l'état initial s.

3

Sélection d'action ε-greedy : avec probabilité ε, choisissez une action aléatoire (exploration), sinon choisissez argmax_a Q(s,a) (exploitation). Décroissez ε de 1,0 → 0,05 pendant l'entraînement.

4

Exécutez l'action a, observez la récompense r et l'état suivant s'. Stockez (s,a,r,s') dans le tampon de replay (DQN).

5

Mise à jour TD : Q(s,a) ← Q(s,a) + α[r + γ·max_a' Q(s',a') - Q(s,a)].

6

Extras DQN : (1) Replay d'expérience — mini-lots aléatoires pour briser les corrélations. (2) Réseau cible — copie gelée Q_cible(θ⁻), synchronisée tous les N pas. (3) Double DQN — découpler la sélection d'action de l'estimation de valeur pour réduire la surestimation.

7

Convergence : le Q-learning tabulaire converge vers Q* pour les MDPs finis avec une exploration suffisante. Les réseaux Q neuronaux ne sont pas garantis mais fonctionnent bien en pratique.

</>

Q-Learning et DQN de Zéro

code
python102 lines
import numpy as np
import gymnasium as gym
from collections import deque
import torch, torch.nn as nn, torch.optim as optim

class="tok-comment"># ── class="tok-num">1. Q-Learning Tabulaire (FrozenLake) ─────────────────────────────────────
env = gym.make(class="tok-str">"FrozenLake-v1", is_slippery=False)
n_etats, n_actions = env.observation_space.n, env.action_space.n

Q       = np.zeros((n_etats, n_actions))
alpha   = class="tok-num">0.8          class="tok-comment"># taux dclass="tok-str">'apprentissage
gamma   = class="tok-num">0.95         class="tok-comment"># escompte
epsilon = class="tok-num">1.0          class="tok-comment"># taux d'exploration

for episode in range(class="tok-num">2000):
    s, _ = env.reset()
    termine = False
    while not termine:
        class="tok-comment"># ε-greedy
        if np.random.random() < epsilon:
            a = env.action_space.sample()
        else:
            a = np.argmax(Q[s])

        s_suiv, r, fin, tronque, _ = env.step(a)
        termine = fin or tronque

        class="tok-comment"># Mise à jour Q-learning (cible Bellman)
        cible_td = r + gamma * np.max(Q[s_suiv]) * (class="tok-num">1 - fin)
        Q[s, a] += alpha * (cible_td - Q[s, a])
        s = s_suiv

    epsilon = max(class="tok-num">0.01, epsilon * class="tok-num">0.999)   class="tok-comment"># décroissance exploration

print(fclass="tok-str">"Q-table entraînée, epsilon final : {epsilon:.4f}")

class="tok-comment"># ── class="tok-num">2. Deep Q-Network (CartPole) ─────────────────────────────────────────────
class DQN(nn.Module):
    def __init__(self, dim_obs, n_actions):
        super().__init__()
        self.reseau = nn.Sequential(
            nn.Linear(dim_obs, class="tok-num">128), nn.ReLU(),
            nn.Linear(class="tok-num">128, class="tok-num">128),    nn.ReLU(),
            nn.Linear(class="tok-num">128, n_actions)
        )
    def forward(self, x): return self.reseau(x)

env = gym.make(class="tok-str">"CartPole-v1")
dim_obs   = env.observation_space.shape[class="tok-num">0]
n_actions = env.action_space.n

q_reseau = DQN(dim_obs, n_actions)
q_cible  = DQN(dim_obs, n_actions)    class="tok-comment"># réseau cible gelé
q_cible.load_state_dict(q_reseau.state_dict())

optimiseur     = optim.Adam(q_reseau.parameters(), lr=class="tok-num">1e-3)
tampon_replay  = deque(maxlen=10_000)
gamma          = class="tok-num">0.99
epsilon        = class="tok-num">1.0
taille_lot     = class="tok-num">64
freq_maj_cible = class="tok-num">100
etapes         = class="tok-num">0

for episode in range(class="tok-num">500):
    s, _ = env.reset()
    recompense_totale = class="tok-num">0
    termine = False
    while not termine:
        class="tok-comment"># Action ε-greedy
        if np.random.random() < epsilon:
            a = env.action_space.sample()
        else:
            with torch.no_grad():
                a = q_reseau(torch.FloatTensor(s)).argmax().item()

        s_suiv, r, fin, tronque, _ = env.step(a)
        termine = fin or tronque
        tampon_replay.append((s, a, r, s_suiv, fin))
        s = s_suiv; recompense_totale += r; etapes += class="tok-num">1

        class="tok-comment"># Entraîner quand le tampon a assez d'échantillons
        if len(tampon_replay) >= taille_lot:
            lot = [tampon_replay[i] for i in np.random.choice(len(tampon_replay), taille_lot, replace=False)]
            S, A, R, S_suiv, D = map(np.array, zip(*lot))
            S_t = torch.FloatTensor(S); A_t = torch.LongTensor(A)
            R_t = torch.FloatTensor(R); S_suiv_t = torch.FloatTensor(S_suiv)
            D_t = torch.FloatTensor(D)

            with torch.no_grad():
                q_max_suiv = q_cible(S_suiv_t).max(class="tok-num">1)[class="tok-num">0]
                cible = R_t + gamma * q_max_suiv * (class="tok-num">1 - D_t)

            q_courant = q_reseau(S_t).gather(class="tok-num">1, A_t.unsqueeze(class="tok-num">1)).squeeze()
            perte = nn.functional.mse_loss(q_courant, cible)
            optimiseur.zero_grad(); perte.backward(); optimiseur.step()

        if etapes % freq_maj_cible == class="tok-num">0:
            q_cible.load_state_dict(q_reseau.state_dict())

    epsilon = max(class="tok-num">0.05, epsilon * class="tok-num">0.995)
    if episode % class="tok-num">50 == class="tok-num">0:
        print(fclass="tok-str">"Épisode {episode:4d} | récompense={recompense_totale:class="tok-num">5.0f} | ε={epsilon:.3f}")

Gradient de Politique et Acteur-Critique (A2C/PPO)

math

Les méthodes de gradient de politique optimisent directement la politique π_θ au lieu d'une fonction de valeur. L'architecture acteur-critique utilise deux réseaux : l'acteur π_θ sélectionne les actions, le critique V_φ estime les valeurs d'état comme baseline pour réduire la variance du gradient. PPO (Proximal Policy Optimization) ajoute un mécanisme de clipping pour éviter les mises à jour de politique destructivement grandes — le rapport r_t(θ) = π_θ(a|s)/π_θ_ancien(a|s) est limité à [1-ε, 1+ε]. Cela rend PPO suffisamment efficace en termes d'échantillons pour un usage pratique et c'est l'algorithme standard dans RLHF pour les LLMs.

Avantage, perte A2C avec bonus d'entropie, PPO avec clipping
⚠️

La Triade Mortelle et les Modes d'Échec Courants du RL

pitfall

La triade mortelle (Sutton & Barto) : combiner (1) l'approximation de fonctions (réseaux de neurones), (2) le bootstrapping (mises à jour TD), et (3) l'apprentissage hors-politique peut provoquer une divergence. DQN évite cela avec des tampons de replay et des réseaux cibles mais l'entraînement peut rester instable. Pièges pratiques du RL : (1) La mise en forme des récompenses peut introduire des raccourcis involontaires — l'agent de course en bateau qui a appris à tourner en rond pour collecter des bonus. (2) Les récompenses rares rendent l'exploration presque impossible — utilisez la motivation intrinsèque (curiosité) ou la mise en forme des récompenses avec précaution. (3) L'écart sim-to-real — les politiques entraînées en simulation échouent sur les robots réels à cause de la physique non modélisée. (4) L'évaluation avec des graines fixes est trompeuse — les résultats RL ont une variance élevée ; rapportez moyenne ± écart-type sur 10+ graines.

L'agent de course en bateau d'OpenAI entraîné avec des récompenses de mise en forme a appris à conduire en cercles pour collecter des bonus au lieu de terminer la course — un célèbre cas d'échec de piratage de récompense.

?Vérification des Connaissances

La progression est sauvegardée dans votre navigateur — aucun compte requis.

Besoin d'un ingénieur IA ou data scientist ?

Je conçois des modèles ML sur mesure, des agents IA, de la vision par ordinateur et de l'automatisation — de l'idée à la production.