Dreamer: World Models for RL
Learn a small simulator of the world from past play, then train the player inside that simulator where mistakes cost nothing and steps run in bulk.
Why Does This Exist?
Model free methods learn by doing. That works until doing costs too much. Robots break, simulators crawl, and pixel environments eat millions of steps before the policy looks sane. Planning in pixels has the mirror problem: predicting full images many steps out is slow and blurry.
Dreamer (Hafner and colleagues, 2019 to 2023) splits the job. First learn a compact world model from logged experience. Then train an actor critic purely inside that model's latent space, where a step is a matrix multiply and you can dream tens of thousands of transitions per second. Start with learning latent dynamics for the model half and model-based deep RL for the family, then compare planning styles in MuZero and AlphaZero.
Three loops run together: act in the world and log , fit the world model on replay, and improve the policy on imagination. This page follows that order.
Think of It Like This
A pilot and a flight simulator built from flight logs
Training a pilot only in a real jet means every lesson risks the jet. Showing them cockpit videos is safe but passive: the video cannot answer what happens if they pull up now.
Dreamer builds the middle option. Engineers compress years of flight telemetry into a simulator, then the student flies thousands of simulated hours, stalls included, with an instructor grading each landing. Real flights still happen, and their logs keep improving the simulator.
The analogy stops at authorship. A flight simulator is hand coded from physics. Dreamer writes its own simulator from raw sensations, so a flawed model teaches confident nonsense. Horizon limits and value bootstrapping exist to contain exactly that.
How It Actually Works
The world model is a recurrent state space model. Latent state pairs a deterministic memory with a stochastic part . An encoder maps pixels to , dynamics predict from and action , and small heads predict reward , discount , and reconstruction. Training balances reconstruction plus reward and discount losses against a KL term that keeps the prior close to the posterior without collapsing it.
DreamerV2 made discrete: 32 categorical variables of 32 classes each, sampled with a straight through estimator so gradients still flow. DreamerV3 added scale handling with the symlog map and its inverse, plus two hot value targets over binned returns. Discrete latents hold multimodal futures better, and symlog keeps one setting working across games with tiny and huge rewards.
Policy learning never renders pixels. From a real encoded state , the actor rolls latent steps through the frozen dynamics, collecting predicted rewards. The critic scores states, and step bootstraps blend into lambda returns:
Here discounts the future and weights short bootstraps against long rollouts. The actor climbs by analytic gradients through the differentiable model, and the critic regresses toward it.
Worked example
Take a short imagined slice with and . Rewards are and , critic values are and .
One step bootstrap:
Two step bootstrap:
Lambda blend:
DreamerV3 compresses that target before the critic fits it:
Inverting restores , so large and small returns share one loss scale.
Code
This snippet repeats the worked slice: two bootstraps, the lambda blend, and the symlog round trip.
import math
def symlog(x: float) -> float: sign = 1.0 if x > 0 else (-1.0 if x < 0 else 0.0) return sign * math.log(abs(x) + 1.0)
def symexp(y: float) -> float: sign = 1.0 if y > 0 else (-1.0 if y < 0 else 0.0) return sign * (math.exp(abs(y)) - 1.0)
def main() -> None: gamma, lam = 0.9, 0.8 r1, r2, v2, v3 = 1.0, 2.0, 2.5, 1.0
g1 = r1 + gamma * v2 g2 = r1 + gamma * r2 + gamma**2 * v3 vlam = (1.0 - lam) * g1 + lam * g2 s = symlog(vlam)
print(f"G1: {g1:.2f}") # -> G1: 3.25 print(f"G2: {g2:.2f}") # -> G2: 3.61 print(f"Vlambda: {vlam:.3f}") # -> Vlambda: 3.538 print(f"symlog: {s:.4f}") # -> symlog: 1.5125 print(f"restored: {symexp(s):.3f}") # -> restored: 3.538
if __name__ == "__main__": main()Watch Out For
Stretching the imagination horizon
Longer dreams feel like deeper planning, so teams raise from 15 to 50 or 100. Small model errors compound with each imagined step, and the actor soon finds states where the model predicts free reward. Imagination scores soar while real play collapses.
Keep near 15 and let the critic carry the far future through with near 0.95. If imagined returns climb but real returns do not, shorten the horizon before touching the actor.
The Quick Version
- Dreamer learns a latent world model from replay, then trains actor and critic on imagined rollouts inside it.
- Latent state pairs recurrent memory with stochastic variables, discrete in V2 and V3 for sharper futures.
- Policy rollouts run steps and are scored with lambda returns that blend short bootstraps and long dreams.
- V3 uses symlog and two hot targets so one setting spans games with very different reward scales.
- In the worked slice, and blend to , which symlog maps to .
- Long horizons invite hallucination. Anchor them with the critic and keep the horizon modest.