Dans ce TD, nous allons utiliser la bibliothèque Stable Baselines 3 pour entraîner un agent sur un environnement Gymnasium existant, puis nous verrons comment créer notre propre environnement Gymnasium.
Installez les dépendances nécessaires:
pip install rl_zoo3 pygame
La bibliothèque Stable Baselines 3 est une implémentation populaire d'algorithmes d'apprentissage par renforcement en Python. Elle offre une interface simple pour entraîner et évaluer des agents sur divers environnements Gymnasium.
Le zoo de Stable Baselines 3 (rl-zoo3) fournit des scripts préconfigurés pour entraîner des agents sur différents environnements en utilisant divers algorithmes.
Pour lancer un entraînement, nous avons besoin de:
Le Zoo de Stable Baselines fournit déjà des hyper-paramètres efficaces pour de nombreux algorithmes et environnements courants.
Pour entraîner un agent SAC sur l'environnement Pendulum-v1, utilisez la commande suivant :
python -m rl_zoo3.train --algo sac --env Pendulum-v1
Vous observerez une sortie de la forme :
---------------------------------
| rollout/ | |
| ep_len_mean | 200 |
| ep_rew_mean | -692 |
| time/ | |
| episodes | 32 |
| fps | 134 |
| time_elapsed | 47 |
| total_timesteps | 6400 |
| train/ | |
| actor_loss | 78.2 |
| critic_loss | 0.856 |
| ent_coef | 0.106 |
| ent_coef_loss | -0.237 |
| learning_rate | 0.001 |
| n_updates | 6299 |
---------------------------------
Des fichiers seront produits dans logs/sac/Pendulum-v1_1/ contenant le modèle entraîné et les journaux d'entraînement.
Afin de tester l'agent entraîné, utilisez la commande suivante :
python -m rl_zoo3.enjoy --algo sac --env Pendulum-v1 -f logs/
Pendulum-v1Nous allons écrire notre propre environnement Gymnasium. Vous pouvez par exemple regarder le code Pendulum-v1.
Un environnement est une classe qui hérite de gymnasium.Env et implémente les méthodes suivantes :
__init__(self): Initialise l'environnement, définit les espaces d'observation et d'action.reset(self): Réinitialise l'environnement à un état initial et retourne la première observation.step(self, action): Applique une action à l'environnement, retourne la nouvelle observation, la récompense, un indicateur de fin d'épisode et des informations supplémentaires.render(self): Affiche l'état actuel de l'environnement.Téléchargez l'archive td4.zip. Il contient le code d'un jeu de mini-golf, que vous pouvez tester en exécutant cette commande depuis le dossier parent à mini_golf :
python -m mini_golf.play
Observez le code de play.py et simulator.py pour comprendre comment l'environnement est implémenté.
Créez un fichier mini_golf_env.py dans le dossier mini_golf/, vous pourrez partir du code suivant:
import time
import gymnasium
import numpy as np
from .simulator import Simulator
class MiniGolfEnv(gymnasium.Env):
metadata = {"render_modes": ["human"], "render_fps": 30}
def __init__(self, render_mode=None):
self.render_mode = render_mode
self.simulator = Simulator()
if self.render_mode == "human":
self.simulator.visualize = True
# TODO: Définir l'espace d'action et d'observation
self.action_space = ...
self.observation_space = ...
def _get_obs(self):
# TODO: Construire l'observation
...
def reset(self, seed=None, options=None):
# TODO: Réinitialiser l'environnement
return self._get_obs(), {}
def step(self, action):
# TODO: Mettre à jour l'environnement
# calculer la récompense et vérifier la fin de l'épisode
return self._get_obs(), reward, done, False, {}
def render(self):
time.sleep(0.5)
Déclarez l'espace d'action et d'observation dans la méthode __init__.
L'action donnée sera la vitesse de la balle au moment du tir \((v_x, v_y)\). L'observation sera la position actuelle de la balle \((x, y)\) et la position du trou \((x_{target}, y_{target})\).
Implémentez la méthode _get_obs qui retourne l'observation actuelle sous la forme d'un tableau numpy.
Vous normaliserez les valeurs de l'observation et de l'action entre \(0\) et \(1\).
Implémentez la méthode reset de manière à réinitialiser la position de la balle et du trou aléatoirement
dans l'écran.
Pensez à éviter de placer la balle ou la cible en collision avec l'obstacle, vous pouvez vous aider de la méthode simulator.in_obstacle()
Implémentez la méthode step qui:
action passée en paramètre pour tirer la balle dans le simulateur.done=True quand la balle est dans le trouObservez le fichier mini_golf/__init__.py, il permet d'enregistrer l'environnement Gymnasium MiniGolf afin de pouvoir l'utiliser avec Stable Baselines 3.
Pour lancer un entraînement, vous aurez besoin de placer les hyper-paramètres suivant dans un fichier YAML, par exemple hyperparams/sac.yml :
# hyperparams/sac.yml
MiniGolf:
n_timesteps: 100000
policy: 'MlpPolicy'
learning_rate: !!float 1e-3
Lancez l'entraînement avec la commande suivante :
python -m rl_zoo3.train --algo sac --env MiniGolf \
--gym-packages mini_golf --conf hyperparams/sac.yml
Testez l'agent entraîné avec la commande suivante :
python -m rl_zoo3.enjoy --algo sac --env MiniGolf \
--gym-packages mini_golf -f logs/
Vous pouvez activer le monitoring avec Weights & Biases en ajoutant l'option --track --wandb-project <nom_du_projet> lors de l'entraînement, par exemple :
python -m rl_zoo3.train --algo sac --env MiniGolf \
--gym-packages mini_golf --conf hyperparams/sac.yml \
--track --wandb-project mini_golf_td4
N'hésitez pas à tester d'autre algorithmes, et à ajuster les hyper-paramètres pour essayer de réduire le temps d'entraînement de d'améloirer les performances de l'agent !