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.
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.
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.
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.
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é.
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 %.
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.
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.
Noms donnés pour stable-baselines3. Les valeurs par défaut sont un bon point de départ.
Largeur du couloir de prudence, 0,2 par défaut. Plus petite, l'apprentissage est plus sûr mais plus lent.
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.
Pas de la descente de gradient, 0,0003 par défaut. Le premier réglage à baisser si la récompense moyenne oscille.
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.
# 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.
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.
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.
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.
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 connuAligner 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 valeurPlus économe en essais car il rejoue ses expériences, mais limité aux actions discrètes.
Voir la fiche →Dataistudio forme les équipes au machine learning et à l'IA, sur des cas concrets.
Nous utilisons des cookies de mesure d'audience et de suivi publicitaire pour comprendre la fréquentation du site et l'efficacité de nos annonces. Rien n'est déposé sans votre accord. En savoir plus