structboost.TrainingReport

class structboost.TrainingReport(iteration, train_loss, loss_pre_boost, loss_post_boost, loss_post_decoder, encoder_delta, decoder_delta, target_grad_norm, decoder_grad_norm, boosting_r2, encoder_weight_norm, weight_change_rel, support_jaccard, min_dim_cosine, n_selected, n_selected_per_dim, latent_var_per_dim)[source]

Bases: object

Per-iteration training diagnostics collected by BAE.fit.

Produced only when diagnostics=True. Every field is a NumPy array whose first axis indexes the training iteration; per-dimension fields have shape (n_iterations, latent_dim).

Each BAE iteration alternates two optimizers, giving three points at which the full-data reconstruction loss can be measured:

A (loss_pre_boost)

before anything changes, i.e. encoder from the previous iteration.

B (loss_post_boost)

after the encoder is re-fit by boosting, before the decoder moves.

C (loss_post_decoder)

after the decoder SGD steps.

The differences encoder_delta = B - A and decoder_delta = C - B attribute the loss change of each iteration to the two halves of the alternation, which is otherwise invisible: a single loss curve cannot say whether the boosting step helps or whether the decoder is merely repairing the damage it does.

Parameters:
iteration

0-based iteration index.

Type:

numpy.ndarray[tuple[Any, …], numpy.dtype[numpy.int64]]

train_loss

Running average minibatch MSE during the decoder update. This is the historical metric and a noisier proxy for loss_post_decoder. Early stopping uses it directly unless soft correlation disentanglement is enabled, in which case the corresponding training_history["selection_loss"] also includes that penalty.

Type:

numpy.ndarray[tuple[Any, …], numpy.dtype[numpy.float64]]

loss_pre_boost

Full-data reconstruction MSE at point A above.

Type:

numpy.ndarray[tuple[Any, …], numpy.dtype[numpy.float64]]

loss_post_boost

Full-data reconstruction MSE at point B above.

Type:

numpy.ndarray[tuple[Any, …], numpy.dtype[numpy.float64]]

loss_post_decoder

Full-data reconstruction MSE at point C above.

Type:

numpy.ndarray[tuple[Any, …], numpy.dtype[numpy.float64]]

encoder_delta

Loss change attributable to the boosting step; negative means it reduced the loss.

Type:

numpy.ndarray[tuple[Any, …], numpy.dtype[numpy.float64]]

decoder_delta

Loss change attributable to the decoder step; negative means it reduced the loss.

Type:

numpy.ndarray[tuple[Any, …], numpy.dtype[numpy.float64]]

target_grad_norm

Norm of the boosting-target gradient, ||dL/dz||. This is the signal the encoder is fitted against; if it collapses toward zero the boosting targets carry no information.

Type:

numpy.ndarray[tuple[Any, …], numpy.dtype[numpy.float64]]

decoder_grad_norm

Norm of the full-data decoder parameter gradient.

Type:

numpy.ndarray[tuple[Any, …], numpy.dtype[numpy.float64]]

boosting_r2

R^2 of the encoder output against the boosting targets, i.e. how well allboost fitted what it was asked to fit.

Type:

numpy.ndarray[tuple[Any, …], numpy.dtype[numpy.float64]]

encoder_weight_norm

Mean absolute encoder weight. Typically grows by orders of magnitude during training, so weight changes must be read relative to it.

Type:

numpy.ndarray[tuple[Any, …], numpy.dtype[numpy.float64]]

weight_change_rel

Mean absolute change of the encoder weights against the previous iteration, divided by encoder_weight_norm. The primary convergence signal. NaN in the first iteration, which has no predecessor.

Type:

numpy.ndarray[tuple[Any, …], numpy.dtype[numpy.float64]]

support_jaccard

Jaccard overlap of the selected-gene set against the previous iteration. Answers whether the gene set has settled, which is coarser and noisier than weight_change_rel but directly interpretable. NaN in the first iteration.

Type:

numpy.ndarray[tuple[Any, …], numpy.dtype[numpy.float64]]

min_dim_cosine

Smallest per-latent-dimension cosine similarity between consecutive encoder weight matrices; scale-invariant, and identifies which dimension is still moving. NaN in the first iteration.

Type:

numpy.ndarray[tuple[Any, …], numpy.dtype[numpy.float64]]

n_selected

Number of genes with a nonzero weight in any latent dimension.

Type:

numpy.ndarray[tuple[Any, …], numpy.dtype[numpy.int64]]

n_selected_per_dim

Number of genes selected per latent dimension.

Type:

numpy.ndarray[tuple[Any, …], numpy.dtype[numpy.int64]]

latent_var_per_dim

Variance of each latent dimension across cells. Compare dimensions with each other rather than against an absolute scale: the overall latent magnitude is set by the boosting shrinkage and is small by construction.

Type:

numpy.ndarray[tuple[Any, …], numpy.dtype[numpy.float64]]

Methods

__init__(iteration, train_loss, ...)

from_dict(data)

Rebuild a report from to_dict() output, e.g. read back from h5ad.

to_dict()

Return the report as a plain dict of arrays, ready for adata.uns.

Attributes

property n_iterations: int

Number of recorded training iterations.

to_dict()[source]

Return the report as a plain dict of arrays, ready for adata.uns.

Return type:

dict[str, ndarray[tuple[Any, …], dtype[Any]]]

classmethod from_dict(data)[source]

Rebuild a report from to_dict() output, e.g. read back from h5ad.

Parameters:

data (dict[str, ndarray[tuple[Any, ...], dtype[Any]]])

Return type:

TrainingReport