TD4: Stable baselines, écriture d'environnements Gymnasium

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.

Installation

Installez les dépendances nécessaires:

pip install rl_zoo3 pygame

Entraînement avec Stable Baselines 3

Présentation

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.

Entraînement

Pour lancer un entraînement, nous avons besoin de:

  1. Préciser l'environnement que l'on souhaite entraîner, par exemple Pendulum-v1.
  2. Choisir un algorithme, comme Soft Actor-Critic (SAC) ou Twin Delayed DDPG (TD3).
  3. Configurer les hyperparamètres si nécessaire (optionnel).

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.

Test de l'agent entraîné

Afin de tester l'agent entraîné, utilisez la commande suivante :

python -m rl_zoo3.enjoy --algo sac --env Pendulum-v1 -f logs/

Code de l'environnement

Lecture de l'environnement Pendulum-v1

Nous 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.

Prise en main du mini-golf

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é.

Écriture d'un environnement Gymnasium

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:

  • Utilise l'action passée en paramètre pour tirer la balle dans le simulateur.
  • Produit une récompense de \(-1 - 10^{-2} \times dist\) à chaque coup, où \(dist\) est la distance entre la balle et le trou après le coup.
  • Produit une terminaison done=True quand la balle est dans le trou

Entraînement de l'agent sur le mini-golf

Observez 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

Test de l'agent entraîné

Testez l'agent entraîné avec la commande suivante :

python -m rl_zoo3.enjoy --algo sac --env MiniGolf \
       --gym-packages mini_golf -f logs/

Monitoring WandB

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

Tuning et améliorations

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 !