Policies Learned in Imagination

Michael BrenndoerferJuly 10, 202664 min read

Part of World Models Handbook

Explains how actor-critic policies train inside learned world models, covering latent rollouts, lambda-returns, value expansion, and model exploitation.

Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.

Article links

Make inline references clickable

Policies Learned in Imagination

The planning methods in Part VII: Planning and Agency so far have used the world model at decision time. Sampling-based planning evaluates candidate action sequences, differentiable planning optimizes them through model gradients, and search expands imagined futures before committing to an action. Their model calls sit on the decision-time critical path.

That arrangement is demanding. A planner sits on the critical path of every decision, so it must fit within the control loop's latency budget. At 50 Hz, the entire sensing-to-action cycle lasts twenty milliseconds; state estimation, communication, inference, and actuation leave only part of that period for planning. The model also has to be accurate in a very specific way: not merely good on average, but trustworthy along the candidate trajectories the planner considers. Constraints may rule out large regions of state space, but a badly calibrated reachable candidate can still make a poor plan look attractive. In the language of classical control, this is the model predictive control regime, where an explicit model is queried online, repeatedly, and where closed-loop quality depends on the model along the plans actually considered and executed.

This chapter takes a different route: learn a policy inside the model, then act with that policy rather than running a planner for each decision. The agent rolls the model forward from states grounded in experience and uses synthetic trajectories to train a policy network. At action-selection time a deployed policy can map its current state estimate to an action without a planning rollout. Online variants may still collect data and update the model and policy between decisions.

The shift is a shift in when the model is used, and that single change ripples through everything else. At training time we can afford to run the model millions of times, to backpropagate through it, to compare it against real data, and to revise it. At deployment time we run a small network once per step. The model has become a teacher rather than an oracle, and the expensive, fragile, high-variance computation has been moved off the critical path entirely.

This is the amortization bargain: spend model compute during training to obtain a reactive controller with fixed per-step network inference cost. Dreamer illustrates this route; MuZero and TD-MPC instead retain learned-model planning at decision time. We will compare those distinct designs in Part VIII: Decision-Centric Research Lineages. First we need the mechanics of policy learning in imagination.

There is a classical analogy. In linear-quadratic control, a known or identified linear system and a specified quadratic objective yield an offline Riccati solution and a cheap feedback law. Here a learned transition and reward predictor supply imagined trajectories, while gradient descent fits a nonlinear policy. The task reward need not itself be learned as a preference; its predictor is learned because the actor trains without querying the environment on each imagined step. The analogy concerns moving computation out of the action-selection loop, not identical assumptions or guarantees.

Imagination

A rollout in imagination is a trajectory generated entirely by the learned model and the current policy, never touching the real environment. Formally, it is a sample path of the Markov chain induced by the policy πω\pi_\omega and the model pθp_\theta, starting from a state or latent sampled from real experience.

This definition fixes the trajectory distribution over which the policy gradient is averaged: the one produced by the policy and learned model. A rollout may resemble real experience on the training distribution, but its transition law is still the model's. That difference underlies the failure modes we will study.

When real interaction is costly, model rollouts can provide additional training signal without another environment step, although those rollouts still consume compute and memory. The hazard is that the policy trains against a guess about the world. It can exploit optimistic errors that are reachable under its policy class and discoverable by its optimizer. A policy that scores well in imagination and fails in reality can therefore be optimizing its stated training objective faithfully.

The objective J^(ω)\hat J(\omega) below is defined under the learned model. If a reachable model error makes a poor action look attractive, optimization may favor it over an action that works in the environment. The optimizer can be doing its job while optimizing the wrong objective.

We will build latent rollouts and the actor-critic losses that consume them, then examine value expansion, synthetic replay data, and ways to limit model exploitation.

Latent Imagined Rollouts

The first design question is what the rollout operates on. A generative pixel-level model can roll forward in observation space if it predicts action-conditioned future images and rewards. But decoding images can be expensive, while the critic may need only a compact, task-relevant summary. Reconstruction can still be useful supervision for learning that summary even when decoding is unnecessary during behavior learning.

This is where notions of model quality separate. Predictive fidelity asks whether the next-step prediction matches reality. Rollout fidelity asks whether predictions remain useful when fed back over many steps. Representation quality asks whether the latent retains information needed for control. Uncertainty quality asks whether the model signals its limitations. Decision usefulness asks whether a policy trained against it works in the real environment. These properties can diverge. Latent imagination avoids repeated decoding during behavior learning; it does not make the other properties optional.

Latent imagination sidesteps this. Building on the recurrent and transformer state-space architectures from Part V: World-Model Architectures, the world model provides an encoder, a latent transition, and a reward head. The rollout happens entirely inside the latent space:

z^t=qϕ(o≤t,a<t),z^t+1∼pθ(zt+1∣z^t,at),r^t=rψ(z^t,at).\hat z_t = q_\phi(o_{\le t}, a_{<t}), \qquad \hat z_{t+1} \sim p_\theta(z_{t+1} \mid \hat z_t, a_t), \qquad \hat r_t = r_\psi(\hat z_t, a_t).

where:

  • o≤to_{\le t}: the observation history up to and including time tt, which the encoder consumes to produce a latent
  • a<ta_{<t}: the action history before time tt, included so the encoder can account for how the current observation was reached
  • qϕq_\phi: the encoder, parameterized by ϕ\phi, that maps observations and past actions into the latent state z^t\hat z_t
  • pθp_\theta: the latent transition model, parameterized by θ\theta, which defines a distribution over the next latent state given the current latent and action
  • rψr_\psi: the reward head, parameterized by ψ\psi, that predicts the scalar reward from a latent state and action
  • z^t\hat z_t: the inferred latent state at time tt, intended to summarize the task-relevant past; whether it succeeds is empirical
  • r^t\hat r_t: the predicted reward at time tt, used as the synthetic training signal for the actor and critic

The equations resemble a classical control pipeline. The encoder qϕq_\phi is a learned state estimator, though it need not produce a calibrated sufficient belief. The transition model pθp_\theta predicts how that state evolves under control. The reward head rψr_\psi predicts a task reward supplied by the environment; it is not itself a learned preference specification. The actor and critic play the roles of controller and value estimate. Under partial observability, history or a belief estimate is generally useful, although a reactive observation policy can suffice in special tasks.

No observation needs to be decoded during these imagined actor and critic updates. The actor and critic read z^t\hat z_t, while the reward head scores (z^t,at)(\hat z_t,a_t). A decoder may still be important when learning the representation.

There are three practical reasons this matters. First, skipping a high-dimensional decoder can reduce rollout compute, depending on architecture and observation resolution. Second, gradients need not pass through a pixel decoder to reach the policy. Third, reconstruction can pressure a model to preserve visual detail irrelevant to action selection; reward and transition objectives can additionally shape the latent toward control.

The representation question is which information the controller needs. A latent can reconstruct fine visual detail yet omit a small cue that changes the right action; another can reconstruct imperfectly but retain that cue. Neither ordering is guaranteed by the loss alone. Reward and value heads can help shape what the actor extracts from the latent, while the model's training objective still determines what information reaches those heads.

The rollout is then a single vectorized loop. Starting from a batch of BB latent states, at each of HH steps:

  • Sample an action at∼πω(⋅∣z^t)a_t \sim \pi_\omega(\cdot \mid \hat z_t), where πω\pi_\omega is the policy parameterized by ω\omega.
  • Step the transition model to get z^t+1\hat z_{t+1}.
  • Score the reward r^t\hat r_t and query the critic for v^t=vξ(z^t)\hat v_t = v_\xi(\hat z_t), where vξv_\xi is the value function parameterized by ξ\xi.

Because the BB rollouts are independent, each step can be batched on a GPU. There are still HH sequential transition steps and arithmetic scaling with BHBH; batching reduces wall-clock overhead, not the amount of work. This is the concrete form of the amortization bargain: training is expensive in aggregate but parallelizable across starts.

After the loop, query the critic once more at the final latent to get a bootstrap value v^H\hat v_H. With γ=0.99\gamma=0.99 and H=20H=20, that terminal value receives weight γ20≈0.818\gamma^{20}\approx0.818. For an infinite stream of constant rewards, about 82% of the normalized discounted mass lies after the first 20 rewards. In a continuing task, omitting the bootstrap can therefore undervalue delayed payoffs.

The scale 1/(1−γ)=1001/(1-\gamma)=100 describes the geometric discount tail, not a literal cutoff. The first 20 rewards contain 1−0.9920≈18.2%1-0.99^{20}\approx18.2\% of the normalized mass for a constant stream. A terminal value estimate, as in finite-horizon dynamic programming or receding-horizon control, represents the continuing value beyond the sampled prefix. Its usefulness depends on its accuracy.

Whether the loop is differentiable matters. If the latent transition is a continuous distribution, we can sample with the reparameterization trick, z^t+1=μθ(z^t,at)+σθ(z^t,at)⊙ϵ\hat z_{t+1} = \mu_\theta(\hat z_t, a_t) + \sigma_\theta(\hat z_t, a_t) \odot \epsilon with ϵ∼N(0,I)\epsilon \sim \mathcal{N}(0, I), where μθ\mu_\theta and σθ\sigma_\theta are the mean and standard deviation predicted by the latent transition model and ⊙\odot denotes elementwise multiplication, and gradients flow straight through the model. If the latent is discrete, as in many categorical state-space models, the sample is not differentiable. The usual fixes are a straight-through estimator, which passes the gradient of a relaxed sample through a hard sample, or a gradient-free actor update that treats the dynamics as a black box. Each choice changes what the actor gradient estimator can do, which we take up next.

Differentiability determines whether an exact pathwise derivative through sampled transitions is available. Continuous reparameterized models support it directly. Discrete or discontinuous models may use a relaxation, straight-through approximation, smoothing, or score-function estimator; none is automatically robust to model error. The choice affects both gradient bias or variance and the model derivatives the actor can exploit.

Stop-Gradient on the Model

For the separate model-fitting and actor-learning setup here, exclude world-model parameters from the actor optimizer. Otherwise the actor objective also pushes the model toward favorable imagined outcomes. Joint objectives are possible, but they require explicit predictive constraints and separate validation of model accuracy.

