Model-Based Reinforcement Learning › Sample Efficiency, Model Bias, and Model Exploitation

Michael BrenndoerferJune 12, 202614 min read
World Models HandbookAll chapters
Part 2 of 12Inference, Decisions, and Control
Chapter 12Model-Based Reinforcement Learning › Sample Efficiency, Model Bias, and Model Exploitation
Reading section 4 of 11 · Sample Efficiency, Model Bias, and Model Exploitation · 14 minSection 4 of 11 · 14 min

Book contents

Section 4 of 11 · 14 min read

Model-Based Reinforcement Learning › Sample Efficiency, Model Bias, and Model ExploitationOne section · Sections in this chapter4 / 11 ↓
Reading tools Definitions & inline links

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

This section covers the central tradeoff of the chapter. Models buy sample efficiency, and they charge for it in bias. The two subsections that follow give each side its due, first the mechanisms by which models reduce the demand for real data, then the quantitative ways in which model error enters and accumulates. By the end, you should be able to identify the controlling tradeoffs and design evaluations that reveal whether a model-based system helps on a particular problem.

Why Models Improve Sample Efficiency

It is worth being precise about where the efficiency comes from, because "the model lets you imagine" is only part of the story. There are at least four distinct sources, and they interact:

  • Compression. A suitable parametric model can share structure across states rather than learn each tabular state-action pair independently. This statistical advantage depends on whether the hypothesis class captures structure that actually transfers.
  • Re-use and re-weighting. Both model-free replay and model-based training can revisit real transitions many times. A model adds structured branching: it can propose continuations and reweight where computation is spent.
  • Off-policy imagination. A generalized model can evaluate actions absent from a particular trajectory, but reliable counterfactual prediction still requires action coverage or defensible structural assumptions. State coverage alone is not enough.
  • Auxiliary predictive signal. Predicting observations or dynamics provides dense self-supervised targets even when reward is sparse. A learned reward model does not by itself densify sparse reward labels; that requires shaping, auxiliary objectives, or other added structure.

These potential benefits do not require long-horizon rollouts. A system may use a model only for short branching, auxiliary prediction, or one-step backups.

Compounding Rollout Error

Suppose the true and learned transition maps start from the same state, so e0=0e_0=0, and are evaluated under the same actions. Assume the learned map has uniform one-step error at most ε\varepsilon on the relevant region and the true transition map is LL-Lipschitz in state. If ehe_h is the state error after hh modeled transitions, then

