Module 8 — Méthodes de gradient de politique
Le DQN du module précédent apprend , puis en déduit une politique par argmax. C'est un détour. Les méthodes de gradient de politique apprennent directement la fonction qui associe une action à un état, sans passer par les valeurs. Cette approche différente débloque deux capacités : les actions continues et la stochasticité.
Politique paramétrée
Une politique est une distribution sur les actions, produite par un réseau de paramètres . Pour un espace d'actions discret, le réseau émet un logit par action et une softmax :
Pour un espace continu, le réseau émet une moyenne (et parfois un écart-type) d'une gaussienne :
Deux propriétés changent tout par rapport au DQN. La politique est stochastique par construction — l'exploration est intégrée, pas ajoutée. Elle est différentiable par rapport à , ce qui autorise la descente de gradient directe sur l'objectif.
Le théorème du gradient de politique
L'objectif est le retour attendu . Son gradient s'écrit :
À lire ainsi : pour chaque action jouée, on augmente ou diminue sa log-probabilité proportionnellement au retour observé. Une bonne trajectoire renforce les actions qui l'ont produite ; une mauvaise trajectoire les affaiblit. Rien de plus.
Ce r ésultat est central. Il ne suppose ni discret ni continu, ni Markov strict, ni environnement connu. Il n'exige que la capacité à échantillonner et à calculer .
REINFORCE, l'implémentation minimale
L'algorithme est direct : jouer des épisodes, calculer les retours, appliquer la mise à jour ci-dessus.
import torch, torch.nn as nn
import gymnasium as gym
env = gym.make("CartPole-v1")
politique = nn.Sequential(nn.Linear(4, 128), nn.ReLU(), nn.Linear(128, 2))
optimiseur = torch.optim.Adam(politique.parameters(), lr=1e-2)
gamma = 0.99
for episode in range(1000):
log_probas, recompenses = [], []
s, _ = env.reset(seed=episode)
while True:
logits = politique(torch.tensor(s, dtype=torch.float32))
distribution = torch.distributions.Categorical(logits=logits)
a = distribution.sample()
log_probas.append(distribution.log_prob(a))
s, r, termine, tronque, _ = env.step(int(a))
recompenses.append(r)
if termine or tronque:
break
# Calcul des retours actualises en arriere
retours, G = [], 0.0
for r in reversed(recompenses):
G = r + gamma * G
retours.insert(0, G)
retours = torch.tensor(retours, dtype=torch.float32)
retours = (retours - retours.mean()) / (retours.std() + 1e-8) # ligne de base par centrage
perte = -torch.stack([lp * G for lp, G in zip(log_probas, retours)]).sum()
optimiseur.zero_grad(); perte.backward(); optimiseur.step()
REINFORCE résout CartPole en quelques centaines d'épisodes. Mais la courbe de récompense est beaucoup plus bruit ée que celle du DQN, avec des chutes brutales même après avoir atteint le score maximal.
Le talon d'Achille : la variance
REINFORCE fait deux choses coûteuses. Il n'apprend qu'à la fin d'un épisode complet (comme Monte-Carlo). Et il multiplie chaque log-probabilité par le retour entier , une somme de nombreux termes aléatoires.
Le gradient a donc une variance très élevée. Deux épisodes proches peuvent produire des mises à jour de signes opposés. Il faut beaucoup de trajectoires pour que le bruit se moyenne — et les mises à jour peuvent osciller violemment entre-temps.
La ligne de base, la première réduction de variance
Une astuce mathématiquement gratuite : soustraire de une ligne de base qui ne dépend pas de l'action. Le gradient de l'objectif ne change pas en espérance, mais sa variance chute.
La ligne de base la plus courante est simplement la moyenne des retours de l'épisode — c'est ce que fait la normalisation dans le code ci-dessus. Une ligne de base plus fine est une fonction de valeur apprise en parallèle : c'est déjà le pas vers les méthodes acteur-critique du module suivant.
Sur politique — la conséquence qui coûte cher
Le théorème du gradient de politique utilise l'espérance sous . Chaque échantillon doit venir de la politique courante. Une transition collectée sous une politique un peu plus ancienne n'est plus valide, et le tampon de rejeu du DQN n'est pas applicable directement.
Cette contrainte « sur politique » (on-policy) rend REINFORCE peu efficace en données : chaque batch de trajectoires est jeté après une mise à jour. C'est le problème que A2C et surtout PPO adressent au module suivant, par des astuces qui permettent de réutiliser quelques pas les mêmes données sans invalider les gradients.
Actions continues : ce que DQN ne savait pas faire
Un argmax sur un espace d'actions continu n'a pas de sens direct : il faudrait résoudre un problème d'optimisation à chaque pas. Le gradient de politique, lui, échantillonne directement d'une gaussienne et calcule sa log-probabilité en forme fermée. Contrôle de robot, torque d'un moteur, angle d'une gouverne : tous les problèmes à commande continue tombent naturellement du côté des politiques, et c'est pourquoi PPO domine ce champ.
Une erreur fréquente : lire la perte de REINFORCE comme celle d'un supervisé et s'attendre à la voir baisser. Elle peut fluctuer largement sans que cela signale rien. La bonne métrique est la récompense moyenne par épisode, tracée sur plusieurs graines aléatoires. Sur REINFORCE nu, prévoyez trois à cinq graines pour distinguer un vrai progrès d'un accident.
En résumé
- Une politique paramétrée apprend directement — stochastique par construction, différentiable, applicable en actions continues.
- Le théorème du gradient de politique dit d'augmenter la log-probabilité de chaque action proportionnellement au retour observé.
- REINFORCE est la mise en œuvre la plus simple ; sa variance très élevée impose une ligne de base pour être utilisable.
- La méthode est sur politique : les données ne peuvent pas être stockées et réutilisées comme dans le DQN.
Module suivant : acteur-critique, A2C et PPO, les évolutions qui rendent le gradient de politique compétitif sur les problèmes réels.