If actor gradients could update an unconstrained reward or transition head, the optimizer could improve the reported outcome without improving behavior. That shortcut is a risk, not an inevitable unbounded trajectory: predictive losses, regularization, and head ranges can counter it. In this chapter's code the model is fitted first and frozen during actor learning, so the two objectives remain separate.

Actor-Critic Learning Inside a Model

Once we can generate rollouts, we need a learning signal. The natural choice is actor-critic, because it gives us both a critic that can reason about the tail of the horizon and an actor that can be optimized directly.

Actor-critic is itself a classical idea, and it is helpful to place it in that lineage. In approximate dynamic programming, the value function is the object of interest: policy iteration alternates between evaluating a policy and improving it greedily with respect to the value function. Actor-critic methods combine those two steps into a single loop with two function approximators, one for the value and one for the policy. Inside a learned model, the loop is unchanged in structure, but every state, reward, and transition it uses is synthetic. This is the sense in which imagination-based learning is classical control with a learned simulator swapped in: the algorithm is familiar, the data is not.

Recall from Chapter 6 of Part II that a critic vξv_\xi estimates the expected discounted return from a state. Inside imagination, the critic is trained by regression onto multi-step return targets computed from the imaginary rewards. The standard target is the λ\lambda-return, a geometric blend of nn-step returns that trades bias against variance. Define the temporal-difference residual along the rollout as

δt=r^t+γ vξ(z^t+1)−vξ(z^t),\delta_t = \hat r_t + \gamma\, v_\xi(\hat z_{t+1}) - v_\xi(\hat z_t),

where:

  • δt\delta_t: the temporal-difference residual at step tt, measuring the surprise of the imagined reward relative to the critic's prediction
  • r^t\hat r_t: the imagined reward at step tt
  • γ\gamma: the discount factor
  • vξ(z^t+1)v_\xi(\hat z_{t+1}): the critic's value estimate at the next latent
  • vξ(z^t)v_\xi(\hat z_t): the critic's value estimate at the current latent

with the boundary condition that z^H\hat z_H is the last latent and vξ(z^H)v_\xi(\hat z_H) is the bootstrap value. The λ\lambda-return is then

G^tλ=vξ(z^t)+∑k=tH−1(γλ)k−t δk,\hat G_t^{\lambda} = v_\xi(\hat z_t) + \sum_{k=t}^{H-1} (\gamma\lambda)^{k-t}\,\delta_k,

where:

  • G^tλ\hat G_t^{\lambda}: the λ\lambda-return target at step tt, blending nn-step returns to balance bias and variance
  • vξ(z^t)v_\xi(\hat z_t): the critic's baseline value estimate at the current latent
  • λ\lambda: the blending parameter between one-step and Monte Carlo returns
  • δk\delta_k: the temporal-difference residual at future step kk
  • HH: the imagination horizon

which can be computed with a single backward pass over the rollout using the recursion G^tλ=δt+γλ G^t+1λ+vξ(z^t)−γλ vξ(z^t+1)\hat G_t^{\lambda} = \delta_t + \gamma\lambda\,\hat G_{t+1}^{\lambda} + v_\xi(\hat z_t) - \gamma\lambda\, v_\xi(\hat z_{t+1}) or, more simply, by accumulating an auxiliary variable At=δt+γλAt+1A_t = \delta_t + \gamma\lambda A_{t+1} and returning vξ(z^t)+Atv_\xi(\hat z_t) + A_t. The critic loss is the mean squared error between vξ(z^t)v_\xi(\hat z_t) and the detached target:

Lcritic(ξ)=E[1H∑t=0H−1(G^tλ−vξ(z^t))2].\mathcal{L}_{\text{critic}}(\xi) = \mathbb{E}\left[\frac{1}{H}\sum_{t=0}^{H-1}\left(\hat G_t^{\lambda} - v_\xi(\hat z_t)\right)^2\right].

where:

  • Lcritic(ξ)\mathcal{L}_{\text{critic}}(\xi): the critic loss as a function of the value-network parameters ξ\xi
  • E[⋅]\mathbb{E}[\cdot]: the expectation over imagined rollouts
  • HH: the number of rollout steps
  • G^tλ\hat G_t^{\lambda}: the detached λ\lambda-return target at step tt
  • vξ(z^t)v_\xi(\hat z_t): the critic's predicted value at the latent state z^t\hat z_t

In this separate critic regression, the target is detached during each update. Other algorithms deliberately differentiate through targets, so detachment is a design choice rather than a universal rule.

Why use a λ\lambda-return rather than only a one-step or full-rollout target? A one-step target relies heavily on the critic's bootstrap and can inherit its bias. A full sampled return avoids intermediate value bootstraps but may have higher sampling variance; in a deterministic model, that variance need not be large. If the rollout ends before the task does, its terminal bootstrap still carries value error. The λ\lambda-return interpolates among these targets. Its useful bias-variance balance depends on critic accuracy, model accuracy, and stochasticity rather than on a universal ordering.

For the actor there are two fundamentally different gradient estimators, and the distinction is one of the most important ideas in this chapter.

The score-function estimator. Also called REINFORCE or the likelihood-ratio estimator, this treats the sampled action as a fixed constant and reweights its log-probability by how good the outcome turned out to be:

∇ωJ^H(ω)=E[∑t=0H−1γt(RtH−b(z^t))∇ωlog⁡πω(at∣z^t)],RtH=∑k=tH−1γk−tr^k.\nabla_\omega \hat J_H(\omega) = \mathbb{E}\left[\sum_{t=0}^{H-1}\gamma^t\left(R_t^H-b(\hat z_t)\right)\nabla_\omega \log \pi_\omega(a_t\mid\hat z_t)\right], \qquad R_t^H=\sum_{k=t}^{H-1}\gamma^{k-t}\hat r_k.

where:

  • ∇ωJ^H\nabla_\omega\hat J_H: the gradient of the finite, HH-step discounted imagined-reward objective
  • RtHR_t^H: sampled discounted reward-to-go from step tt through the truncated rollout
  • b(z^t)b(\hat z_t): a state-dependent baseline, often the critic, whose expectation against the action score is zero
  • γt\gamma^t: the time weight required by the stated discounted objective
  • log⁡πω(at∣z^t)\log \pi_\omega(a_t \mid \hat z_t): the log-probability of the sampled action under the current policy

The likelihood-ratio identity is unbiased for this finite imagined objective when RtHR_t^H is sampled from the stated rollout distribution and the baseline depends on state, not the sampled action. A practical update may replace RtHR_t^H with a bootstrapped λ\lambda-return and use sg⁡(G^tλ−vξ(z^t))\operatorname{sg}(\hat G_t^\lambda-v_\xi(\hat z_t)) as an advantage; with an approximate critic and λ<1\lambda<1, that surrogate is generally biased. The estimator works with discrete actions and non-differentiable transitions. Original Dreamer used analytic gradients through latent dynamics; DreamerV3 uses a REINFORCE-style actor update.

For one sampled action, the score is weighted by how far its return lies above or below the baseline. The magnitude matters, but the estimator does not observe the derivative of reward with respect to an untried nearby action. Sampling supplies that information indirectly. A critic baseline reduces variance by subtracting predictable state value without changing the exact score identity.

The pathwise estimator. Also called the analytic or reparameterized gradient, this differentiates directly through the reward and dynamics:

∇ωJ^H(ω)=E[∑t=0H−1γt(∂r^ψ∂atdatdω+∂r^ψ∂z^tdz^tdω)].\nabla_\omega \hat J_H(\omega) = \mathbb{E}\left[\sum_{t=0}^{H-1}\gamma^t\left(\frac{\partial \hat r_\psi}{\partial a_t}\frac{d a_t}{d\omega}+\frac{\partial \hat r_\psi}{\partial \hat z_t}\frac{d\hat z_t}{d\omega}\right)\right].

Here dat/dωd a_t/d\omega and dz^t/dωd\hat z_t/d\omega are total derivatives through all earlier sampled actions and transitions. If the actor objective includes a terminal bootstrap, its derivative must be included too. On a smooth reparameterized model, pathwise gradients often have lower variance than score-function gradients, though long Jacobian products can be unstable. They estimate the gradient of the imagined objective without requiring the model to be correct; model accuracy is needed to identify that gradient with the real-environment gradient. Discrete or discontinuous models may require a relaxation, straight-through estimator, or score-function route.

The score-function estimator uses sampled outcomes; the pathwise estimator additionally uses local model derivatives. Those derivatives can provide efficient credit assignment, but can also be misleading outside the training distribution. Neither estimator removes model bias. Their relative variance and learning speed depend on the model, horizon, policy, and optimizer.

The two can also be mixed, but their weights and bootstrap treatment define the actual objective. A REINFORCE-style bootstrapped actor surrogate, as used in later Dreamer variants, is:

Lactor(ω)=− E[∑t=0H−1γtsg⁡ ⁣(G^tλ−vξ(z^t))log⁡πω(at∣z^t)]−η E[∑t=0H−1H[πω(⋅∣z^t)]].\mathcal{L}_{\text{actor}}(\omega) = -\,\mathbb{E}\left[\sum_{t=0}^{H-1}\gamma^t\operatorname{sg}\!\left(\hat G_t^{\lambda} - v_\xi(\hat z_t)\right)\log \pi_\omega(a_t \mid \hat z_t)\right] - \eta\,\mathbb{E}\left[\sum_{t=0}^{H-1}\mathcal{H}\big[\pi_\omega(\cdot \mid \hat z_t)\big]\right].

The entropy coefficient η\eta can discourage premature concentration. Its effect depends on reward and gradient scales. The toy actor below has a learned global log-standard-deviation, so it cannot modulate exploration by state. Its optional actor.dist(s).entropy() term measures the pre-squash Normal's entropy, a surrogate regularizer rather than the entropy of bounded actions after tanh⁡\tanh. The plotted experiments set η=0\eta=0 to isolate the two gradient routes.

At exactly zero variance, a point-mass policy has no ordinary log-density score; very small variance can make score estimates ill-conditioned and leave too little exploration. Entropy can prevent premature concentration, but stochasticity does not by itself protect against model exploitation.

