Accueil / Factory / Algos ML / PPO — factory / algos ML / apprentissage par renforcement

PROXIMAL POLICY OPTIMIZATION.

Un algorithme de policy gradient qui s'interdit de trop changer sa stratégie à chaque mise à jour. Cette prudence le rend stable et facile à régler. Publié par OpenAI en 2017, c'est l'algorithme de renforcement par défaut de nombreuses équipes, et celui qui a servi à aligner InstructGPT puis ChatGPT par RLHF.

Décision séquentielleActions continuesRLHF / LLMÉnergieNiveau : avancé

FICHE D'IDENTITÉ

notes sur 5 · usage entreprise
PerformanceSolide sur la plupart des problèmes, rarement le mauvais choix
InterprétabilitéStratégie portée par un réseau de neurones
VitesseDes centaines de milliers de pas simulés
Facilité de réglageLes réglages par défaut marchent souvent, d'où son succès
Tolérance aux données brutesActions continues ou discrètes ; observations à normaliser
EN 30 SECONDES

Un conducteur qui découvre une nouvelle ligne corrige sa conduite après chaque trajet, mais jamais d'un coup : un changement brutal pourrait tout dérégler. Il progresse par petites retouches sûres.

1. On collecte des essais avec la stratégie actuelle

Un réseau de neurones propose une action pour chaque situation, ici une puissance de charge ou de décharge. On joue quelques milliers de pas et on note les gains.

2. On mesure si chaque action a fait mieux que prévu

Un second réseau, le critique, estime ce que vaut chaque situation. L'avantage d'une action est l'écart entre le gain obtenu et cette estimation.

3. On corrige, mais dans un couloir

La stratégie est poussée vers les actions avantageuses. L'objectif cesse de récompenser les changements de probabilité au-delà d'environ 20 % par rapport à l'ancienne stratégie. C'est le « clip » qui donne à PPO sa stabilité.

LE CAS MÉTIER

énergie · pilotage d'une batterie sur site
EN ENTRÉE

Une batterie de 1 MWh et un prix horaire

Chaque heure, l'algorithme voit le niveau de charge et l'heure, puis choisit une puissance entre décharge et charge maximales. Le prix de l'électricité est simulé : creux la nuit, pics le matin et en début de soirée, rendement de charge de 90 %.

EN SORTIE

Un programme de charge heure par heure

La stratégie apprend à charger quand l'électricité est bon marché et à puiser dans la batterie pendant les pics. L'action est continue : PPO la gère directement, là où un DQN imposerait de découper la puissance en quelques niveaux.

CE QU'ON MESURE

Les euros économisés face à une règle horaire

On compare le gain sur deux jours à une règle simple : charger de 0 h à 5 h, décharger de 17 h à 21 h. Si l'algorithme ne bat pas cette règle, la règle suffit.

QUAND LE SORTIR, QUAND L'ÉVITER

OUI

  • Actions continues (puissance, dose, vitesse) ou mélange d'actions
  • Premier essai de renforcement profond sur un simulateur : les réglages par défaut sont raisonnables
  • Environnements où l'on peut lancer des milliers de simulations, en parallèle si besoin
  • Ajustement de modèles de langage sur des préférences humaines (RLHF)

NON

  • Simulations coûteuses (plusieurs minutes par essai) : PPO consomme beaucoup d'essais, préférer un algorithme qui réutilise ses expériences comme DQN ou SAC
  • Problème déjà résolu par une règle métier ou une optimisation classique : commencer par comparer à cette règle
  • Petit problème à actions discrètes : un Q-learning tabulaire est plus simple et plus lisible
  • Aligner un LLM sans équipe spécialisée : des méthodes plus simples comme DPO existent
LES 4 RÉGLAGES QUI COMPTENT

Noms donnés pour stable-baselines3. Les valeurs par défaut sont un bon point de départ.

clip_range

Largeur du couloir de prudence, 0,2 par défaut. Plus petite, l'apprentissage est plus sûr mais plus lent.

n_steps

Nombre de pas collectés avant chaque mise à jour (2 048 par défaut). Plus il est grand, plus l'estimation est fiable, mais plus les mises à jour sont espacées.

learning_rate

Pas de la descente de gradient, 0,0003 par défaut. Le premier réglage à baisser si la récompense moyenne oscille.

ent_coef

Bonus donné aux stratégies qui restent variées, nul par défaut. À augmenter légèrement si l'algorithme se fige trop tôt sur une seule action.

