World Models
Collection
4 items • Updated
A faithful reproduction of Ha & Schmidhuber's World Models
on CarRacing-v3. The agent factorises into three parts — Vision, Memory,
Controller — trained in that order:
64×64×3 frame into a 32-d latent zp(z′ | z, a, h)[z; h] → action, evolved with CMA-ESOnly the controller ever touches the reward; V and M are trained once, self-supervised, then frozen.
| Metric | This model | Paper (Ha & Schmidhuber) |
|---|---|---|
| Best-agent reward (avg / 100 rollouts) | 915.9 | 906 ± 21 |
left: what the car sees · middle: the frame round-tripped through V · right: the next frame as M predicts it, one step ahead.
| File | Module | Architecture |
|---|---|---|
vae.pt |
V | AutoEncoder — 4× stride-2 conv encoder [32→64→128→256], mirror deconv decoder, 32-d latent, β-VAE with free-bits floor (λ = 0.5/dim) |
rnn.pt |
M | RNN — LSTM (hidden 256) over [z; a] (35-d) + MDN head, 5 Gaussians × 32 dims |
controller.pt |
C | linear [z(32); h(256)] → a(3), 867 params, CMA-ES (popsize 64, avg 16, σ 0.3) |
model.py |
— | the module definitions |
config.yaml |
— | hyperparameters for instantiation |
import torch
from omegaconf import OmegaConf
from huggingface_hub import hf_hub_download
from model import AutoEncoder, RNN # model.py from this repo
repo = "flydexo/world-models-carracing-v3"
cfg = OmegaConf.load(hf_hub_download(repo, "config.yaml"))
vae = AutoEncoder(cfg)
vae.load_state_dict(torch.load(hf_hub_download(repo, "vae.pt"), map_location="cpu"))
rnn = RNN(cfg)
rnn.load_state_dict(torch.load(hf_hub_download(repo, "rnn.pt"), map_location="cpu"))
# Controller: a plain linear [z; h] -> action
ctrl = torch.nn.Linear(cfg.controller.state_dim + cfg.controller.hidden_dim,
cfg.controller.action_dim)
ctrl.load_state_dict(torch.load(hf_hub_download(repo, "controller.pt"), map_location="cpu"))
Rollout loop: encode obs → z, concat [z; h] → controller → action, step env, feed
[z; a] through the RNN to advance the hidden state h.
The gap between a naïve implementation (600) and the paper (906) came down to a few details:
z ~ N(μ, σ) sampled every batch (not the mean μ); softmax
temperature applied only at sampling, never inside the training loss; correct mixture sampling.[z; h] (latent plus the RNN hidden state).