Two possible stability tools are target critics and return normalization. A slowly updated target critic can reduce target movement; a return scale estimated independently of the current actor batch can moderate gradient magnitude across reward scales. They are not universal requirements. Our toy implementation instead uses a fixed reward scale, bounded actions, a conservative learning rate, and gradient clipping; its exact score-function branch does not normalize the sampled advantage.

Bootstrapping with function approximation can destabilize value learning, especially with off-policy data. Target networks can damp one feedback loop, while scaling changes optimizer step sizes. Neither proves convergence, and scaling the advantage using statistics of the same sampled actions can change the exact score-gradient estimator. The code below keeps that distinction visible.

Finally, note what the actor is not doing. It is not maximizing the true return. The objective is

J^(ω)=Ep^θ, πω[∑t=0H−1γtr^ψ(z^t,at)],\hat J(\omega) = \mathbb{E}_{\hat p_\theta,\, \pi_\omega}\left[\sum_{t=0}^{H-1}\gamma^t \hat r_\psi(\hat z_t, a_t)\right],

where:

  • J^(ω)\hat J(\omega): the imagined return objective as a function of policy parameters ω\omega
  • Ep^θ, πω\mathbb{E}_{\hat p_\theta,\, \pi_\omega}: the expectation taken under the learned model p^θ\hat p_\theta and the current policy πω\pi_\omega
  • γ\gamma: the discount factor
  • r^ψ(z^t,at)\hat r_\psi(\hat z_t, a_t): the model's reward prediction at latent state z^t\hat z_t and action ata_t

an expectation under the model. Everything that follows is about the gap between J^(ω)\hat J(\omega) and the real J(ω)J(\omega).

It is worth stating the mismatch in the sharpest possible terms. The world model is trained to predict observations, rewards, and transitions, which is a prediction objective. The actor is trained to maximize return under the model, which is a control objective. These two objectives are not the same, and nothing in the training procedure guarantees that the model's predictions are accurate on the states the actor will visit. This is sometimes called objective mismatch, and it is the structural reason that improving the model's average prediction error does not automatically improve the policy. A model can become better at predicting the data it was trained on while becoming worse as a training environment, if the improvement comes from fitting incidental structure that the policy then exploits.

Value Expansion and Synthetic Experience

Training a policy in imagination is one way to use a model. Another family uses it to improve value targets or augment replay data. Which approach performs better depends on model accuracy, data regime, task, and compute budget.

The distinction between the two families is a distinction in what the model is asked to do. In pure imagination, the model is asked to be an environment: it supplies entire trajectories, and the policy is trained on them. In value expansion and synthetic experience, the model is asked to be a data amplifier: it supplies a small amount of extra information that improves an otherwise model-free update. The model is still central, but its errors are more contained, because the update is anchored to real data rather than floating free in imagination.

An early ancestor is Sutton's Dyna architecture from 1990, elaborated in 1991. It interleaves updates from real transitions with planning updates from a learned model. The methods below refine how imagined transitions or returns enter a learner; they are not all interchangeable with arbitrary model-free updates.

Dyna separates two questions: where an update's transition comes from, and how the learner uses it. Real and simulated transitions can feed compatible updates, provided the algorithm handles their sampling distribution and model error. Generating extra experience is useful only when those conditions hold.

Model-based value expansion (MVE) uses short model rollouts to build value targets from real replay starts. For a state-value target, the model starts at a replay state and the current policy chooses the first and subsequent imagined actions. An action-value target can instead anchor its first action to the recorded replay action; later imagined actions still come from the current policy, not recorded future actions. The original formulation evaluates reward with the known task reward function; when that is unavailable, a learned reward head adds another error source. The following state-value equation depicts that learned-reward variant:

ytH=∑i=0H−1γir^ψ(s^t+i,at+i)+γHvξ(s^t+H).y_t^{H} = \sum_{i=0}^{H-1}\gamma^i \hat r_\psi(\hat s_{t+i}, a_{t+i}) + \gamma^{H} v_\xi(\hat s_{t+H}).

where:

  • ytHy_t^{H}: the HH-step value expansion target at time tt
  • γ\gamma: the discount factor
  • r^ψ(s^t+i,at+i)\hat r_\psi(\hat s_{t+i}, a_{t+i}): the model's predicted reward at the imaginary state s^t+i\hat s_{t+i} under action at+ia_{t+i}
  • s^t+i\hat s_{t+i}: the ii-th imaginary state along the rollout, initialized from a real state sts_t
  • at+ia_{t+i}: an action sampled from the policy at the imagined state; in this state-value target, that includes ata_t
  • γHvξ(s^t+H)\gamma^{H} v_\xi(\hat s_{t+H}): the bootstrapped value term, weighted by the discount over the whole horizon

The parameter HH controls how many predicted rewards and transitions precede the bootstrap. A longer expansion downweights the terminal critic by γH\gamma^H but exposes the target to more model error. STEVE mixes targets from multiple horizons, using inverse-variance weights estimated from ensembles of dynamics, reward, and value functions; those weights do not correct unestimated bias.

MVE can improve a value target when short-horizon model errors are smaller than the critic errors they replace. It can also make the target worse when the model is inaccurate. There is no universal ordering of model error, critic bias, and Monte Carlo variance. The useful horizon depends on those quantities and their covariance under the policy's state-action distribution.

Synthetic experience takes the Dyna idea literally. Rather than only changing the loss target, generated transitions are written into replay and sampled alongside real ones. The crucial design question is where those trajectories start. Model-based policy optimization (MBPO) branches from real replay states, takes a short number of model steps under the current policy, and adds those synthetic transitions to training. Its rollout length is tuned to model quality and training phase rather than fixed by a universal range.

Branching fixes the starting state to one observed in real replay. It limits the number of consecutive model steps but does not guarantee that subsequent policy actions or imagined states remain on the data distribution. MBPO's analysis makes the tradeoff between rollout length and model error explicit; the useful length depends on model quality and policy shift.

The containment strategy is to reduce, not eliminate, compounding error. Every synthetic transition is only a few model steps removed from a real start. Its distribution can still move far from the data if policy actions or one-step predictions do. Mixing in real data provides an anchor, but the mixture and resulting value estimates must be evaluated rather than assumed reliable.

Two further details matter: the synthetic-to-real sampling ratio, and which policy chooses imagined actions. Too much synthetic data can fit the critic to the model's distribution while concealing real-environment error in the training loss. Current-policy actions may improve relevance to the policy being evaluated but move rollouts away from the behavior data. This tension recurs in Offline and Conservative Model-Based RL.

Training loss on the synthetic mixture cannot establish accuracy under real rollouts. A held-out real transition set can test one-step value or model predictions; closed-loop environment rollouts test policy performance. Neither metric replaces the other. The action distribution deserves the same scrutiny because the model is used at states selected by the current policy, not merely at recorded replay states.

There is one more reason to prefer short rollouts, and it is the reason we return to in the next section: a long synthetic rollout gives the policy more opportunities to steer into a region where the model is wrong.

Regularizing Policies Against Model Errors

For two discounted MDPs with the same state and action spaces, 0≤γ<10\le\gamma<1, and bounded true rewards ∣r(s,a)∣≤Rmax⁡|r(s,a)|\le R_{\max}, let ϵr=sup⁡s,a∣r(s,a)−r^(s,a)∣\epsilon_r=\sup_{s,a}|r(s,a)-\hat r(s,a)| and ϵm=sup⁡s,a∥T(⋅∣s,a)−T^(⋅∣s,a)∥1\epsilon_m=\sup_{s,a}\|T(\cdot\mid s,a)-\hat T(\cdot\mid s,a)\|_1. For any policy π\pi, including one selected using the learned model, Bellman unrolling gives the uniform bound

∥Vπ−V^π∥∞≤ϵr1−γ+γ ϵm Rmax⁡(1−γ)2.\big\|V^\pi - \hat V^\pi\big\|_\infty \le \frac{\epsilon_r}{1-\gamma} + \frac{\gamma\,\epsilon_m\,R_{\max}}{(1-\gamma)^2}.

where:

  • VπV^\pi: the true value function of policy π\pi in the real environment
  • V^π\hat V^\pi: the value function of the same policy under the learned model
  • ∥⋅∥∞\|\cdot\|_\infty: the supremum norm, i.e. the worst-case absolute difference over all states
  • ϵr\epsilon_r: a bound on the per-step reward error ∣r(s,a)−r^(s,a)∣|r(s,a) - \hat r(s,a)|
  • ϵm\epsilon_m: a bound on the per-step transition error ∥T(⋅∣s,a)−T^(⋅∣s,a)∥1\|T(\cdot\mid s,a) - \hat T(\cdot\mid s,a)\|_1
  • TT and T^\hat T: the true and learned transition distributions
  • γ\gamma: the discount factor
  • Rmax⁡R_{\max}: the maximum possible absolute reward
  • (1−γ)−1(1-\gamma)^{-1} and (1−γ)−2(1-\gamma)^{-2}: geometric accumulation factors from the Bellman unrolling

For one policy, write Vπ−V^π=δr+γT^π(Vπ−V^π)+γ(Tπ−T^π)VπV^\pi-\hat V^\pi=\delta_r+\gamma\hat T^\pi(V^\pi-\hat V^\pi)+\gamma(T^\pi-\hat T^\pi)V^\pi. A Markov transition operator is non-expansive in the supremum norm: ∥T^πf∥∞≤∥f∥∞\|\hat T^\pi f\|_\infty\le\|f\|_\infty. Together with ∥Vπ∥∞≤Rmax⁡/(1−γ)\|V^\pi\|_\infty\le R_{\max}/(1-\gamma), this yields the two terms above. The L1L^1 norm in ϵm\epsilon_m measures distance between transition distributions; it is not the induced matrix norm of T^\hat T.

Reward error carries a factor (1−γ)−1(1-\gamma)^{-1}; transition error carries (1−γ)−2(1-\gamma)^{-2} because it changes downstream state values as well as accumulating over time. That is worse horizon scaling, not proof that the transition term dominates: dominance also depends on ϵr\epsilon_r, ϵm\epsilon_m, Rmax⁡R_{\max}, and units. This is an infinite-horizon bound in γ\gamma, not a finite-imagination-horizon bound in HH. The unbounded quadratic reward of the toy point mass below does not satisfy its global Rmax⁡R_{\max} assumption without restricting the state domain.