LE CODE MINIMAL

données simulées dans le code
# Pilotage d'une batterie sur site : PPO en Python
import numpy as np
import gymnasium as gym
from stable_baselines3 import PPO

class Batterie(gym.Env):   # chaque heure : niveau de charge et heure -> charger ou décharger
    observation_space = gym.spaces.Box(-1.0, 1.0, shape=(3,), dtype=np.float32)
    action_space = gym.spaces.Box(-1.0, 1.0, shape=(1,), dtype=np.float32)   # -1 décharge, +1 charge

    def reset(self, seed=None, options=None):
        super().reset(seed=seed)
        self.heure, self.charge = 0, 0.5
        return np.array([0.5, 0.0, 1.0], dtype=np.float32), {}

    def step(self, action):
        h = self.heure % 24   # prix spot simulé (€/MWh) : creux la nuit, pics à 8 h et 19 h
        prix = 50 + 40 * np.exp(-((h - 8) ** 2) / 4) + 70 * np.exp(-((h - 19) ** 2) / 4) + self.np_random.normal(0, 5)
        energie = float(np.clip(action[0] * 0.25, -self.charge, (1 - self.charge) / 0.9))   # 1 MWh, 0,25 MWh par heure au plus
        self.charge += 0.9 * energie if energie > 0 else energie                             # rendement 90 %
        self.heure += 1
        obs = np.array([self.charge, np.sin(self.heure * np.pi / 12), np.cos(self.heure * np.pi / 12)], dtype=np.float32)
        return obs, -prix * energie / 100, False, self.heure >= 48, {}   # gain : achat évité ou revente

modele = PPO("MlpPolicy", Batterie(), learning_rate=3e-4, n_steps=2048, clip_range=0.2, seed=42, verbose=0)
modele.learn(total_timesteps=200_000)

def evaluer(choix, env=Batterie(), total=0.0):   # gain moyen (€) sur 20 fois 2 jours
    for i in range(20):
        obs, fini = env.reset(seed=i)[0], False
        while not fini:
            obs, gain, _, fini, _ = env.step(choix(obs, env.heure % 24))
            total += gain * 100
    return round(total / 20, 1)

regle = lambda obs, h: [1.0 if h < 5 else -1.0 if 17 <= h < 21 else 0.0]   # charger la nuit, décharger le soir
print("PPO :", evaluer(lambda obs, h: modele.predict(obs, deterministic=True)[0]), "| règle horaire fixe :", evaluer(regle))

PPO se pratique en Python (stable-baselines3, PyTorch, Gymnasium ; TRL pour les LLM) : pas d'équivalent R utilisé en entreprise.

QUESTIONS FRÉQUENTES

Pourquoi PPO a-t-il été utilisé pour entraîner ChatGPT ?

Le RLHF ajuste un très gros modèle de langage sans devoir le déstabiliser. Le clip de PPO, complété par une pénalité qui empêche de trop s'éloigner du modèle de départ, limite chaque mise à jour. OpenAI l'a utilisé pour InstructGPT puis ChatGPT ; d'autres méthodes comme DPO ou GRPO sont aussi répandues aujourd'hui.

Quelle différence entre PPO et TRPO ?

TRPO, son prédécesseur, impose une contrainte mathématique stricte sur l'écart entre ancienne et nouvelle stratégie, coûteuse à calculer. PPO obtient un effet proche avec un simple écrêtage (clip) de l'objectif, bien plus facile à programmer et à faire tourner.

PPO fonctionne-t-il avec des actions continues ?

Oui. La stratégie produit alors une loi normale : le réseau en donne la moyenne, l'écart-type est lui aussi appris, et l'action est tirée dans cette loi. C'est un net avantage sur le DQN, limité à une liste d'actions.

LES ALGOS VOISINS

à comparer avant de choisir
la famille

Policy Gradient

PPO est un policy gradient doté d'un garde-fou sur la taille des mises à jour. REINFORCE en est la version brute.

Voir la fiche →
l'usage le plus connu

RLHF

Aligner un LLM sur les préférences humaines : PPO optimise le modèle de langage face à un modèle de récompense.

Voir la fiche →
l'alternative par la valeur

Deep Q-Network (DQN)

Plus économe en essais car il rejoue ses expériences, mais limité aux actions discrètes.

Voir la fiche →
— formation

Passer de la fiche à la pratique

Dataistudio forme les équipes au machine learning et à l'IA, sur des cas concrets.

Voir les formations →