Skip to content
AI360Xpert
Beta

MuZero and AlphaZero

AlphaZero mastered chess and Go using a perfect simulator, but MuZero eliminates the simulator entirely—learning an internal latent world model that plans by predicting only value, policy, and reward.

MuZero combines Monte Carlo Tree Search with learned representation, dynamics, and prediction neural networks, planning entirely in latent space without a ground-truth simulator.
MuZero combines Monte Carlo Tree Search with learned representation, dynamics, and prediction neural networks, planning entirely in latent space without a ground-truth simulator.

Why Does This Exist?

In 2017, DeepMind introduced AlphaZero, achieving superhuman mastery across Chess, Shogi, and Go using a tabula rasa combination of deep neural networks and Monte Carlo Tree Search (MCTS). However, AlphaZero suffered from a critical limitation: it relied on a perfect, handcrafted, external simulator p(s′∣s,a)p(s' \mid s, a). At every node expansion in the search tree, the algorithm asked the ground-truth game engine: "If I play move aa from board ss, what is the exact legal next board state s′s'?"

In real-world reinforcement learning—such as robotics, autonomous vehicles, visual video games, or financial forecasting—a perfect forward simulator does not exist. The dynamics are complex, noisy, or unknown.

Early model-based reinforcement learning methods attempted to overcome this by building world models that reconstructed raw observations (e.g., predicting future video frames pixel-by-pixel). This proved inefficient and fragile: neural networks wasted vast capacity trying to reproduce visually intricate but task-irrelevant details (such as fluttering leaves or flickering background score counters) while suffering from compounding prediction drift.

MuZero (Schrittwieser et al., 2020) resolved this bottleneck with a fundamental conceptual breakthrough: an agent does not need to reconstruct the world to plan effectively—it only needs to model what directly impacts its decisions. Instead of predicting raw observation transitions, MuZero trains deep neural networks to predict only three decision-critical quantities: the policy p\mathbf{p}, the value vv, and the immediate reward rr. By executing MCTS purely inside an abstract, learned latent state space, MuZero matched AlphaZero in Chess and Go while simultaneously setting state-of-the-art benchmark records across visually rich Atari 2600 games without ever knowing the rules of the environment.

Think of It Like This

Navigating an Unfamiliar Maze in the Dark

Imagine two people attempting to navigate a complex, hazardous labyrinth in complete darkness:

AlphaZero is an explorer who carries a high-definition architectural blueprint and a mechanical rulebook of every door and latch in the labyrinth. Before taking a step, they inspect the blueprint, test every hallway mathematically, calculate every branch, and pick the optimal turn. But the moment you take away the blueprint—or place them in an unmapped cave—AlphaZero is paralyzed and cannot make a single plan.

MuZero is a blindfolded martial artist equipped with a tactile cane. They carry no map and do not know the layout of the labyrinth. They do not attempt to paint a mental 3D picture of the stone textures, wall carvings, or ceiling cobwebs. Instead, as they explore, they tap their cane and track three vital, task-focused sensations:

  1. "Which directions feel open to step?" (the policy p\mathbf{p})
  2. "Did that step yield a gold coin or trigger a spike trap?" (the immediate reward rr)
  3. "Does this hallway feel closer to the sunlight or deeper into danger?" (the value vv)

By linking these tactile memories together, MuZero builds an internal mental simulator. In a split second, it can mentally simulate stepping three paces forward, turning left, and anticipating a reward—planning entirely inside its mind without ever seeing a single physical wall.

Where the analogy stops: A human's intuition is constrained by 3D physical spatial geometry. MuZero's internal hidden state sks^k is a high-dimensional abstract vector completely untethered from physical dimensions, shaped exclusively by gradient descent to optimize decision-making.

How It Actually Works

From AlphaZero to MuZero: The Simulator Bottleneck

AlphaZero combines a dual-head deep neural network fθ(s)=(p,v)f_\theta(s) = (\mathbf{p}, v) with Monte Carlo Tree Search. During MCTS, nodes represent ground-truth environment states ss, and directed edges represent actions aa.

At each state ss, actions are selected using the Predictor Upper Confidence Bound applied to Trees (PUCT) formula:

at=arg⁡max⁡a[Q(s,a)+cpuct⋅P(s,a)⋅∑bN(s,b)1+N(s,a)]a_t = \arg\max_a \left[ Q(s, a) + c_{\text{puct}} \cdot P(s, a) \cdot \frac{\sqrt{\sum_b N(s, b)}}{1 + N(s, a)} \right]

where:

  • Q(s,a)Q(s, a) is the running mean action-value of the edge.
  • P(s,a)P(s, a) is the prior probability of selecting action aa, supplied by the policy head of fθ(s)f_\theta(s).
  • N(s,a)N(s, a) is the number of times action aa has been traversed from node ss.
  • ∑bN(s,b)\sum_b N(s, b) is the total visit count of parent state ss.
  • cpuctc_{\text{puct}} is an exploration parameter balancing exploitation of high-QQ branches against exploration of low-visit branches.

Once a leaf node is reached, AlphaZero invokes the exact environment rules engine: s′=env.step(s,a)s' = \text{env}.\text{step}(s, a) to instantiate the child state, evaluates s′s' using fθ(s′)f_\theta(s'), and backs up the predicted value vv along the search path.

The MuZero Triplet: Representation, Dynamics, and Prediction

MuZero removes the environment simulator by parameterizing the world model through three neural network functions:

Observation History (o₁...o_t)        │        ▼┌───────────────────────────────┐│ Representation Function h_θ   │  ──>  s⁰ (Initial Latent State)└───────────────────────────────┘        │        ├──────────────────────────────────────┐        ▼                                      ▼┌───────────────────────────────┐      ┌───────────────────────────────┐│ Dynamics Function g_θ         │      │ Prediction Function f_θ       ││ (s^{k-1}, a^k) ──> (r^k, s^k) │      │ s^k ──> (p^k, v^k)            │└───────────────────────────────┘      └───────────────────────────────┘
  1. Representation Function (hθh_\theta): s0=hθ(o1,o2,…,ot)s^0 = h_\theta(o_1, o_2, \dots, o_t) Encodes the historical sequence of past observations into an initial abstract hidden state s0s^0. In visual Atari tasks, hθh_\theta is a convolutional network (CNN) or ResNet processing stacked image frames.

  2. Dynamics Function (gθg_\theta): (rk,sk)=gθ(sk−1,ak)(r^k, s^k) = g_\theta(s^{k-1}, a^k) Acts as the internal, learned simulator. Given the previous hidden state sk−1s^{k-1} and candidate action aka^k, it recurrently outputs the predicted next hidden state sks^k and the immediate scalar reward rkr^k. Note that sks^k does not have any semantic obligation to resemble a decoded image; it is purely an abstract computational substrate.

  3. Prediction Function (fθf_\theta): (pk,vk)=fθ(sk)(\mathbf{p}^k, v^k) = f_\theta(s^k) Evaluates any hidden state sks^k generated during tree search, producing:

    • Policy distribution pk\mathbf{p}^k: a probability vector over all legal actions.
    • Value estimate vkv^k: the expected cumulative discounted future return from state sks^k.

Latent MCTS: Planning Without Ground Truth

During inference and acting, MuZero runs MCTS entirely in hidden state space across four distinct phases:

  1. Selection: Starting at root node s0s^0, the agent recursively traverses edges choosing action aka^k that maximizes the PUCT objective until reaching an unexpanded edge. To stabilize search across games with varied reward scales, MuZero normalizes QQ-values into [0,1][0, 1] using min-max tracking: Qˉ(s,a)=Q(s,a)−Qmin⁡Qmax⁡−Qmin⁡\bar{Q}(s, a) = \frac{Q(s, a) - Q_{\min}}{Q_{\max} - Q_{\min}}
  2. Expansion: The selected action aka^k and parent state sk−1s^{k-1} are fed into the learned dynamics function: (rk,sk)=gθ(sk−1,ak)(r^k, s^k) = g_\theta(s^{k-1}, a^k) creating a new child node with hidden state sks^k and edge reward rkr^k.
  3. Evaluation: The newly created state sks^k is passed through the prediction network: (pk,vk)=fθ(sk)(\mathbf{p}^k, v^k) = f_\theta(s^k) storing prior probabilities pk\mathbf{p}^k on outgoing edges.
  4. Backup: The leaf value vkv^k is discounted and propagated back up the search path. For a trajectory of depth dd, the mm-step return backed up to edge (sm−1,am)(s^{m-1}, a^m) is: Gm=∑τ=0d−m−1γτrm+τ+1+γd−mvkG^m = \sum_{\tau=0}^{d-m-1} \gamma^\tau r^{m+\tau+1} + \gamma^{d-m} v^k Edge statistics are updated: N(sm−1,am)←N(sm−1,am)+1N(s^{m-1}, a^m) \leftarrow N(s^{m-1}, a^m) + 1 Q(sm−1,am)←N(sm−1,am)⋅Q(sm−1,am)+GmN(sm−1,am)+1Q(s^{m-1}, a^m) \leftarrow \frac{N(s^{m-1}, a^m) \cdot Q(s^{m-1}, a^m) + G^m}{N(s^{m-1}, a^m) + 1}

Once search concludes (e.g., after 50–800 simulations), an action ata_t is selected in the real environment proportionally to visit counts: πt(a)=N(s0,a)1/T∑bN(s0,b)1/T\pi_t(a) = \frac{N(s^0, a)^{1/T}}{\sum_b N(s^0, b)^{1/T}} where TT is a temperature parameter (T=1T=1 for exploratory self-play, T→0T \to 0 for competitive deployment).

End-to-End Joint Loss Without Observation Reconstruction

MuZero trains all three networks (hθ,gθ,fθh_\theta, g_\theta, f_\theta) end-to-end via gradient descent. Trajectories are sampled from a replay buffer, and the model is unrolled for KK hypothetical simulation steps (K=5K=5 typically):

L(θ)=∑k=0K[ℓp(πt+k,ptk)+ℓv(zt+k,vtk)]+∑k=1Kℓr(ut+k,rtk)+c∥θ∥2\mathcal{L}(\theta) = \sum_{k=0}^K \left[ \ell_p(\pi_{t+k}, \mathbf{p}_t^k) + \ell_v(z_{t+k}, v_t^k) \right] + \sum_{k=1}^K \ell_r(u_{t+k}, r_t^k) + c \|\theta\|^2

where:

  • ℓp(π,p)=−∑πlog⁡p\ell_p(\pi, \mathbf{p}) = -\sum \pi \log \mathbf{p} is the cross-entropy loss aligning the predicted policy with the MCTS visit distribution π\pi.
  • ℓv(z,v)\ell_v(z, v) is the loss between predicted value vtkv_t^k and target return zt+kz_{t+k} (computed from bootstrapped nn-step returns or final game outcomes).
  • ℓr(u,r)\ell_r(u, r) is the loss matching predicted reward rtkr_t^k to real observed reward ut+ku_{t+k}.
  • c∥θ∥2c \|\theta\|^2 is L2L_2 weight regularization.

Because gradients flow from ℓp,ℓv,\ell_p, \ell_v, and ℓr\ell_r backward through the dynamics function gθg_\theta and representation function hθh_\theta, the hidden states are forced to capture all information necessary to predict value, policy, and rewards—and strictly nothing else.

Worked numerical example

Let us trace a concrete single-step MCTS iteration in latent state space (k=1k=1) with exploration parameter cpuct=1.0c_{\text{puct}} = 1.0 and discount γ=0.9\gamma = 0.9.

Initial Root State Setup

  • Initial root hidden state: s0=[0.8,−0.4]s^0 = [0.8, -0.4]
  • Root prediction: fθ(s0)→p0={a1:0.7, a2:0.3}f_\theta(s^0) \to \mathbf{p}^0 = \{a_1: 0.7,\, a_2: 0.3\}, v0=1.5v^0 = 1.5
  • Current tree edge visit counts:
    • N(s0,a1)=3N(s^0, a_1) = 3
    • N(s0,a2)=1N(s^0, a_2) = 1
    • Total parent visits: ∑bN(s0,b)=3+1=4\sum_b N(s^0, b) = 3 + 1 = 4
  • Current edge action-values:
    • Q(s0,a1)=1.2Q(s^0, a_1) = 1.2
    • Q(s0,a2)=0.8Q(s^0, a_2) = 0.8

Step 1: Compute PUCT Exploration Scores

For Action a1a_1: U(s0,a1)=cpuct⋅P(s0,a1)⋅∑bN(s0,b)1+N(s0,a1)=1.0×0.7×41+3=0.7×24=0.3500U(s^0, a_1) = c_{\text{puct}} \cdot P(s^0, a_1) \cdot \frac{\sqrt{\sum_b N(s^0, b)}}{1 + N(s^0, a_1)} = 1.0 \times 0.7 \times \frac{\sqrt{4}}{1 + 3} = 0.7 \times \frac{2}{4} = 0.3500 Score(s0,a1)=Q(s0,a1)+U(s0,a1)=1.2+0.3500=1.5500\text{Score}(s^0, a_1) = Q(s^0, a_1) + U(s^0, a_1) = 1.2 + 0.3500 = 1.5500

For Action a2a_2: U(s0,a2)=cpuct⋅P(s0,a2)⋅∑bN(s0,b)1+N(s0,a2)=1.0×0.3×41+1=0.3×22=0.3000U(s^0, a_2) = c_{\text{puct}} \cdot P(s^0, a_2) \cdot \frac{\sqrt{\sum_b N(s^0, b)}}{1 + N(s^0, a_2)} = 1.0 \times 0.3 \times \frac{\sqrt{4}}{1 + 1} = 0.3 \times \frac{2}{2} = 0.3000 Score(s0,a2)=Q(s0,a2)+U(s0,a2)=0.8+0.3000=1.1000\text{Score}(s^0, a_2) = Q(s^0, a_2) + U(s^0, a_2) = 0.8 + 0.3000 = 1.1000

Step 2: Action Selection

Comparing the candidate PUCT scores: Score(s0,a1)=1.5500>1.1000=Score(s0,a2)\text{Score}(s^0, a_1) = 1.5500 > 1.1000 = \text{Score}(s^0, a_2) The agent selects action a1a_1.

Step 3: Latent Dynamics Expansion

The agent passes (s0,a1)(s^0, a_1) into the learned dynamics function: gθ(s0,a1)⟶s1=[0.9,−0.2],r1=0.5000g_\theta(s^0, a_1) \longrightarrow s^1 = [0.9, -0.2], \quad r^1 = 0.5000

Step 4: Latent Prediction Evaluation

The child hidden state s1s^1 is evaluated by the prediction network: fθ(s1)⟶p1={a1:0.6, a2:0.4},v1=2.0000f_\theta(s^1) \longrightarrow \mathbf{p}^1 = \{a_1: 0.6,\, a_2: 0.4\}, \quad v^1 = 2.0000

Step 5: Backpropagation Backup Update

The backup return for edge (s0,a1)(s^0, a_1) is computed using the immediate reward and discounted child value: Backup Return G=r1+γ⋅v1=0.5+0.9×2.0000=0.5+1.8000=2.3000\text{Backup Return } G = r^1 + \gamma \cdot v^1 = 0.5 + 0.9 \times 2.0000 = 0.5 + 1.8000 = 2.3000

Now update the statistics for edge (s0,a1)(s^0, a_1):

  • Previous total value: Total Valueold=N×Q=3×1.2=3.6000\text{Total Value}_{\text{old}} = N \times Q = 3 \times 1.2 = 3.6000
  • New visit count: Nnew(s0,a1)=3+1=4N_{\text{new}}(s^0, a_1) = 3 + 1 = 4
  • New total value: Total Valuenew=3.6000+2.3000=5.9000\text{Total Value}_{\text{new}} = 3.6000 + 2.3000 = 5.9000
  • New updated QQ-value: Qnew(s0,a1)=Total ValuenewNnew=5.90004=1.4750Q_{\text{new}}(s^0, a_1) = \frac{\text{Total Value}_{\text{new}}}{N_{\text{new}}} = \frac{5.9000}{4} = 1.4750

The edge action-value increases from 1.20001.2000 to 1.47501.4750, reflecting the promising simulated transition discovered in latent space.

Code

Below is a self-contained, type-hinted Python implementation of the core MuZero model architecture (hθ,gθ,fθh_\theta, g_\theta, f_\theta) and the latent MCTS node selection, expansion, and backpropagation backup:

from dataclasses import dataclass, fieldimport mathfrom typing import Dict, List, Tuple

@dataclassclass MCTSNode:    """Represents a node in MuZero's latent Monte Carlo search tree."""
    hidden_state: List[float]    prior_p: float = 0.0    visit_count: int = 0    total_value: float = 0.0    reward: float = 0.0    children: Dict[str, "MCTSNode"] = field(default_factory=dict)
    @property    def q_value(self) -> float:        if self.visit_count == 0:            return 0.0        return self.total_value / self.visit_count

class MuZeroModel:    """MuZero's three parameterized neural functions operating on latent states."""
    def h_representation(self, observations: List[float]) -> List[float]:        """s^0 = h_theta(o_1...o_t): Encodes observation history into initial latent state."""        # Maps input observation directly to initial abstract hidden state        return list(observations)
    def g_dynamics(        self, hidden_state: List[float], action: str    ) -> Tuple[List[float], float]:        """(s^k, r^k) = g_theta(s^{k-1}, a^k): Recurrently predicts next hidden state and reward."""        if action == "a_1":            # Latent transition for action a_1            return [0.9, -0.2], 0.5        else:            # Latent transition for action a_2            return [0.7, -0.6], 0.1
    def f_prediction(        self, hidden_state: List[float]    ) -> Tuple[Dict[str, float], float]:        """(p^k, v^k) = f_theta(s^k): Predicts policy probabilities and state value."""        if math.isclose(hidden_state[0], 0.8) and math.isclose(            hidden_state[1], -0.4        ):            return {"a_1": 0.7, "a_2": 0.3}, 1.5        elif math.isclose(hidden_state[0], 0.9) and math.isclose(            hidden_state[1], -0.2        ):            return {"a_1": 0.6, "a_2": 0.4}, 2.0        else:            return {"a_1": 0.5, "a_2": 0.5}, 1.0

class LatentMCTS:    """Monte Carlo Tree Search executed entirely within learned hidden state space."""
    def __init__(        self,        model: MuZeroModel,        c_puct: float = 1.0,        discount_gamma: float = 0.9,    ) -> None:        self.model = model        self.c_puct = c_puct        self.gamma = discount_gamma
    def calculate_puct(        self, parent_visits: int, child_q: float, child_p: float, child_n: int    ) -> Tuple[float, float]:        """Calculates exploration bonus U(s, a) and total PUCT score."""        u_score = (            self.c_puct            * child_p            * (math.sqrt(parent_visits) / (1.0 + child_n))        )        total_score = child_q + u_score        return u_score, total_score
    def backup(self, child_node: MCTSNode, parent_node: MCTSNode) -> float:        """Propagates predicted return back to parent edge statistics."""        backup_return = child_node.reward + self.gamma * child_node.total_value        parent_node.visit_count += 1        parent_node.total_value += backup_return        return backup_return

if __name__ == "__main__":    model = MuZeroModel()    mcts = LatentMCTS(model, c_puct=1.0, discount_gamma=0.9)
    # 1. Initialize Root State s^0    obs = [0.8, -0.4]    s0 = model.h_representation(obs)    prior_policies, root_value = model.f_prediction(s0)
    # Replicate edge statistics from worked example:    # N(s^0, a_1) = 3, Q(s^0, a_1) = 1.2 -> total_value = 3 * 1.2 = 3.6    # N(s^0, a_2) = 1, Q(s^0, a_2) = 0.8 -> total_value = 1 * 0.8 = 0.8    total_parent_visits = 4
    q_a1, p_a1, n_a1 = 1.2, prior_policies["a_1"], 3    q_a2, p_a2, n_a2 = 0.8, prior_policies["a_2"], 1
    u_a1, score_a1 = mcts.calculate_puct(total_parent_visits, q_a1, p_a1, n_a1)    u_a2, score_a2 = mcts.calculate_puct(total_parent_visits, q_a2, p_a2, n_a2)
    print("=== PUCT Edge Selection ===")    print(        f"Action a_1: U = {u_a1:.4f}, Total Score = {score_a1:.4f} (Q={q_a1}, P={p_a1})"    )    print(        f"Action a_2: U = {u_a2:.4f}, Total Score = {score_a2:.4f} (Q={q_a2}, P={p_a2})"    )
    # Numerical assertions    assert math.isclose(u_a1, 0.35, rel_tol=1e-5)    assert math.isclose(score_a1, 1.55, rel_tol=1e-5)    assert math.isclose(u_a2, 0.30, rel_tol=1e-5)    assert math.isclose(score_a2, 1.10, rel_tol=1e-5)
    # 2. Selection: Pick action with highest PUCT score    selected_action = "a_1" if score_a1 > score_a2 else "a_2"    print(f"\nSelected Action: {selected_action}")    assert selected_action == "a_1"
    # 3. Expansion: Step dynamics function g_theta in latent space    s1, r1 = model.g_dynamics(s0, selected_action)    print(f"\n=== Latent Dynamics Expansion (g_theta) ===")    print(f"Child Hidden State s^1: {s1}")    print(f"Predicted Reward r^1:   {r1:.4f}")    assert s1 == [0.9, -0.2]    assert math.isclose(r1, 0.5)
    # 4. Evaluation: Step prediction function f_theta    p1, v1 = model.f_prediction(s1)    print(f"\n=== Latent Prediction Evaluation (f_theta) ===")    print(f"Prior Policy p^1: {p1}")    print(f"Leaf Value v^1:   {v1:.4f}")    assert math.isclose(v1, 2.0)
    # 5. Backup: Propagate return to edge statistics    backup_return = r1 + mcts.gamma * v1    new_n_a1 = n_a1 + 1    new_total_val_a1 = (n_a1 * q_a1) + backup_return    new_q_a1 = new_total_val_a1 / new_n_a1
    print(f"\n=== Backpropagation Backup ===")    print(        f"Backup Return G = r^1 + gamma * v^1: {r1} + 0.9 * {v1} = {backup_return:.4f}"    )    print(f"Updated Visit Count N(s^0, a_1):     {new_n_a1}")    print(f"Updated Action-Value Q(s^0, a_1):    {new_q_a1:.4f}")
    assert new_n_a1 == 4    assert math.isclose(backup_return, 2.3)    assert math.isclose(new_q_a1, 1.475)

Expected output:

=== PUCT Edge Selection ===Action a_1: U = 0.3500, Total Score = 1.5500 (Q=1.2, P=0.7)Action a_2: U = 0.3000, Total Score = 1.1000 (Q=0.8, P=0.3)
Selected Action: a_1
=== Latent Dynamics Expansion (g_theta) ===Child Hidden State s^1: [0.9, -0.2]Predicted Reward r^1:   0.5000
=== Latent Prediction Evaluation (f_theta) ===Prior Policy p^1: {'a_1': 0.6, 'a_2': 0.4}Leaf Value v^1:   2.0000
=== Backpropagation Backup ===Backup Return G = r^1 + gamma * v^1: 0.5 + 0.9 * 2.0 = 2.3000Updated Visit Count N(s^0, a_1):     4Updated Action-Value Q(s^0, a_1):    1.4750

Watch Out For

Latent State Compounding Divergence and Inconsistent Scale

The Trap: Because MuZero unrolls its learned dynamics function gθg_\theta autoregressively in latent space without intermediate ground-truth observation grounding, tiny approximation errors accumulate along deep tree branches (k>5k > 5). If the scale of the hidden state vectors is unconstrained, activation magnitudes explode or contract, leading to latent state divergence. The prediction network fθf_\theta encounters out-of-distribution latent vectors, producing garbage policy priors and severely hallucinated value estimates that poison the entire MCTS search tree.

The Symptom: During training, MCTS visit distributions fail to concentrate on winning actions; search trees become uniformly flat or hyper-fixate on hallucinated dead ends. When deployed in complex environments with large reward ranges, tree values blow up and learning collapses.

The Fix:

  1. Hidden State Normalization: MuZero normalizes hidden state activations using min-max scaling to the interval [0,1][0, 1] before passing them to the next recurrent step: snormk=sk−min⁡(sk)max⁡(sk)−min⁡(sk)s^k_{\text{norm}} = \frac{s^k - \min(s^k)}{\max(s^k) - \min(s^k)}
  2. Min-Max QQ-Value Normalization in PUCT: Dynamically track the global minimum and maximum QQ-values observed across the entire tree (Qmin⁡,Qmax⁡Q_{\min}, Q_{\max}) and normalize all action-values to [0,1][0, 1] prior to computing PUCT scores.
  3. Bounded Unroll Horizon (K≤5K \le 5): Train the dynamics function gθg_\theta by unrolling only K=5K=5 hypothetical simulation steps during training, matching the empirical depth where gradient backpropagation remains numerically stable.

The Quick Version

  • Simulator-Free Planning: While AlphaZero requires an exact, handcrafted environment rules engine p(s′∣s,a)p(s' \mid s, a), MuZero plans inside unknown and visual environments by learning an internal latent simulator.
  • The Triplet Architecture: MuZero decomposes world modeling into three neural networks: representation s0=hθ(o)s^0 = h_\theta(o), dynamics (rk,sk)=gθ(sk−1,ak)(r^k, s^k) = g_\theta(s^{k-1}, a^k), and prediction (pk,vk)=fθ(sk)(\mathbf{p}^k, v^k) = f_\theta(s^k).
  • No Pixel Reconstruction: The model never reconstructs visual observations; gradients from policy, value, and reward targets shape hidden states to encode only decision-critical features.
  • Latent MCTS: Tree search is executed entirely within abstract hidden state space, using min-max normalized PUCT selection and backup returns to deliver superhuman performance across board games and complex Atari environments.