The bound can be too loose to certify useful performance because it uses global worst-case errors and large discount factors. It still applies to a policy selected after seeing the model: the errors are uniform over all state-action pairs. What fails under policy optimization is the comforting inference from a small average prediction error on a fixed dataset. The learned policy may select reachable regions where optimistic error is much larger than that average.

The practical distinction is therefore between uniform and distribution-weighted evidence. A uniform bound covers the selected policy but is often vacuous. A test-set average can be precise yet irrelevant to the states that policy visits. Closed-loop evaluation supplies the missing decision-focused check.

The imagination gap, J^(ω)−J(ω)\hat J(\omega)-J(\omega), is a useful diagnostic when the two returns use the same starting-state distribution, policy, horizon, and discount. It can be positive or negative: models can be optimistic or pessimistic. A persistent positive gap alongside improving imagined and worsening real return is consistent with exploitation, but its cause still needs investigation.

In particular, the sign of the gap is not a theorem. The horizon sweep below contains negative as well as positive gaps. Track its magnitude and sign, then inspect the trajectories and model errors responsible rather than interpreting a single scalar as proof of intent or mechanism.

Four families of remedies are in common use.

Limit how far the policy can look. Shortening the imagination horizon or terminating a rollout outside estimated data support can reduce compounding model error, though even one-step errors can be exploited. Lowering the discount also changes the task objective and may suppress delayed rewards. The tradeoff prepares the hierarchical methods in Hierarchical, Symbolic, Language, and Multi-Agent Planning.

Shorter rollouts bound the number of consecutive model predictions; they do not guarantee that the visited states are trustworthy. When reward depends on delayed consequences, truncation can damage credit assignment unless a reliable terminal value supplies the tail. Hierarchical skills can reduce decision depth, but their option-level models also need validation.

Penalize uncertainty. Train an ensemble with different seeds or bootstrap resamples. For a DD-coordinate next state, scale each coordinate by a declared task scale dj>0d_j>0, then form a scalar disagreement such as u(s,a)=D−1∑j=1D(std⁡k[T^k,j(s,a)]/dj)2u(s,a)=\sqrt{D^{-1}\sum_{j=1}^{D}(\operatorname{std}_k[\hat T_{k,j}(s,a)]/d_j)^2}. This uu is dimensionless, so λ\lambda has reward units in the shaped reward:

r~(s,a)=r^ψ(s,a)−λ u(s,a).\tilde r(s,a) = \hat r_\psi(s,a) - \lambda\, u(s,a).

where:

  • r~(s,a)\tilde r(s,a): the pessimism-adjusted reward used for actor learning
  • r^ψ(s,a)\hat r_\psi(s,a): the model's predicted reward at state ss and action aa
  • λ\lambda: a coefficient in reward units that sets the cost of one unit of standardized disagreement
  • u(s,a)u(s,a): a nonnegative scalar summary of standardized ensemble transition disagreement

The policy pays a price where the ensemble disagrees. MOPO uses a related model-uncertainty reward penalty. MOReL instead constructs a pessimistic MDP that sends unknown state-action pairs to a low-reward absorbing state. Ensemble spread is a heuristic for epistemic uncertainty, not a calibrated guarantee: members can disagree in familiar regions or agree on a shared misspecification.

Epistemic uncertainty reflects limited evidence; model misspecification reflects a representational or training limitation that may persist with more data. An ensemble can expose some epistemic uncertainty, but agreement alone cannot rule out common-mode error. The toy penalty sweep below shows one setting where a stronger penalty helps modestly; it does not certify safety or replace targeted data collection when interaction is possible.

Stay close to the data. A behavior-cloning or KL penalty added to the actor loss keeps the learned policy near the policy that generated the training data:

L(ω)=Lactor(ω)+β E[DKL ⁣[πω(⋅∣z^t) ∥ πdata(⋅∣z^t)]].\mathcal{L}(\omega) = \mathcal{L}_{\text{actor}}(\omega) + \beta\,\mathbb{E}\left[D_{\mathrm{KL}}\!\left[\pi_\omega(\cdot\mid \hat z_t)\,\big\|\,\pi_{\text{data}}(\cdot\mid \hat z_t)\right]\right].

This is one family of offline-RL regularizers. It discourages departures from high-density behavior actions where the model may be poorly supported. A finite penalty does not guarantee that the learned policy stays in empirical support, nor does it impose an absolute performance ceiling. Offline learning can use a fixed dataset without an online exploration phase.

The tradeoff is that stronger conservatism may prevent valuable departures from the behavior policy. Its useful strength depends on data coverage and model error; neither the KL term nor behavior cloning by itself makes a policy safe. The point is to make unsupported actions costly while checking real-environment performance whenever interaction is available.

Keep one foot in reality. Online systems such as Dreamer and MBPO alternate real interaction with model and behavior updates. New transitions can reveal errors along the current policy's trajectory; whether retraining repairs them depends on model capacity and optimization. This is the subject of Online, Offline, and Continual Learning.

Interleaving real interaction attacks distribution shift directly, but it costs environment samples and cannot guarantee a corrected model under misspecification. It is complementary to short rollouts and policy constraints rather than a replacement for their validation.

A final, less obvious regularizer is gradient control. If the actor is optimized with pathwise gradients, the gradient magnitude scales with the Jacobian of the model, and a model with a spuriously large local slope will produce a spuriously large update. Clipping the actor gradient norm and scaling the pathwise term by a constant are cheap insurance. And the stop-gradient rule from earlier is itself a regularizer: if the actor loss could touch the model, the model would drift toward being optimistic, which is the opposite of what we want.

Gradient clipping limits the norm of a single parameter update direction before the optimizer step; it does not bound model error or closed-loop state excursions. Adjusting a pathwise term's weight changes the optimization surrogate and may help or hurt. The score-function term is not categorically more robust to a wrong model, since it still uses model-generated outcomes.

Worked Example: A One-Dimensional Point Mass

Abstract warnings about exploitation are easy to nod along to and hard to internalize. A concrete example makes the failure visible.

Our environment is a point mass with drag moving on a line. The state is position and velocity, s=(x,v)s = (x, v), and the action aa is an acceleration. The dynamics are linear:

xt+1=xt+Δt vt,vt+1=ρ vt+Δt at,x_{t+1} = x_t + \Delta t\, v_t, \qquad v_{t+1} = \rho\, v_t + \Delta t\, a_t,

with Δt=0.1\Delta t = 0.1 and ρ=0.99\rho = 0.99. The reward penalizes distance from a target at x⋆=2.0x^\star = 2.0 and the squared control effort:

r(s,a)=−(x−x⋆)2−0.05 a2.r(s, a) = -(x - x^\star)^2 - 0.05\,a^2.

The maximum per-step reward is 00 when x=x⋆x=x^\star and a=0a=0, regardless of velocity. Position, velocity, action, and reward are normalized toy quantities rather than physical SI measurements. Evaluation runs for 40 steps from states near rest at the origin.

The system is linear, low-dimensional, and fully observed. That removes representation learning and partial observability from this particular demonstration. The learned MLP is still an approximation, and optimizer behavior can interact with its errors. We will measure both prediction and closed-loop control rather than attribute every outcome to coverage alone.

The comparison uses two world models trained on different datasets.

  • Model A is trained on data collected from initial states near the origin, with position and velocity independently drawn from zero-mean normals with standard deviation 0.250.25, and with small actions. It has essentially never seen the region around x=2.0x = 2.0.
  • Model B is trained on data collected from initial states spread uniformly over [−3,3][-3, 3] with wider actions. It has seen the goal region many times.

Both models have the same architecture, transition count, loss, and optimizer. The treatment is the data collection distribution: Model A uses concentrated starts and smaller random actions; Model B uses wider starts and actions. This changes several state-action marginals together, not one isolated scalar.

The comparison can show how those two collection regimes affect learned predictions and downstream policies, but it cannot prove that goal-state coverage alone caused every behavioral difference. Training randomness, action coverage, and the actor optimizer also matter. A small seed check below keeps one attractive trajectory from standing in for a general result.

Model A's reward prediction near and beyond the goal relies much more on extrapolation. The learned policy may therefore see less cost to overshooting than the true reward assigns. Model B has direct samples around the goal, but broader data is not a guarantee of a good controller: the actor still needs a stable objective, bounded actions, and closed-loop evaluation.

In the reproducible run below, the narrow-model policy overshoots the target more than the broad-model policy and has a positive imagination gap. Both overshoot to some extent. That is evidence for this particular setup, not a claim that all narrow models fail or all broad models succeed.

We track the imagination gap: the return the learned model estimates for the policy minus its return in the real environment.

Implementing Imagination-Based Learning

Let us build the experiment. We start with the environment and a data collection routine, then train the two models, then run actor-critic learning inside each.

The environment is small enough to express directly, and we will use the analytic reward for evaluation while the models learn their own reward head.

In[3]:
Code
import numpy as np
import torch
import torch.nn as nn

DT, DRAG = 0.1, 0.99
GAMMA, LAM = 0.99, 0.95
TARGET, CTRL = 2.0, 0.05
EVAL_HORIZON = 40

torch.set_num_threads(1)


def true_reward(x, a):
    """Analytic reward: used to score the real environment during evaluation."""
    return -((x - TARGET) ** 2) - CTRL * a**2

The analytic reward supplies labels for the real training transitions and scores real evaluation rollouts. During imagined actor updates, the learner sees only the fitted reward head. Keeping those roles distinct lets us compare model-predicted return with the actual task reward; it does not mean the reward head was trained without true-reward labels.

Data collection draws episodes with a chosen initial-state distribution and a chosen action scale. Both dataset parameters are what distinguish Model A from Model B.