eh+1≤Leh+ε,eH≤ε∑k=0H−1Lk={εLH−1L−1,L≠1,Hε,L=1.e_{h+1} \le L e_h + \varepsilon, \qquad e_H \le \varepsilon\sum_{k=0}^{H-1}L^k = \begin{cases} \varepsilon\dfrac{L^H-1}{L-1}, & L\ne 1,\\[6pt] H\varepsilon, & L=1. \end{cases}

An error injected kk transitions before the end is multiplied by at most LkL^k. The regimes differ: the bound stays finite as HH grows when L<1L<1, grows linearly when L=1L=1, and grows exponentially only when L>1L>1.

The bound is easiest to internalize as a curve. Fix a one-step error of ε=0.01\varepsilon = 0.01, a deliberately small value that would look excellent on any one-step benchmark, and plot the worst-case rollout error against horizon for a few values of the Lipschitz constant LL:

In[3]:
Code
import numpy as np

EPSILON = 0.01
HORIZONS = np.arange(1, 51)
LIPSCHITZ_VALUES = [0.8, 1.0, 1.2]


def rollout_error_bound(L, horizons, epsilon=EPSILON):
    if np.isclose(L, 1.0):
        return epsilon * horizons
    return epsilon * (L**horizons - 1.0) / (L - 1.0)


bound_curves = {L: rollout_error_bound(L, HORIZONS) for L in LIPSCHITZ_VALUES}
Out[4]:
Visualization
Three state-error bounds: a saturating curve for L 0.8, a linear curve for L 1, and a steep exponential curve for L 1.2.
Worst-case open-loop state-error bound against horizon with one-step error 0.01. Contractive dynamics (L = 0.8) approach a finite bound, L = 1 grows linearly, and expansive dynamics (L = 1.2) grow exponentially.

The plot does not say that every rollout diverges. It isolates how transition sensitivity and repeated one-step error interact under explicit assumptions. Short rollouts, replanning, and value bootstrapping reduce exposure to the expansive regime.

Discounting supplies a separate amplification factor. If εB\varepsilon_B is a uniform one-step Bellman-operator error, the induced fixed-policy value error is bounded on the order of εB/(1−γ)\varepsilon_B/(1-\gamma). That statement does not follow from an unspecified transition prediction error. Simulation lemmas based on reward error and transition-kernel error usually contain a reward term proportional to (1−γ)−1(1-\gamma)^{-1} and a transition term proportional to (1−γ)−2(1-\gamma)^{-2}, with constants determined by reward bounds, the norm convention, and policy selection.

The amplification factor 1/(1−γ)1/(1-\gamma) is worth seeing as a curve rather than a formula, because its growth is not gentle:

In[5]:
Code
import numpy as np

GAMMA_GRID = np.linspace(0.50, 0.999, 300)
amplification = 1.0 / (1.0 - GAMMA_GRID)
gamma_marks = np.array([0.9, 0.99, 0.999])
mark_amplification = 1.0 / (1.0 - gamma_marks)
Out[6]:
Visualization
Rising Bellman-error amplification curve with markers at factors 10, 100, and 1000.
Amplification factor 1/(1-gamma) for a uniform Bellman-backup error, with markers at gamma = 0.9, 0.99, and 0.999. A fixed value-error budget therefore permits ten times less backup error at each successive marker.

The markers make the arithmetic concrete: moving from γ=0.9\gamma=0.9 to 0.990.99 multiplies a fixed Bellman error by ten, so a fixed value-error budget permits ten times less one-step backup error. Moving to 0.9990.999 tightens the budget by another factor of ten.

Let's make compounding concrete with a small experiment. We take a damped pendulum, fit two models to a few thousand random-policy transitions, a linear model that is structurally misspecified for the nonlinear dynamics and a more flexible small neural network, and compare their one-step error against their open-loop rollout error. The experiment measures the resulting errors directly; it does not separately identify approximation bias, estimation error, and recursive feedback.

In[7]:
Code
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.neural_network import MLPRegressor

rng = np.random.default_rng(0)

DT = 0.1


def pendulum_next(s, a):
    """Deterministic damped pendulum: state is (angle, angular velocity)."""
    theta, omega = s[0], s[1]
    return np.array(
        [
            theta + DT * omega,
            omega + DT * (-np.sin(theta) - 0.1 * omega + a),
        ]
    )


rng = np.random.default_rng(0)


def collect_transitions(n_traj, horizon):
    S, A, S2 = [], [], []
    for _ in range(n_traj):
        s = np.array([rng.uniform(-np.pi, np.pi), rng.uniform(-2.0, 2.0)])
        for _ in range(horizon):
            a = rng.uniform(-2.0, 2.0)
            S.append(s)
            A.append(a)
            S2.append(pendulum_next(s, a))
            s = S2[-1]
    return np.array(S), np.array(A), np.array(S2)


S, A, S2 = collect_transitions(100, 20)  # 2000 random-policy transitions
X = np.hstack([S, A[:, None]])
lin = LinearRegression().fit(X, S2)
mlp = MLPRegressor(
    hidden_layer_sizes=(64, 64), max_iter=5000, random_state=0
).fit(X, S2)

The raw linear model cannot represent the sin⁡(θ)\sin(\theta) term exactly. The neural network is more flexible, but capacity alone does not guarantee lower held-out error. We therefore evaluate both models on exactly the same held-out initial states and action sequences.

In[8]:
Code
eval_rng = np.random.default_rng(2026)


def predict_linear(s, a):
    return lin.predict(np.append(s, a)[None, :])[0]


def predict_mlp(s, a):
    return mlp.predict(np.append(s, a)[None, :])[0]


N_TEST_TRAJ, TEST_HORIZON = 50, 30
test_initial_states = np.column_stack(
    [
        eval_rng.uniform(-np.pi, np.pi, size=N_TEST_TRAJ),
        eval_rng.uniform(-2.0, 2.0, size=N_TEST_TRAJ),
    ]
)
test_actions = eval_rng.uniform(-2.0, 2.0, size=(N_TEST_TRAJ, TEST_HORIZON))


def evaluate_model(predict):
    n_traj, horizon = test_actions.shape
    onestep_err = np.zeros(horizon)
    rollout_err = np.zeros(horizon)
    for initial_state, actions in zip(test_initial_states, test_actions):
        s_true = initial_state.copy()
        s_model = s_true.copy()
        for t in range(horizon):
            a = actions[t]
            s_true_next = pendulum_next(s_true, a)
            onestep_err[t] += np.mean((s_true_next - predict(s_true, a)) ** 2)
            rollout_err[t] += np.mean((s_true_next - predict(s_model, a)) ** 2)
            s_true, s_model = s_true_next, predict(s_model, a)
    return onestep_err / n_traj, rollout_err / n_traj


err_lin_onestep, err_lin_rollout = evaluate_model(predict_linear)
err_mlp_onestep, err_mlp_rollout = evaluate_model(predict_mlp)
horizons = np.arange(1, TEST_HORIZON + 1)

Both models see the same held-out trajectories. One-step error always starts from the true state; rollout error feeds each model's prediction back as its next input.

Out[9]:
Console
Linear model  one-step MSE (steps 1-5): [0.0014 0.0013 0.0013 0.0012 0.0011]
MLP model     one-step MSE (steps 1-5): [0.0015 0.0014 0.0011 0.0013 0.0016]
Linear model  rollout MSE  at step 30:  1.234
MLP model     rollout MSE  at step 30:  1.016
Out[10]:
Visualization
Two similar-scale one-step error curves evaluated on identical trajectories.
Paired held-out one-step MSE for the linear and neural pendulum models. Their errors are of the same order, with no consistent winner over the first five steps.
Two rising rollout-error curves on a log scale, with the neural curve lower at long horizons.
Paired held-out open-loop rollout MSE. Error grows for both models, while the neural model has lower error by step 30 despite its weaker one-step result.

The panels support a narrower and more useful conclusion. On these paired trajectories, the two models have one-step errors of the same order, with no consistent winner over the first five steps. By step 30 the neural model has the lower rollout error. One-step ranking therefore does not determine long-horizon ranking, and recursive use must be evaluated directly. A trained policy would induce another test distribution, so these random-action results should not be generalized beyond the displayed experiment.

Model Exploitation and Distribution Shift

Compounding error degrades rollouts passively. A nastier failure mode is active: the decision machinery seeks out the model's errors.

Model exploitation

Model exploitation occurs when optimization favors trajectories that look good under the learned model because of model error, for example an overestimated reward or implausibly convenient dynamics. Greater search pressure can increase this failure, but optimizer choice alone does not determine it.

The interaction is between optimization and distribution shift. A planner may steer toward unfamiliar states or actions where the model is unreliable; those regions need not be the true high-reward regions. If optimistic errors dominate there, additional planning can worsen real performance even while imagined return improves.

One common defense is model uncertainty. Bootstrap ensembles often provide a useful proxy for epistemic uncertainty. Disagreement can expose sensitivity to finite data, but it can miss shared model-class bias and is not automatically calibrated.

To see both the value and the limitation, fit quadratic models to bootstrap resamples of noisy sine data. The members share the same misspecified feature class, so their spread measures resampling sensitivity within that class, not total predictive uncertainty.

In[11]:
Code
import numpy as np
from sklearn.linear_model import LinearRegression

rng = np.random.default_rng(7)
N_ENSEMBLE = 20


def make_features(x):
    return np.column_stack([np.ones_like(x), x, x**2])


x_train = rng.uniform(-1.0, 1.0, size=60)
y_train = np.sin(2.0 * np.pi * x_train) + rng.normal(0.0, 0.1, size=60)
F_train = make_features(x_train)

x_eval = np.linspace(-1.6, 1.6, 200)
F_eval = make_features(x_eval)

ensemble_preds = np.zeros((N_ENSEMBLE, len(x_eval)))
for m in range(N_ENSEMBLE):
    idx = rng.integers(0, len(x_train), size=len(x_train))
    coef, *_ = np.linalg.lstsq(F_train[idx], y_train[idx], rcond=None)
    ensemble_preds[m] = F_eval @ coef

pred_mean = ensemble_preds.mean(axis=0)
pred_std = ensemble_preds.std(axis=0)
true_curve = np.sin(2.0 * np.pi * x_eval)
covered = (x_eval >= -1.0) & (x_eval <= 1.0)
Out[12]:
Visualization
True sine curve, quadratic ensemble mean, and a widening bootstrap spread that does not cover all shared bias.
Quadratic bootstrap-ensemble mean and two-standard-deviation spread for noisy sine data observed only on [-1, 1]. Spread widens outside the data range, yet the ensemble can agree while sharing substantial misspecification inside it.

The widening band outside [−1,1][-1,1] is a useful warning about extrapolation. The dashed truth also exposes the limitation: a thin band is not a certificate of correctness when all members share a misspecified quadratic class. An uncertainty penalty or rollout truncation can still be useful, but it should be calibrated and checked against control-relevant held-out data.

PETS averages over ensemble rollouts in its planner; many other methods add an uncertainty penalty directly to the objective. Other common defenses include:

  • Short rollouts and branching. Generate imagined data only a few steps from real states, then bootstrap with the value function. This bounds compounding by construction: every imagined trajectory starts from ground truth and stays short. This is MBPO's core insight and, as we saw, it is also implicit in MPC's re-planning.
  • Pessimism. One common implementation subtracts an uncertainty estimate from imagined reward so that unfamiliar, possibly-wrong regions look bad rather than promising. Other implementations use lower-confidence values, robust transition sets, constraints, or worst-case objectives. These constructions connect to the same pessimism principle used in offline RL.
  • Model trust diagnostics. Before letting the agent act on a model, test it the way the qualification test from Part I: The World-Model Idea suggested: not only on held-out data, but on the distribution the policy will induce, and at the rollout lengths the decision machinery will use. A model validated only on its training distribution has not been validated at all, as far as the decision machinery is concerned.

Planner error and model error are distinct. A precise optimizer can expose optimistic model errors, while an approximate optimizer can simply be suboptimal. Robust objectives, constraints, uncertainty penalties, and real-environment validation are more principled controls than assuming that fewer optimizer iterations always make an uncertain model safer.