> ## Documentation Index
> Fetch the complete documentation index at: https://docs.priorlabs.ai/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> TabPFN-3 and later versions support up to 1,000,000 rows, subject to feature count and checkpoint/API limits.
> For large datasets, use per-estimator subsampling, e.g. inference_config={"SUBSAMPLE_SAMPLES": 100_000}, in TabPFNClassifier or TabPFNRegressor from tabpfn or tabpfn_client.
> Pass raw pandas DataFrames to fit and predict. Categorical strings/categories, raw text, and missing feature values are handled automatically; no manual integer/one-hot encoding, imputation, scaling, or outlier removal is needed.

# Decoder readout

> Inspect and plot how training rows contribute to local TabPFN classification predictions.

<Info>
  Looking for usage documentation? Check out [Interpretability](/capabilities/interpretability) and [Classification](/capabilities/classification).
</Info>

Read out TabPFN's classification head as a label-vote over training rows.

TabPFN classifies with an attention-based retrieval head (`ManyClassDecoder`):
each test row attends to the training rows, and the prediction is the average of
their one-hot labels weighted by that attention. The prediction is therefore a
weighted vote, and `P(class c)` for a test row is the sum of its attention
weights over the training rows whose label is `c`.

[`get_decoder_readout`](/api-reference/python/tabpfn-extensions/interpretability/decoder-readout#get-decoder-readout) recovers those per-training-row attention weights, so you
can see *which* training points drive a prediction and by how much. The weights come
from the head's own `ManyClassDecoder.attention_weights` (`tabpfn>=8.3.0`), read
off a forward pre-hook during `predict`; `forward` itself fuses the attention
into a single kernel and never materializes them. For each test row the weights sum
to 1 (averaged over the decoder's attention heads and over the ensemble members).
Collapsing them by training label with [`class_vote`](/api-reference/python/tabpfn-extensions/interpretability/decoder-readout#class-vote) reproduces the model's
`predict_proba` up to the head's log-clamping when `softmax_temperature=1.0` and
`balance_probabilities=False`. Both are applied to the decoder's logits *after*
this readout, so at the library default
`softmax_temperature=0.9` the temperature sharpens the vote (per estimator,
`predict_proba` ∝ `vote ** (1 / T)`); `predict_proba` then differs from the
vote by up to \~2 percentage points for binary and \~6 at 10 classes, and
`balance_probabilities=True` widens it further.

Only the local `tabpfn` backend is supported: the client/API backend does not
expose the model internals this reads from. Row subsampling
(`TabPFNClassifier(..., subsample_samples=...)`) is not supported, since the
weight columns would no longer align to a single set of training rows.

<div className="python-reference-heading">
  <h2 id="get-decoder-readout">
    `decoder_readout.get_decoder_readout`
  </h2>

  <a className="python-reference-source" href="https://github.com/PriorLabs/tabpfn-extensions/blob/840c15a1848a986b39c85bc17efc61e0e377f983/src/tabpfn_extensions/interpretability/decoder_readout.py#L58" aria-label="View source for decoder_readout.get_decoder_readout"><span aria-hidden="true">\</></span> View source <span aria-hidden="true">↗</span></a>
</div>

Extract the decoder-head attention weights over training rows.

```python theme={null}
decoder_readout.get_decoder_readout(
    estimator: BaseEstimator,
    X: np.ndarray,
    *,
    average_over_estimators: bool = True,
) -> tuple[np.ndarray, np.ndarray]
```

**Parameters**

<div className="python-reference-table">
  | Parameter | Type | Default | Description |
  | - | - | - | - |
  | <span id="get-decoder-readout-estimator" /><code className="python-reference-parameter">estimator</code> | <code className="python-reference-type">Base<wbr />Estimator</code> | Required | A fitted local `TabPFNClassifier`. |
  | <span id="get-decoder-readout-x" /><code className="python-reference-parameter">X</code> | <code className="python-reference-type"><a href="https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html">np.ndarray</a></code> | Required | Test inputs, shape `(n_test, n_features)`. |
  | <span id="get-decoder-readout-average-over-estimators" /><code className="python-reference-parameter">average\_<wbr />over\_<wbr />estimators</code> | <code className="python-reference-type">bool</code> | `True` | If `True` (default), average the weights over the preprocessing ensemble members, returning one weight matrix. If `False`, keep the per-member weights on a leading axis. |
</div>

**Returns**

<div className="python-reference-table python-reference-returns">
  | Type | Description |
  | - | - |
  | <code className="python-reference-type">tuple\[<a href="https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html">np.ndarray</a>, <a href="https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html">np.ndarray</a>]</code> | `(weights, train_indices)`.<br /><br />`weights` has shape `(n_test, n_train)` when `average_over_estimators` is `True`, else `(n_estimators, n_test, n_train)`. Along the training axis the weights are non-negative and sum to 1 for each test row: `weights[i, j]` is the attention test row `i` pays to training row `j`.<br /><br />`train_indices` has shape `(n_train,)` and indexes the columns of `weights` into the rows of the data the model was fit on (i.e. `weights[:, k]` refers to training row `train_indices[k]`). |
</div>

***

<div className="python-reference-heading">
  <h2 id="class-vote">
    `decoder_readout.class_vote`
  </h2>

  <a className="python-reference-source" href="https://github.com/PriorLabs/tabpfn-extensions/blob/840c15a1848a986b39c85bc17efc61e0e377f983/src/tabpfn_extensions/interpretability/decoder_readout.py#L145" aria-label="View source for decoder_readout.class_vote"><span aria-hidden="true">\</></span> View source <span aria-hidden="true">↗</span></a>
</div>

Collapse per-row readout weights into a per-class vote.

Sums the attention weights within each training label, turning the readout
into a class distribution. Averaged over the ensemble, this reproduces the
model's `predict_proba` up to the head's log-clamping when
`softmax_temperature=1.0` and `balance_probabilities=False`. Both are
applied downstream of this readout, so at the library default
`softmax_temperature=0.9` the vote is sharpened (per estimator,
`predict_proba` ∝ `vote ** (1 / T)`), differing by up to \~2 percentage
points for binary and \~6 at 10 classes. It is also exact only in full precision;
reduced precision costs \~1e-2 relative, so fit with
`inference_precision=torch.float32` for a tight match.

```python theme={null}
decoder_readout.class_vote(
    weights: np.ndarray,
    y_train: np.ndarray,
    classes: np.ndarray | None = None,
) -> tuple[np.ndarray, np.ndarray]
```

**Parameters**

<div className="python-reference-table">
  | Parameter | Type | Default | Description |
  | - | - | - | - |
  | <span id="class-vote-weights" /><code className="python-reference-parameter">weights</code> | <code className="python-reference-type"><a href="https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html">np.ndarray</a></code> | Required | Readout weights `(n_test, n_train)` from [`get_decoder_readout`](/api-reference/python/tabpfn-extensions/interpretability/decoder-readout#get-decoder-readout). |
  | <span id="class-vote-y-train" /><code className="python-reference-parameter">y\_<wbr />train</code> | <code className="python-reference-type"><a href="https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html">np.ndarray</a></code> | Required | Training labels aligned to the weight columns, shape `(n_train,)`. |
  | <span id="class-vote-classes" /><code className="python-reference-parameter">classes</code> | <code className="python-reference-type"><a href="https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html">np.ndarray</a> \| None</code> | `None` | Class order for the output columns. Defaults to the sorted unique labels of `y_train`. |
</div>

**Returns**

<div className="python-reference-table python-reference-returns">
  | Type | Description |
  | - | - |
  | <code className="python-reference-type">tuple\[<a href="https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html">np.ndarray</a>, <a href="https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html">np.ndarray</a>]</code> | `(votes, classes)` where `votes` has shape `(n_test, n_classes)` and each row sums to 1, and `classes` is the class order of its columns. |
</div>

***

<div className="python-reference-heading">
  <h2 id="plot-decoder-readout">
    `decoder_readout.plot_decoder_readout`
  </h2>

  <a className="python-reference-source" href="https://github.com/PriorLabs/tabpfn-extensions/blob/840c15a1848a986b39c85bc17efc61e0e377f983/src/tabpfn_extensions/interpretability/decoder_readout.py#L217" aria-label="View source for decoder_readout.plot_decoder_readout"><span aria-hidden="true">\</></span> View source <span aria-hidden="true">↗</span></a>
</div>

Draw the decoder readout for a set of queries over a 2D projection.

Each panel places one query and its `top_k` most-attended training rows on a
2D projection of the rows, drawing a line from the query to each attended row
colored by the row's class and scaled by its vote weight; the query star is
colored by the predicted class (`argmax` of the class votes). The projection
uses `embeddings` (a `(train_vecs, test_vecs)` pair, e.g. TabPFN's
target-conditioned embeddings from `get_embeddings`) when given, else UMAP
(falling back to PCA) over the raw `train_features`/`test_features`.
Contrasting the two shows what the head keys on: distance in the embedding
space, where votes concentrate on the query's own class, versus the raw feature
space, where that locality is weaker.

Works for any number of classes. All test-row arrays (`weights`,
`test_features`, the test vectors in `embeddings`, `y_test`) span the full
test set; `queries` indexes into them to select the rows to draw.

```python theme={null}
decoder_readout.plot_decoder_readout(
    weights: np.ndarray,
    queries: list[int],
    train_features: np.ndarray,
    test_features: np.ndarray,
    y_train: np.ndarray,
    class_names: list[str],
    *,
    y_test: np.ndarray | None = None,
    embeddings: tuple[np.ndarray, np.ndarray] | None = None,
    query_titles: list[str] | None = None,
    colors: list[str] | None = None,
    title: str = "TabPFN decoder-head readout",
    top_k: int = 20,
) -> Figure
```

**Parameters**

<div className="python-reference-table">
  | Parameter | Type | Default | Description |
  | - | - | - | - |
  | <span id="plot-decoder-readout-weights" /><code className="python-reference-parameter">weights</code> | <code className="python-reference-type"><a href="https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html">np.ndarray</a></code> | Required | Readout weights `(n_test, n_train)` from [`get_decoder_readout`](/api-reference/python/tabpfn-extensions/interpretability/decoder-readout#get-decoder-readout). |
  | <span id="plot-decoder-readout-queries" /><code className="python-reference-parameter">queries</code> | <code className="python-reference-type">list\[int]</code> | Required | Indices into the test set of the rows to draw, one per panel. |
  | <span id="plot-decoder-readout-train-features" /><code className="python-reference-parameter">train\_<wbr />features</code> | <code className="python-reference-type"><a href="https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html">np.ndarray</a></code> | Required | Raw training features `(n_train, n_features)`. |
  | <span id="plot-decoder-readout-test-features" /><code className="python-reference-parameter">test\_<wbr />features</code> | <code className="python-reference-type"><a href="https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html">np.ndarray</a></code> | Required | Raw test features `(n_test, n_features)`; the queried rows are selected internally. |
  | <span id="plot-decoder-readout-y-train" /><code className="python-reference-parameter">y\_<wbr />train</code> | <code className="python-reference-type"><a href="https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html">np.ndarray</a></code> | Required | Training labels aligned to the weight columns, `(n_train,)`. |
  | <span id="plot-decoder-readout-class-names" /><code className="python-reference-parameter">class\_<wbr />names</code> | <code className="python-reference-type">list\[str]</code> | Required | Per-class names, aligned to the sorted class labels (same order as `colors`), so `class_names[i]` names the `i`-th class in `sorted(unique(y_train))` rather than the label whose value is `i`. This keeps string and non-0-indexed integer labels working. |
  | <span id="plot-decoder-readout-y-test" /><code className="python-reference-parameter">y\_<wbr />test</code> | <code className="python-reference-type"><a href="https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html">np.ndarray</a> \| None</code> | `None` | Optional test labels `(n_test,)`; when given, each panel is annotated with the query's true class. |
  | <span id="plot-decoder-readout-embeddings" /><code className="python-reference-parameter">embeddings</code> | <code className="python-reference-type">tuple\[<a href="https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html">np.ndarray</a>, <a href="https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html">np.ndarray</a>] \| None</code> | `None` | Optional `(train_vecs, test_vecs)` with `test_vecs` spanning the full test set, projected instead of the raw features. |
  | <span id="plot-decoder-readout-query-titles" /><code className="python-reference-parameter">query\_<wbr />titles</code> | <code className="python-reference-type">list\[str] \| None</code> | `None` | Optional per-panel labels, aligned to `queries`. |
  | <span id="plot-decoder-readout-colors" /><code className="python-reference-parameter">colors</code> | <code className="python-reference-type">list\[str] \| None</code> | `None` | Optional per-class colors, aligned to the sorted class labels. Defaults to a colorblind-validated categorical palette. |
  | <span id="plot-decoder-readout-title" /><code className="python-reference-parameter">title</code> | <code className="python-reference-type">str</code> | `"TabPFN decoder-head readout"` | [`Figure`](https://matplotlib.org/stable/api/_as_gen/matplotlib.figure.Figure.html) title; the projection name is appended. |
  | <span id="plot-decoder-readout-top-k" /><code className="python-reference-parameter">top\_<wbr />k</code> | <code className="python-reference-type">int</code> | `20` | Number of top-voting training rows to draw per query. |
</div>

**Returns**

<div className="python-reference-table python-reference-returns">
  | Type | Description |
  | - | - |
  | <code className="python-reference-type"><a href="https://matplotlib.org/stable/api/_as_gen/matplotlib.figure.Figure.html">Figure</a></code> | [`Figure`](https://matplotlib.org/stable/api/_as_gen/matplotlib.figure.Figure.html) with one panel per query, showing its top-voting training rows. |
</div>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.