In[4]:
Code
def collect(init_fn, action_scale, n_episodes=300, ep_len=40, seed=0):
    """Roll out the true environment under a uniform random behaviour policy."""
    rng = np.random.default_rng(seed)
    s_buf, a_buf, r_buf, sn_buf = [], [], [], []
    for _ in range(n_episodes):
        x, v = init_fn(rng)
        for _ in range(ep_len):
            a = rng.uniform(-action_scale, action_scale)
            r = true_reward(x, a)
            x_next = x + DT * v + rng.normal(0.0, 0.01)
            v_next = DRAG * v + DT * a + rng.normal(0.0, 0.01)
            s_buf.append((x, v))
            a_buf.append((a,))
            r_buf.append(r)
            sn_buf.append((x_next, v_next))
            x, v = x_next, v_next
    return (
        np.asarray(s_buf, dtype=np.float32),
        np.asarray(a_buf, dtype=np.float32),
        np.asarray(r_buf, dtype=np.float32)[:, None],
        np.asarray(sn_buf, dtype=np.float32),
    )


narrow = collect(
    lambda rng: (rng.normal(0.0, 0.25), rng.normal(0.0, 0.25)),
    action_scale=0.4,
    seed=1,
)
broad = collect(
    lambda rng: (rng.uniform(-3.0, 3.0), rng.uniform(-0.8, 0.8)),
    action_scale=1.0,
    seed=2,
)
Out[5]:
Console
narrow:  12000 transitions | |x| max 2.64 | |v| max 0.68
 broad:  12000 transitions | |x| max 7.17 | |v| max 1.47

The narrow dataset has only 9 of 12,000 positions within 0.2 of x=2.0x=2.0 and none at or beyond it; the broad dataset has 641 within that band. These counts measure one aspect of the wider collection distribution. The histograms show the positional difference, not the full action or velocity coverage.

Out[6]:
Visualization
Overlaid histograms compare positions in narrow and broad training datasets, with a vertical marker at the goal position x equals 2.
Positions in the two 12,000-transition datasets. Model A has sparse samples near the goal and none at or beyond x = 2.0; Model B has many samples around it. Initial-state and action sampling both differ between collection regimes.

The world model predicts the state delta and the normalized reward. Predicting a delta rather than an absolute next state is a small but meaningful inductive bias: it makes the identity dynamics the default, so the network only has to learn the correction.

The delta parameterization is worth a sentence of justification, because it is the kind of choice that looks cosmetic but is not. The true dynamics are close to the identity over a short step, since the position changes by Δt v\Delta t\,v and the velocity changes by a small amount. A network that predicts the next state directly has to relearn the identity mapping from scratch, spending capacity on reproducing something it already knows. A network that predicts the delta starts from the identity and only has to learn the small correction. This is the same reason residual connections help deep networks: the identity path is a strong prior, and it costs nothing to build it in.

In[7]:
Code
class WorldModel(nn.Module):
    """Predicts the next state and reward for (state, action) pairs."""

    def __init__(self, hidden=64):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(3, hidden),
            nn.SiLU(),
            nn.Linear(hidden, hidden),
            nn.SiLU(),
            nn.Linear(hidden, 3),
        )
        self.register_buffer("r_mu", torch.zeros(1))
        self.register_buffer("r_sigma", torch.ones(1))

    def forward(self, s, a):
        out = self.net(torch.cat([s, a], dim=-1))
        return s + out[:, :2], out[:, 2]

    def step(self, s, a):
        s_next, r_norm = self.forward(s, a)
        return s_next, self.r_mu + self.r_sigma * r_norm
In[8]:
Code
def train_world_model(
    data, steps=3000, batch=256, lr=3e-3, seed=0, bootstrap=False
):
    """Fit a dynamics-and-reward model by minibatch least squares."""
    torch.manual_seed(seed)
    s, a, r, sn = (torch.as_tensor(x) for x in data)
    r_norm = (r - r.mean()) / r.std()
    n = len(s)
    if bootstrap:
        idx = torch.randint(0, n, (n,))
        s, a, r_norm, sn = s[idx], a[idx], r_norm[idx], sn[idx]

    model = WorldModel()
    model.r_mu = r.mean().reshape(1)
    model.r_sigma = r.std().reshape(1)
    optimiser = torch.optim.Adam(model.parameters(), lr=lr)

    for _ in range(steps):
        idx = torch.randint(0, n, (batch,))
        s_hat, r_hat = model(s[idx], a[idx])
        loss = ((s_hat - sn[idx]) ** 2).mean() + (
            (r_hat - r_norm[idx, 0]) ** 2
        ).mean()
        optimiser.zero_grad()
        loss.backward()
        optimiser.step()

    model.eval()
    return model


model_narrow = train_world_model(narrow, seed=10)
model_broad = train_world_model(broad, seed=10)

Both models fit their training data well. The interesting question is what happens away from it.

The mechanism behind Model A's failure is visible in its reward head. Plotting each model's predicted reward along a slice of position reveals how far each one is willing to extrapolate, and where the optimizer will be pulled.

In[9]:
Code
probe_x = np.linspace(-3.0, 4.0, 200)
probe_v = np.zeros_like(probe_x)
probe_a = np.zeros_like(probe_x)
probe_s = torch.tensor(
    np.stack([probe_x, probe_v], axis=1), dtype=torch.float32
)
probe_act = torch.tensor(probe_a[:, None], dtype=torch.float32)

with torch.no_grad():
    probe_reward_true = true_reward(probe_s[:, 0], probe_act[:, 0]).numpy()
    probe_reward_narrow = (
        model_narrow.r_mu
        + model_narrow.r_sigma * model_narrow(probe_s, probe_act)[1]
    ).numpy()
    probe_reward_broad = (
        model_broad.r_mu
        + model_broad.r_sigma * model_broad(probe_s, probe_act)[1]
    ).numpy()
Out[10]:
Visualization
Line chart compares the analytic reward curve with reward predictions from narrow-coverage and broad-coverage models across position.
Zero-action reward predictions across position. Model A's narrow-data head peaks near x = 2.1 but underestimates the cost of overshoot: at x = 4 it predicts about -1.21 versus the true -4. Model B predicts about -4.06 there. This slice does not establish closed-loop policy quality.

Figure 2. Both heads peak near the goal, but Model A penalizes overshoot too weakly: at x=4x=4 and zero action it predicts about −1.21-1.21 instead of −4-4. Model B predicts about −4.06-4.06 there. The slice isolates reward extrapolation, not full closed-loop behavior.

The training loss does not report this out-of-distribution reward error. The next cell probes dynamics separately by rolling both models open loop from starts near the goal. Reward accuracy and transition accuracy are distinct; neither by itself certifies a useful policy.

We test them on a probe set of trajectories that start near the target at x=2.0x = 2.0 and roll out open loop under the true dynamics. Open-loop means the model receives only the initial state and the action sequence; every predicted state becomes the input for the next prediction, so errors compound.

Open-loop probing measures how state error grows when predictions become inputs. The narrow model has sparse goal-region data rather than none, and the probe compares its error with the broad model's under the same initial states and actions.

In[11]:
Code
def open_loop_error(model, s0, actions, true_states):
    """Per-step mean squared state error of an open-loop model rollout."""
    s = s0.clone()
    errors = []
    for t in range(actions.shape[1]):
        with torch.no_grad():
            s = model.step(s, actions[:, t])[0]
        errors.append(((s - true_states[t + 1]) ** 2).sum(-1).mean().item())
    return np.array(errors)


probe_rng = np.random.default_rng(7)
n_probe, probe_horizon = 32, 25
probe_s0 = torch.tensor(
    np.stack(
        [
            2.0 + 0.2 * probe_rng.normal(size=n_probe),
            0.5 * probe_rng.normal(size=n_probe),
        ],
        axis=1,
    ),
    dtype=torch.float32,
)
probe_actions = torch.tensor(
    probe_rng.uniform(-0.5, 0.5, size=(n_probe, probe_horizon, 1)),
    dtype=torch.float32,
)

true_probe_states = [probe_s0]
s = probe_s0
for t in range(probe_horizon):
    a = probe_actions[:, t, 0]
    s = torch.stack([s[:, 0] + DT * s[:, 1], DRAG * s[:, 1] + DT * a], dim=1)
    true_probe_states.append(s)

error_narrow = open_loop_error(
    model_narrow, probe_s0, probe_actions, true_probe_states
)
error_broad = open_loop_error(
    model_broad, probe_s0, probe_actions, true_probe_states
)
Out[12]:
Visualization
Line chart shows open-loop prediction error increasing rapidly with rollout step for the narrow-data model while remaining lower for the broad-data model.
Open-loop mean squared state error from 32 starts near the goal. Error grows for both models; at step 25 it is about 0.156 for Model A and 0.0183 for Model B. The narrow model is substantially worse on this probe, but these curves alone do not certify a policy.

Figure 3. Both models accumulate open-loop state error. At step one, the narrow and broad MSEs are approximately 6.58×10−56.58\times10^{-5} and 2.07×10−52.07\times10^{-5}; at step 25 they are 0.1560.156 and 0.01830.0183. The narrow model is roughly 8.5 times worse at the end of this probe.

The first-step errors are small but differ by a factor of about 3.2. Both errors then grow, with Model A ending substantially higher. The models fit their respective training samples, but we have not shown that their training losses are equal or that Model B is accurate everywhere its actor will go.

The probe separates small one-step error from larger multi-step drift. It shows why reporting only in-distribution training loss would be insufficient: these rollouts begin near a goal that Model A's collection policy rarely visited. Closed-loop policy evaluation remains a separate test.

Now the policy. The actor samples a Gaussian raw action and applies tanh⁡\tanh so the environment action stays in [−1,1][-1,1]. Its MLP mean and learned state-independent log-standard-deviation parameterize the raw Gaussian. The critic is a plain MLP. Bounding actions is part of the toy task specification, not a seed-specific rescue: without it, the earlier unbounded actor could produce exploding real trajectories even with the broad model.

In[13]:
Code
class Actor(nn.Module):
    """Tanh-squashed Gaussian policy; environment actions lie in [-1, 1]."""

    def __init__(self, hidden=64):
        super().__init__()
        self.body = nn.Sequential(
            nn.Linear(2, hidden),
            nn.SiLU(),
            nn.Linear(hidden, hidden),
            nn.SiLU(),
            nn.Linear(hidden, 1),
        )
        self.log_std = nn.Parameter(torch.tensor([-1.0]))

    def forward(self, s):
        return torch.tanh(self.body(s))

    def dist(self, s):
        mean = self.body(s)
        return torch.distributions.Normal(
            mean, self.log_std.exp().expand_as(mean)
        )


