Source code for simulusion.training.train_controller

"""Training a linear controller on latent + recurrent state with CMA-ES.

This module provides functions to train a linear controller using Covariance
Matrix Adaptation Evolution Strategy (CMA-ES). The controller maps latent
and hidden states to actions for the learned world model.

Reference:
    Ha & Schmidhuber (2018). Recurrent World Models Facilitate Policy Evolution.
    https://arxiv.org/abs/1805.11111
"""

from typing import Any
from os.path import join
import torch
import gymnasium as gym

from simulusion.configs.wm_config import WMControllerConfig
from simulusion.envs.gym_env import GymImageEnv


[docs] def make_controller_env(env_name: str) -> Any: """``env_name`` as the controller sees it: 64x64 image observations. Environments that take ``continuous`` (CarRacing) get the continuous action space the World Models controller outputs. Environments are made with ``render_mode="rgb_array"``, so those whose observations are vectors (Pendulum, BipedalWalker) are seen through their rendered frames. """ try: env: Any = gym.make(env_name, continuous=True, render_mode="rgb_array") except TypeError: env = gym.make(env_name, render_mode="rgb_array") return GymImageEnv(env=env, size=(64, 64))
[docs] def train_controller(config: WMControllerConfig) -> None: """Train a linear controller using CMA-ES. Runs on the shared :class:`~simulusion.training.Trainer` through the ``controller`` task, with the VAE and MDN-RNN in ``<logdir>/vae/best.tar`` and ``<logdir>/mdrnn/best.tar``. One step is one CMA-ES generation of ``pop_size`` candidates, each scored over ``n_samples`` episodes of up to ``time_limit`` steps in ``env_name``. The best controller so far is kept in ``<logdir>/ctrl/best.tar`` (and started from when it exists); training stops when CMA-ES converges or the best return passes ``target_return``. Candidates are scored one after another in this process, so ``max_workers`` and ``display`` no longer apply. The controller's sizes come from the trained models, whatever ``latent_size`` / ``hidden_size`` / ``action_size`` say. Args: config: WMControllerConfig containing training hyperparameters, including env_name and action_size. """ from simulusion.training.legacy import fit_legacy from simulusion.training.tasks.world_models import ( ControllerTask, ControllerTaskConfig, ) from simulusion.world_model.vae_mdrnn import MDRNNWorldModel device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model = MDRNNWorldModel.from_checkpoints( join(config.logdir, "vae", "best.tar"), join(config.logdir, "mdrnn", "best.tar"), device=device, ) ctrl_dir = join(config.logdir, "ctrl") fit_legacy( ControllerTask( ControllerTaskConfig(model=config), env_factory=lambda: make_controller_env(config.env_name), model=model, legacy_dir=ctrl_dir, ), ctrl_dir, # CMA-ES has no fixed number of generations; it runs until it # converges or reaches target_return (ControllerTask.should_stop). max_steps=10**9, device=device, eval_every=3, )