What a fit writes into your AnnData¶
fit mutates adata in place and returns the model. Everything below is written
by fit() unless noted.
obsm¶
Key |
Shape |
Meaning |
|---|---|---|
|
|
The latent space. Exactly |
|
|
Transfer models only. Per-dimension standardized latent. see Transferring a model to a new dataset. |
|
|
Only when you call |
transform also writes X_bae (and X_bae_scaled for transfers), so calling it
on a query dataset annotates that dataset in place.
varm¶
Key |
Shape |
Written by |
|---|---|---|
|
|
|
|
|
|
|
|
the standalone |
|
|
|
Note the encoder matrix is stored transposed relative to the internal
(latent_dim, n_genes) layout, so it lines up with adata.var.
uns["bae"]¶
Always present after a fit:
latent_dim, is_fitted, training_history, latent_init, disentanglement,
boosting_precompute_covcache, variance_explained.
boosting_precompute_covcache records the resolved covariance-cache
strategy, not the setting: the default is "auto", so without this a run
does not say which strategy it actually used.
Present when the corresponding feature was used:
Key |
Written when |
|---|---|
|
the fit read a layer rather than |
|
|
|
|
|
|
|
|
|
the mode included |
|
|
|
a stability run was performed |
|
|
Note
layer is absent, not None, when the fit read adata.X. AnnData’s uns
cannot hold None, and no key is the honest encoding of “the default”.
The two metrics people confuse¶
Both appear only for conditioned fits, and they answer different questions.
latent_obs_r2_per_dimAn integration metric. The fraction of each latent dimension’s variance explained by the conditioned obs columns. Values near zero are the goal. A single high entry is a residual covariate axis worth inspecting.
reconstruction_loss_by_obsA fairness metric. Reconstruction MSE per group. It says whether the model fits all groups comparably, not whether it integrated them.
A group can reconstruct poorly in a perfectly integrated model, and a model can reconstruct every group equally well while still routing batch through the latent. Check the one that matches your question.
Per-group losses are skipped, with a warning, for any column with more than 50 levels. Beyond that the breakdown is per-cell noise rather than a summary.
Gene panel identity¶
The encoder maps gene columns by position. Applying a model to a matrix with the same width but a different gene order produces plausible, wrong numbers.
transform and reconstruct compare adata.var_names against the names
recorded at fit time and emit a UserWarning naming the first differing
positions. It is a warning, not an error, and the call proceeds. To move a model
onto a genuinely different panel, use
from_reference(), which aligns by gene name.
Round-tripping to disk¶
Everything above survives adata.write_h5ad(...). To persist the model, meaning the
decoder, the config and the covariate encodings, see Saving and loading a model.
the AnnData keys alone are not enough to reproduce reconstruct.