class Critic(nn.Module):
    def __init__(self, hidden=64):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(2, hidden),
            nn.SiLU(),
            nn.Linear(hidden, hidden),
            nn.SiLU(),
            nn.Linear(hidden, 1),
        )

    def forward(self, s):
        return self.net(s).squeeze(-1)

The λ\lambda-return recursion is a short backward loop. Note that the values entering the target are detached, which keeps the critic's regression target fixed within a step.

In[14]:
Code
def lambda_returns(rewards, values, gamma=GAMMA, lam=LAM):
    """Backward recursion for lambda-returns along an imagined rollout."""
    vals = [v.detach() for v in values]
    acc = torch.zeros_like(vals[0])
    out = [None] * len(rewards)
    for t in reversed(range(len(rewards))):
        delta = rewards[t] + gamma * vals[t + 1] - vals[t]
        acc = delta + gamma * lam * acc
        out[t] = vals[t] + acc
    return out

The imagination loop collects states, actions, rewards, values, and log-probabilities. Setting pathwise=True keeps the sampled action attached to the graph so gradients flow through the model; the default detaches it for the score-function estimate.

The pathwise flag is the switch between the two gradient estimators from earlier in the chapter, and it is worth tracing what it changes. When pathwise=False, the action is detached before it enters the model, so the model sees a constant input and the reward-objective gradient reaches the actor through the score-function term. If the optional entropy coefficient eta is positive, the actor also receives a direct entropy-regularization gradient; the plotted comparisons set eta=0. When pathwise=True, the action stays attached, so the reward and the next state both depend on the policy's parameters and the actor receives the analytic gradient through the model. The same rollout function supports both, which makes the comparison in the final cell a one-line change.

In[15]:
Code
def imagine(model, actor, critic, s0, horizon, pathwise=False):
    """Roll the world model forward under the actor for `horizon` steps."""
    s = s0
    states, actions, rewards, values, logps = [], [], [], [], []
    for _ in range(horizon):
        states.append(s)
        dist = actor.dist(s)
        raw_a = dist.rsample()
        a = torch.tanh(raw_a)
        a_model = a if pathwise else a.detach()
        actions.append(a_model)
        s_next, r_hat = model.step(s, a_model)
        rewards.append(r_hat)
        # The critic learns from imagined states, but its update must not
        # backpropagate through the actor or world-model rollout graph.  The
        # actor update below owns that graph in pathwise mode.
        values.append(critic(s.detach()))
        # The tanh transform is parameter-independent when its sampled raw
        # action is held fixed; its score is the raw Normal score.
        logps.append(dist.log_prob(raw_a.detach()).sum(-1))
        s = s_next
    values.append(critic(s.detach()))
    return states, actions, rewards, values, logps

Two evaluation helpers let us watch the gap. imagined_return scores the deterministic policy under the model; true_return scores the same policy in the real environment. Both use a 40-step horizon so the numbers are comparable even when the training horizon is shorter.

Both evaluations use the same deterministic mean policy, start states, horizon, and discount. The real evaluation uses the analytic, noise-free dynamics and reward; data collection alone adds small transition noise. The imagined evaluation uses the learned transition and reward heads. Their difference measures this complete model-versus-environment mismatch, not only transition error.

In[16]:
Code
@torch.no_grad()
def true_return(actor, s0, horizon=EVAL_HORIZON):
    """Closed-loop return of the deterministic policy in the real environment."""
    s = s0.clone()
    total = torch.zeros(s.shape[0])
    discount = 1.0
    for _ in range(horizon):
        a = actor(s)
        total = total + discount * true_reward(s[:, 0], a[:, 0])
        s = torch.stack(
            [s[:, 0] + DT * s[:, 1], DRAG * s[:, 1] + DT * a[:, 0]], dim=1
        )
        discount *= GAMMA
    return total.mean().item()


@torch.no_grad()
def imagined_return(actor, model, s0, horizon=EVAL_HORIZON):
    """Closed-loop return of the deterministic policy under the world model."""
    s = s0.clone()
    total = torch.zeros(s.shape[0])
    discount = 1.0
    for _ in range(horizon):
        a = actor(s)
        s, r_hat = model.step(s, a)
        total = total + discount * r_hat
        discount *= GAMMA
    return total.mean().item()

The training loop ties it together. The critic uses detached λ\lambda-targets, while the actor uses a sampled, finite-horizon reward-to-go and a state-dependent critic baseline. Both actor-gradient branches therefore target the same truncated discounted reward objective. The actor gradient is clipped, and the model parameters are excluded from its optimizer.

The score branch retains the outcome magnitude rather than normalizing advantages from the same samples, which would change the exact score estimate. Its sampled return is truncated at HH even though the critic target bootstraps there; this distinction is deliberate. Action squashing enforces the task's actuator limit and prevents the unbounded-policy divergence seen in the initial diagnostic run. Clipping controls update size but does not guarantee convergence or protection against model error.

In[17]:
Code
def train_imagination(
    model,
    horizon=20,
    iterations=250,
    batch=64,
    lr=1e-3,
    gamma=GAMMA,
    lam=LAM,
    eta=1e-3,
    seed=0,
    pathwise=False,
    uncertainty=None,
    penalty=0.0,
    eval_states=None,
    record_every=25,
):
    """Actor-critic training entirely inside the learned model."""
    if pathwise and penalty > 0.0:
        raise ValueError(
            "The toy pathwise branch does not differentiate uncertainty"
        )
    torch.manual_seed(seed)
    for parameter in model.parameters():
        parameter.requires_grad_(False)
    actor, critic = Actor(), Critic()
    opt_a = torch.optim.Adam(actor.parameters(), lr=lr)
    opt_c = torch.optim.Adam(critic.parameters(), lr=lr)
    history = {"iter": [], "imagined": [], "true": []}

    for it in range(iterations):
        s0 = torch.randn(batch, 2) * torch.tensor([0.25, 0.25])
        states, actions, rewards, values, logps = imagine(
            model, actor, critic, s0, horizon, pathwise
        )

        if uncertainty is not None and penalty > 0.0:
            rewards = [
                r - penalty * uncertainty(s.detach(), a.detach())
                for r, s, a in zip(rewards, states, actions)
            ]

        returns = lambda_returns(rewards, values, gamma, lam)
        v_stack = torch.stack(values[:-1])
        g_stack = torch.stack(returns).detach()

        critic_loss = ((v_stack - g_stack) ** 2).mean()
        opt_c.zero_grad()
        critic_loss.backward()
        opt_c.step()

        if pathwise:
            actor_loss = (
                -sum((gamma**t) * rewards[t] for t in range(horizon)).mean()
                / horizon
            )
        else:
            # A full sampled reward-to-go gives a score-function estimate of
            # the same truncated H-step objective as the pathwise branch.
            tail = torch.zeros_like(rewards[0])
            reward_to_go = [None] * horizon
            for t in reversed(range(horizon)):
                tail = rewards[t].detach() + gamma * tail
                reward_to_go[t] = tail
            advantage = torch.stack(reward_to_go) - v_stack.detach()
            discounts = torch.tensor(
                [gamma**t for t in range(horizon)], dtype=advantage.dtype
            )[:, None]
            actor_loss = (
                -(discounts * advantage * torch.stack(logps)).sum(dim=0).mean()
                / horizon
            )

        if eta > 0.0:
            entropy = torch.stack(
                [actor.dist(s).entropy().sum(-1) for s in states]
            ).mean()
            actor_loss = actor_loss - eta * entropy

        opt_a.zero_grad()
        actor_loss.backward()
        torch.nn.utils.clip_grad_norm_(actor.parameters(), 5.0)
        opt_a.step()

        if eval_states is not None and (
            it % record_every == 0 or it == iterations - 1
        ):
            history["iter"].append(it)
            history["imagined"].append(
                imagined_return(actor, model, eval_states)
            )
            history["true"].append(true_return(actor, eval_states))

    return {"actor": actor, "critic": critic, "history": history}
In[18]:
Code
torch.manual_seed(123)
eval_states = 0.02 * torch.randn(64, 2)
eval_states[:, 0] = eval_states[:, 0] + 0.0

res_narrow = train_imagination(
    model_narrow,
    seed=0,
    eval_states=eval_states,
    horizon=30,
    iterations=400,
    eta=0.0,
)
res_broad = train_imagination(
    model_broad,
    seed=0,
    eval_states=eval_states,
    horizon=30,
    iterations=400,
    eta=0.0,
)
Out[19]:
Visualization
Training curves compare imagined and real returns for policies learned with narrow-data and broad-data world models.
One seeded actor-critic run per model with bounded actions and a 30-step training rollout. Both real returns improve overall but fluctuate. At iteration 399, Model A's imagined and real 40-step returns are about -47.7 and -51.3; Model B's are about -47.2 and -47.1. This run shows a modest optimistic gap for Model A, not monotone exploitation or a universal coverage guarantee.

Figure 4. Both policies improve overall in this run, with visible fluctuations. Model A ends at approximately −47.7-47.7 imagined versus −51.3-51.3 real return; Model B ends at −47.2-47.2 versus −47.1-47.1. A positive imagination gap is visible for Model A, but this chart alone does not establish its cause.

Model B's final predicted and real returns happen to agree closely here; Model A's do not. Neither curve rises smoothly, and neither comparison proves that coverage alone caused the gap. The reward probe and real trajectory help identify the plausible mechanism: Model A underprices overshoot outside its dense data region.

The plot does not show critic loss or training stability directly. It does show why an imagined learning curve is not enough: a model can predict more return than the same policy earns in the environment. Repeating the experiment across actor seeds is needed before treating the size of that gap as a stable property of the collection regime.

