xwm.heads¶
Prediction heads: categorical reward and value, pessimistic Q-ensembles, squashed-Gaussian policies, and the two-hot/symlog machinery they share.
Prediction heads: reward, value, policy, Q.
The pieces a reward-driven world model needs and a self-supervised one does not. JEPA gets by with an encoder and a predictor; TD-MPC2 and MuZero also have to say how good a state is and what to do in it.
Modules:
| Name | Description |
|---|---|
categorical |
Scalar regression as classification: two-hot targets over a fixed bin grid. |
policy |
A squashed-Gaussian policy head. |
q_ensemble |
An ensemble of Q-functions, with a pessimistic aggregate. |
scalar |
An MLP trunk with a categorical scalar output -- rewards and values. |
Classes:
| Name | Description |
|---|---|
CategoricalScalar |
A fixed grid of bins for encoding and decoding scalars. |
GaussianPolicy |
|
PolicyOutput |
A sampled action with the statistics needed for a SAC-style update. |
QEnsemble |
|
ScalarHead |
Predict a scalar from a latent (and optionally an action). |
Functions:
| Name | Description |
|---|---|
cross_entropy |
Mean cross-entropy against a (possibly soft) target distribution. |
symexp |
Inverse of |
symlog |
|
two_hot |
Two-hot encode |
CategoricalScalar
¶
CategoricalScalar(n_bins: int = 101, low: float = -10.0, high: float = 10.0, *, transform: bool = True)
Bases: Module
A fixed grid of bins for encoding and decoding scalars.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_bins
|
int
|
number of bins. More bins means finer resolution and a harder classification problem; 101 is TD-MPC2's choice. |
101
|
low, high
|
range covered. Values outside are clipped, so pick a range that actually contains your returns. |
required | |
transform
|
bool
|
apply |
True
|
Methods:
| Name | Description |
|---|---|
encode |
Scalar(s) -> two-hot distribution |
decode |
Logits |
loss |
Cross-entropy between predicted logits and the two-hot target. |
Attributes:
| Name | Type | Description |
|---|---|---|
bins |
Array
|
|
Source code in xwm/heads/categorical.py
GaussianPolicy
¶
GaussianPolicy(latent_dim: int, action_dim: int, *, key: PRNGKey | None = None, hidden_dim: int = 512, depth: int = 2)
Bases: Module
z -> tanh(Normal(mu(z), sigma(z))), bounded in [-1, 1].
Methods:
| Name | Description |
|---|---|
distribution |
|
act |
Sample an action, or return the deterministic mean when |
sample |
Sample with the log-probability of the squashed action. |
Source code in xwm/heads/policy.py
distribution
¶
(mean, log_std) before squashing.
Source code in xwm/heads/policy.py
act
¶
Sample an action, or return the deterministic mean when key is None.
Source code in xwm/heads/policy.py
sample
¶
sample(z: Array, key: PRNGKey) -> PolicyOutput
Sample with the log-probability of the squashed action.
Source code in xwm/heads/policy.py
PolicyOutput
¶
Bases: NamedTuple
A sampled action with the statistics needed for a SAC-style update.
QEnsemble
¶
QEnsemble(latent_dim: int, action_dim: int, *, key: PRNGKey | None = None, n_members: int = 5, subset_size: int = 2, hidden_dim: int = 512, depth: int = 2, scalar: CategoricalScalar | None = None)
Bases: Module
n_members action-conditioned scalar heads over a shared latent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_members
|
int
|
ensemble size. |
5
|
subset_size
|
int
|
how many members the pessimistic aggregate draws from. |
2
|
Methods:
| Name | Description |
|---|---|
logits |
|
values |
|
pessimistic |
Minimum over a random subset of members -- the aggregate to plan with. |
loss |
Mean cross-entropy across members against a shared scalar target. |
Source code in xwm/heads/q_ensemble.py
logits
¶
values
¶
pessimistic
¶
Minimum over a random subset of members -- the aggregate to plan with.
key is required during training (the subset must be resampled every
step); pass None to use the min over all members, which is the
deterministic choice for evaluation.
Source code in xwm/heads/q_ensemble.py
loss
¶
Mean cross-entropy across members against a shared scalar target.
ScalarHead
¶
ScalarHead(latent_dim: int, *, action_dim: int = 0, key: PRNGKey | None = None, hidden_dim: int = 512, depth: int = 2, scalar: CategoricalScalar | None = None)
Bases: Module
Predict a scalar from a latent (and optionally an action).
Emits logits over bins rather than a number; call value to decode
or loss to train. See xwm.heads.categorical for why that
beats a squared error here.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
latent_dim
|
int
|
width of the input latent. |
required |
action_dim
|
int
|
width of an action to condition on; |
0
|
scalar
|
CategoricalScalar | None
|
the bin grid. Defaults to TD-MPC2's 101 bins with symlog. |
None
|
Methods:
| Name | Description |
|---|---|
logits |
|
value |
Decoded scalar. |
loss |
Cross-entropy against the two-hot encoding of |
Source code in xwm/heads/scalar.py
logits
¶
(n_bins,) logits.
Source code in xwm/heads/scalar.py
value
¶
loss
¶
cross_entropy
¶
Mean cross-entropy against a (possibly soft) target distribution.
symexp
¶
symlog
¶
two_hot
¶
Two-hot encode x over n_bins uniform bins spanning [low, high].
The value's mass is split linearly between its two neighbouring bins, so
sum(bins * two_hot(x)) == clip(x, low, high) exactly.