In[20]:
Code
seed_check = []
for actor_seed in (0, 1, 2):
    for name, model, first_run in (
        ("A/narrow", model_narrow, res_narrow),
        ("B/broad", model_broad, res_broad),
    ):
        run = (
            first_run
            if actor_seed == 0
            else train_imagination(
                model,
                seed=actor_seed,
                eval_states=eval_states,
                horizon=30,
                iterations=400,
                eta=0.0,
            )
        )
        imagined = imagined_return(run["actor"], model, eval_states)
        real = true_return(run["actor"], eval_states)
        seed_check.append((actor_seed, name, imagined, real))
        print(
            f"seed {actor_seed} {name:>8}: imagined {imagined:7.2f} | real {real:7.2f}"
        )
Out[20]:
Console
seed 0 A/narrow: imagined  -47.68 | real  -51.26
seed 0  B/broad: imagined  -47.24 | real  -47.14
seed 1 A/narrow: imagined  -60.33 | real  -60.26
seed 1  B/broad: imagined  -49.83 | real  -50.71
seed 2 A/narrow: imagined  -47.78 | real  -51.26
seed 2  B/broad: imagined  -52.70 | real  -52.16

The three fixed seeds show variation in both real return and the sign or size of the gap. They are a robustness check for this toy protocol, not an uncertainty interval for a broader population of tasks.

The consequences for behavior are equally visible. Rolling each trained policy out in the real environment shows where it actually ends up, as opposed to where its imagination believes it is.

In[21]:
Code
@torch.no_grad()
def policy_positions(actor, s0, horizon=EVAL_HORIZON):
    """Closed-loop mean position of the deterministic policy in the real environment."""
    s = s0.clone()
    xs = [s[:, 0].mean().item()]
    for _ in range(horizon):
        a = actor(s)
        s = torch.stack(
            [s[:, 0] + DT * s[:, 1], DRAG * s[:, 1] + DT * a[:, 0]], dim=1
        )
        xs.append(s[:, 0].mean().item())
    return np.array(xs)


pos_narrow = policy_positions(res_narrow["actor"], eval_states)
pos_broad = policy_positions(res_broad["actor"], eval_states)
pos_steps = np.arange(len(pos_narrow))
Out[22]:
Visualization
Mean position trajectories compare policies trained in narrow-data and broad-data models against a horizontal goal-position reference.
Mean closed-loop position under the two seed-0 policies. Both pass the goal rather than settle there by step 40: Model A ends near x = 2.92 and Model B near x = 2.36. The shaded goal tolerance is x = 2.0 ± 0.15. Model A overshoots more in this run, consistent with its optimistic reward extrapolation, but not proof of coverage as the sole cause.

Figure 5. Neither policy settles inside the shaded 2.0±0.152.0\pm0.15 band at step 40. Model A ends near 2.922.92, Model B near 2.362.36. The legend maps each line to its trained model.

Next we sweep the imagination horizon while keeping the actor seed, iteration budget, optimizer, and 40-step evaluation protocol fixed. Horizon changes both the training objective and the trajectories seen by the optimizer. Short rollouts may omit useful delayed consequences; longer ones may accumulate more model error. Neither effect guarantees a monotone curve.

In[23]:
Code
horizons = [5, 10, 20, 30, 40]
sweep = {"horizon": [], "imagined": [], "true": [], "gap": []}
for h in horizons:
    out = train_imagination(
        model_narrow, horizon=h, seed=0, iterations=400, eta=0.0
    )
    imag = imagined_return(out["actor"], model_narrow, eval_states)
    real = true_return(out["actor"], eval_states)
    sweep["horizon"].append(h)
    sweep["imagined"].append(imag)
    sweep["true"].append(real)
    sweep["gap"].append(imag - real)
Out[24]:
Visualization
Line chart compares imagined and real policy returns across increasing imagination horizons for the narrow-coverage model.
Single-seed horizon sweep for Model A, evaluated over the same 40 real or imagined steps. Returns are nonmonotone: H = 20 gives a large optimistic gap, while H = 30 and 40 perform substantially better in reality. These are separately trained policies with different objectives, not a nested sequence of improvements.

Figure 6. At H=20H=20, predicted return is about −63-63 while real return is about −126-126; at H=30H=30, they are about −48-48 and −51-51. The gap can also be negative at shorter horizons. The comparison is a single-seed sensitivity check, not evidence that increasing HH must help or hurt.

Neither curve is monotone. The shortest training horizons perform poorly, plausibly because they provide little credit for reaching x=2x=2 from near the origin. The H=20H=20 run has a large positive gap, while the longer H=30H=30 and 4040 runs perform better under this fixed iteration budget. Horizon is therefore a hyperparameter to validate in the closed loop, not a one-direction safety dial.

These policies are trained separately, with nonconvex function approximation and finite optimization. A longer rollout changes the objective rather than enlarging a nested feasible set. The gap at a particular horizon reports model-versus-environment return for that trained policy; it does not identify the cause without inspecting trajectories and errors.

Now to value expansion. The next diagnostic starts from real replay states but uses a fixed, generated action sequence in both model and true dynamics. This isolates prefix-return prediction error; it is not an implementation of MVE's policy-generated imagined actions. As HH grows, the model's mean partial return can drift from truth while the coefficient on an HH-step terminal bootstrap, γH\gamma^H, decreases. The panels have different units and do not locate an optimal horizon.

In[25]:
Code
branch_rng = np.random.default_rng(11)
n_branch, branch_horizon = 64, 30
branch_idx = branch_rng.choice(len(narrow[0]), size=n_branch, replace=False)
branch_s0 = torch.tensor(narrow[0][branch_idx])
branch_actions = torch.tensor(
    branch_rng.uniform(-0.8, 0.8, size=(n_branch, branch_horizon, 1)),
    dtype=torch.float32,
)

true_branch_states = [branch_s0]
s = branch_s0.clone()
for t in range(branch_horizon):
    a = branch_actions[:, t, 0]
    s = torch.stack([s[:, 0] + DT * s[:, 1], DRAG * s[:, 1] + DT * a], dim=1)
    true_branch_states.append(s)

model_rewards, true_rewards = [], []
s = branch_s0.clone()
with torch.no_grad():
    for t in range(branch_horizon):
        a = branch_actions[:, t]
        s, r_hat = model_narrow.step(s, a)
        model_rewards.append(r_hat)
        true_rewards.append(true_reward(true_branch_states[t][:, 0], a[:, 0]))


def discounted_prefix(reward_list):
    out, acc, discount = [], torch.zeros_like(reward_list[0]), 1.0
    for r in reward_list:
        acc = acc + discount * r
        out.append(acc)
        discount *= GAMMA
    return out


model_prefix = discounted_prefix(model_rewards)
true_prefix = discounted_prefix(true_rewards)
bias_curve = np.array(
    [
        abs(m.mean().item() - t.mean().item())
        for m, t in zip(model_prefix, true_prefix)
    ]
)
bootstrap_weight = np.array([GAMMA ** (h + 1) for h in range(branch_horizon)])
horizon_axis = np.arange(1, branch_horizon + 1)
Out[26]:
Visualization
Line chart shows the absolute difference of batch-mean model and true prefix returns increasing with rollout horizon.
Absolute difference between batch-mean model and true H-step prefix returns under the same generated action sequence. It grows from nearly zero at H = 1 to about 8.9 at H = 30. This mean difference may hide cancellation across trajectories.
Line chart shows the value-function bootstrap weight decreasing geometrically with rollout horizon.
Coefficient gamma^H on a terminal value in an H-step expansion target. It falls from 0.99 at H = 1 to about 0.74 at H = 30. This coefficient alone says nothing about critic error or total target quality.

Figure 7a. The plotted quantity is the absolute difference of two batch means, not the mean absolute per-trajectory error. It grows from about 0.000060.00006 at one step to 8.918.91 at 30 under this fixed generated action sequence.

Figure 7b. The terminal-value coefficient decreases from 0.990.99 at one step to about 0.740.74 at 30 steps. It is a coefficient, not a measurement of the critic's error.

Together, the panels show why model and critic errors must both be considered, but they cannot be crossed or compared numerically: one is in reward units and the other is dimensionless. We did not measure critic error, target variance, or complete MVE target MSE, so this diagnostic does not locate a sweet spot. STEVE estimates target variance across horizons to set mixture weights; bias still needs separate scrutiny.

Now the regularizer. We train a three-member bootstrapped ensemble on the narrow data. Its next-state prediction spread is a heuristic for epistemic uncertainty. We divide position and velocity spread by fixed toy scales of 2 and 1 before taking a root-mean-square, so the penalty is scalar and dimensionless. We do not assume that disagreement perfectly tracks error or that it must explode outside the data.

In[27]:
Code
ensemble = [
    train_world_model(narrow, seed=s, bootstrap=True) for s in (101, 102, 103)
]


def disagreement(models, s, a):
    """Dimensionless RMS of standardized next-state ensemble spread."""
    preds = torch.stack([m(s, a)[0] for m in models])
    spread = preds.std(dim=0, unbiased=False) / s.new_tensor([2.0, 1.0])
    return torch.sqrt((spread**2).mean(dim=-1))


@torch.no_grad()
def trajectory_disagreement(actor, s0, models, horizon=EVAL_HORIZON):
    """Mean ensemble disagreement along the policy's closed-loop real trajectory."""
    s = s0.clone()
    readings = []
    for _ in range(horizon):
        a = actor(s)
        readings.append(disagreement(models, s, a).mean().item())
        s = torch.stack(
            [s[:, 0] + DT * s[:, 1], DRAG * s[:, 1] + DT * a[:, 0]], dim=1
        )
    return float(np.mean(readings))
In[28]:
Code
penalties = [0.0, 1.0, 5.0, 20.0]
penalty_return, penalty_disagreement = [], []
for p in penalties:
    out = train_imagination(
        model_narrow,
        seed=0,
        horizon=30,
        iterations=400,
        eta=0.0,
        uncertainty=lambda s, a: disagreement(ensemble, s, a),
        penalty=p,
    )
    penalty_return.append(true_return(out["actor"], eval_states))
    penalty_disagreement.append(
        trajectory_disagreement(out["actor"], eval_states, ensemble)
    )
Out[29]:
Visualization
Line chart shows real return changing as the uncertainty penalty increases.
Single-seed 40-step real return under increasing standardized ensemble penalty. Return improves modestly from about -51.3 at lambda = 0 to -49.5 at lambda = 20. This does not establish a general monotone benefit.
Line chart shows mean ensemble disagreement along the policy trajectory as the uncertainty penalty increases.
Mean standardized ensemble disagreement along the corresponding real trajectory falls slightly, from about 0.00349 to 0.00301. Disagreement is a proxy, not measured model error or a safety guarantee.

Figure 8a. In this run, real return improves modestly from approximately −51.3-51.3 with no penalty to −49.5-49.5 at λ=20\lambda=20.

Figure 8b. Standardized mean ensemble disagreement falls slightly, from approximately 0.003490.00349 to 0.003010.00301. This is not a direct measurement of real model error.

The left panel plots real return and the right panel plots disagreement. Both changes are modest for this seed: stronger penalty correlates with slightly better task return and slightly lower ensemble spread. The plot does not establish causality outside the specified training protocol or prove that the goal is unreachable under pessimism.

The lesson is narrower than either "pessimism always hurts" or "pessimism fixes exploitation." The penalty changes this actor's behavior enough to improve one real evaluation, but the ensemble score is not calibrated against transition error. A different seed, penalty scale, or misspecified ensemble could reverse the result. Closed-loop return and uncertainty diagnostics must be reported together.

Uncertainty penalties cannot create missing evidence. When interaction is available, targeted data collection can test the model in weakly covered regions. Choosing actions that improve both the task and what the agent knows is the subject of Active Perception, Dual Control, and Exploration.

For completeness, we compare score-function and pathwise actor updates on Model B under the same truncated discounted reward objective, seed, horizon, batch size, and iteration budget. Its open-loop probe was better than Model A's, but that does not guarantee accuracy on every visited state. One seed can illustrate behavior, not establish an estimator ranking.

In[30]:
Code
score_fn = train_imagination(
    model_broad,
    seed=3,
    horizon=30,
    iterations=400,
    eta=0.0,
    eval_states=eval_states,
)
pathwise = train_imagination(
    model_broad,
    seed=3,
    horizon=30,
    iterations=400,
    eta=0.0,
    pathwise=True,
    eval_states=eval_states,
)

comparison = {
    "score-function": true_return(score_fn["actor"], eval_states),
    "pathwise": true_return(pathwise["actor"], eval_states),
}
Out[31]:
Console
  score-function: real return -107.946
        pathwise: real return -46.632

Imagination gap at the end of training
 Model A: imagined -47.678 | real -51.259 | gap   3.581
 Model B: imagined -47.239 | real -47.143 | gap  -0.096

With seed 3, the pathwise policy reaches about −46.6-46.6 real return after 400 iterations while the score-function policy reaches about −107.9-107.9. This is a result of this configuration, not evidence that pathwise updates are always faster or safer. The actor losses are aligned on the same truncated objective; their gradient estimators and resulting optimization paths differ.

We have not run the corresponding estimator comparison on Model A, so we should not predict its outcome. To compare estimators more generally, vary actor seeds, inspect complete learning curves, and measure model error on the trajectories each estimator induces. Otherwise optimization and model mismatch remain entangled.

Limitations and Impact

Learning a policy from imagined experience can move model computation out of the per-action control loop. Its value depends on the quality of the learned model, the policy update, and how performance is checked in the environment.

The Dreamer family is a clear example of latent imagination used to train behavior. MuZero and TD-MPC use learned models differently: they retain decision-time search or trajectory optimization. These lineages are evidence for several ways a model can improve control, not evidence that all successful model-based agents discard their planner. A reactive policy can be useful when a model is too costly to query on every control step, but training on many rollouts does not make it independent of model accuracy.

A policy trained from many starts may average some zero-mean sampling noise. It can also amplify a systematic optimistic error because the optimizer favors actions that exploit it. Online planners likewise evaluate many trajectories and often replan from new observations. The useful distinction is computational timing and the policy class learned, not an automatic robustness advantage for either family.

The central limitation is objective mismatch: the actor is trained under the model but judged in the environment. The uniform bound above covers even a model-selected policy, yet can be too loose to certify it. More useful warnings include:

  • Imagined return improves while matched real-environment return stagnates or worsens.
  • Actions or visited states depart from the model's training distribution.
  • Multi-step prediction or reward error grows on states induced by the current policy.

These warnings are neither necessary nor sufficient. Measuring real return requires closed-loop environment rollouts; a held-out list of starting states alone cannot supply it.

An optimistic reward head can make an overshoot look cheap, as in the toy probe. Other models may be pessimistic or may fail through inaccurate transitions rather than large actions. Inspecting actual states, actions, and errors is more informative than inferring a mechanism from an imagined-return curve alone.

Each remedy changes a different part of the problem:

  • Short horizons limit compounding steps but can lose delayed rewards; the observed sweep is nonmonotone.
  • Ensemble penalties discourage estimated uncertainty but can miss shared model error; the observed penalty sweep improves return modestly for one seed.
  • Behavior penalties discourage unsupported actions but neither guarantee safety nor impose a fixed performance ceiling.
  • New real interaction can expose errors on visited states, at an environment-sample cost, when online data collection is allowed.

None of these interventions supplies a universal safety bound by itself. A finite penalty may be overcome by reward scale; a short rollout may still cross a bad one-step error; new data may not repair model misspecification. They are controls to test against the intended task, not certificates.

The imagination gap reflects both the model's error along a policy's trajectory and the policy found by optimization. Stronger optimization can discover optimistic mistakes, but it can also find actions that work better in the environment; the gap need not grow monotonically with iteration count, network size, or entropy changes. Model quality and optimizer settings must be evaluated together.

It is possible for a better solution to the imagined objective to perform worse in reality. That possibility is enough to require real-environment evaluation; it does not make stronger optimization inherently harmful. Report matched imagined and real returns, the training budget, and the states and actions where they diverge.

The practical takeaways are unglamorous and reliable:

  • Measure the gap.
  • Evaluate in the closed loop, not open loop, because open-loop prediction accuracy and closed-loop decision usefulness are different properties, as the coverage experiment showed.
  • Sweep rollout horizons rather than assume shorter is always better.
  • Keep some real data flowing.
  • Treat every regularizer as a constraint to verify empirically rather than assume it helps.

The worked example supports a narrower conclusion. Model A has sparser goal coverage and worse open-loop error on the chosen probe. With bounded actions and the stated seed, it overshoots more and has a modest optimistic return gap; across three seeds, results vary. The horizon sweep is nonmonotone, and the penalty sweep improves one run modestly. These observations show why model diagnostics, policy rollouts, and sensitivity checks must be reported together.

Summary

Learning policies in imagination converts a world model into a controller without planning at deployment time. The key ideas:

  • Latent imagination rolls a learned transition under the policy without decoding every predicted observation. This can reduce compute, but the learned representation and reward head still need validation.
  • Actor-critic learning inside the model can use λ\lambda-returns for critic targets and score-function or pathwise actor updates. The exact likelihood-ratio identity uses sampled return-to-go and discount weights; bootstrapped λ\lambda advantages can be biased with an approximate critic. Pathwise updates use model derivatives and can be efficient on smooth, reliable models. Actor updates here do not optimize model parameters.
  • Value expansion builds targets of the form ∑i<Hγir^i+γHvξ(s^H)\sum_{i<H}\gamma^i \hat r_i + \gamma^H v_\xi(\hat s_H) by rolling the model forward from real states. The horizon trades model bias against reliance on the learned value function, whose weight decays as γH\gamma^H.
  • Synthetic experience adds short model-generated branches from real replay states. Branching limits consecutive model steps but does not guarantee that the resulting distribution stays close to real data.
  • Model exploitation remains a risk when a policy selects optimistic errors. The uniform infinite-horizon bound applies even to a model-selected policy but can be loose; average test error is not a substitute for checking policy-induced trajectories. The imagination gap can have either sign.
  • Uncertainty penalties may help or hurt depending on calibration, reward scale, and task. In this toy run a stronger standardized disagreement penalty modestly improves real return. Missing coverage still motivates the targeted data collection developed in the next chapter.

Quiz

Ready to test your understanding? Take this quick quiz to reinforce what you've learned about policies learned in imagination.

Policies Learned in Imagination

Question 1 of 80 of 8 completed
According to the amortization bargain, how is world-model computation shifted between training and deployment?

Comments

No comments yet. Be the first to share your thoughts!

Reference

Citation details

Cite or share this article.

BIBTEXAcademic
@misc{brenndoerfer2026policieslearned, author = {Michael Brenndoerfer}, title = {Policies Learned in Imagination}, year = {2026}, url = {https://mbrenndoerfer.com/writing/policies-learned-in-imagination-world-models}, organization = {mbrenndoerfer.com}, note = {Accessed: 2026-09-27} }
APAAcademic
Michael Brenndoerfer (2026). Policies Learned in Imagination. Retrieved from https://mbrenndoerfer.com/writing/policies-learned-in-imagination-world-models
MLAAcademic
Michael Brenndoerfer. "Policies Learned in Imagination." 2026. Web. September 27, 2026. <https://mbrenndoerfer.com/writing/policies-learned-in-imagination-world-models>.
CHICAGOAcademic
Michael Brenndoerfer. "Policies Learned in Imagination." Accessed September 27, 2026. https://mbrenndoerfer.com/writing/policies-learned-in-imagination-world-models.
HARVARDAcademic
Michael Brenndoerfer (2026) 'Policies Learned in Imagination'. Available at: https://mbrenndoerfer.com/writing/policies-learned-in-imagination-world-models (Accessed: September 27, 2026).
SimpleBasic
Michael Brenndoerfer (2026). Policies Learned in Imagination. https://mbrenndoerfer.com/writing/policies-learned-in-imagination-world-models

About the author

Continue with the full handbook

This chapter is part of World Models Handbook. Use the handbook page to browse the complete table of contents and continue reading in sequence.

Explore World Models Handbook
Newsletter

Stay up to date

Get articles, book updates, and news delivered to your inbox.

No spam, unsubscribe anytime.

or

Join the community

Sign in to remove popups, track your reading progress, and join the discussion.