spacr.deep_spacr¶
Workflow inputs and outputs¶
Activation¶
Apply the matching image classifier and preprocessing to inspect saliency/model-response maps.
Open: Classify → Activation.
Inputs and outputs below include conditional alternatives. The guidance and handoff notes say which route applies.
Inputs
Trained image classifier — Saved classifier checkpoint, model settings and matching channel/preprocessing configuration.
Object crops — data/**/*_png when save_png is enabled; png_list indexes saved crops. Supported workflows can instead stream crops from merged arrays and masks. Relevant tables, depending on the route:
png_list. Relevant columns, depending on the route:png_path,prcfo.
Outputs
Image attribution maps — Saved model-response/saliency images for the matching classifier and input preprocessing.
Before this module
Classify: Also provide the matching crops and channel preprocessing.
Computer Vision¶
Train an image classifier from labelled object crops, archives or supported streamed crops. Match channels and preprocessing when applying its checkpoint.
Open: Classify → Computer Vision.
Inputs and outputs below include conditional alternatives. The guidance and handoff notes say which route applies.
Inputs
Measured objects — measurements/measurements.db; object tables depend on the enabled cell, nucleus, pathogen and organelle masks. Relevant tables, depending on the route:
cell,nucleus,pathogen,cytoplasm. Relevant columns, depending on the route:plateID,rowID,columnID,fieldID.Object crops — data/**/*_png when save_png is enabled; png_list indexes saved crops. Supported workflows can instead stream crops from merged arrays and masks. Relevant tables, depending on the route:
png_list. Relevant columns, depending on the route:png_path,prcfo.Training annotations — A chosen annotation column in measurements/measurements.db, table png_list; labels belong to object identities. Relevant tables, depending on the route:
png_list. Relevant columns, depending on the route:prcfo.
Outputs
Object classification scores — Saved score CSVs and, when merged, measurements/measurements.db, table png_list. Relevant tables, depending on the route:
png_list. Relevant columns, depending on the route:pred,cv_predictions,ml_pred,predictions.Trained image classifier — Saved classifier checkpoint, model settings and matching channel/preprocessing configuration.
Classifier evaluation bundle — Held-out predictions, labels, split metadata and calibration/leakage metrics for a saved classifier run.
PyTorch dataset generation, classification, inference, and attribution.
Classes¶
SmoothGrad attribution: average gradients over noisy copies of the input. |
Functions¶
|
Compute and evaluate attribution maps for one or more images. |
|
Annotate and filter vision-model score CSVs, then optionally drop training images. |
|
Apply a trained PyTorch model to images in a directory. |
|
Apply a trained PyTorch model to images stored in a tar archive. |
|
Add flat |
|
Half precision for the block, or nothing at all. |
|
Assemble the record that travels with a checkpoint. |
|
Names for the classes |
|
Which metric columns to carry across folds, for THIS class count. |
|
Count the images the classifier was trained on, per split, per class. |
|
Run the full spacr deep-learning pipeline: build dataset, train, apply model, merge predictions into the measurements DB. |
|
Evaluate a binary or multiclass classifier and return metrics plus raw probs/labels. |
|
Render a card as Markdown — the version a human reads first. |
|
One line naming every class and how it actually did. |
|
Generate saliency or Grad-CAM activation maps for every image in a tar dataset. |
|
Everything the card says about held-out performance, recomputable. |
|
Write per-image prediction scores back into a spacr SQLite database. |
|
Build, write and register a card for |
|
Fuse the weights of several identically-shaped model checkpoints into one. |
|
Distil an ensemble of teacher models into a single student TorchModel. |
|
|
|
Select CUDA when sufficient memory is available, otherwise select CPU. |
|
The card beside |
|
Register the checkpoint and its card in the artifact registry. |
|
Translate |
|
(on, note). Whether to train in half precision on THIS machine. |
|
Extract the |
|
Reduce per-fold metrics to mean plus the spread around it. |
|
Core test loop over |
|
Evaluate |
|
Train a classifier and return it together with its checkpoint path. |
|
Train a vision classifier on a spacr training dataset and/or evaluate it on the held-out |
|
Show one synthesised class-visualisation image for class 0 and class 1. |
|
Compute and plot Integrated Gradients maps for every PNG under |
|
Compute and plot SmoothGrad maps for every PNG under |
|
Write |
Module Contents¶
- class spacr.deep_spacr.SmoothGrad(model, n_samples=50, stdev_spread=0.15)[source]¶
SmoothGrad attribution: average gradients over noisy copies of the input.
- Parameters:
model – PyTorch classifier used for gradient computation.
n_samples – Number of noisy samples to average over. Default
50.stdev_spread – Noise standard deviation as a fraction of the input’s dynamic range. Default
0.15.
Store the model and noise parameters.
- compute_smooth_grad(input_tensor, target_class)[source]¶
Return the averaged gradient map for
target_classgiveninput_tensor.- Parameters:
input_tensor – Input tensor to attribute (single sample or batch).
target_class – Class index whose logit is differentiated.
- Returns:
Tensor of the same shape as
input_tensorholding the averaged gradients.
- spacr.deep_spacr.analyze_activation_maps(model, images, methods=None, *, masks=None, target=None, target_layer=None, model_type=None, n_steps=12, baseline='blur', sanity_check=True, sanity_threshold=0.5, verbose=True)[source]¶
Compute and evaluate attribution maps for one or more images.
By default, the analysis evaluates
gradcam,saliency,integrated_gradients, andocclusion. For each successful attribution it computes deletion and insertion AUC; when an object mask is supplied it also evaluates the pointing game. Rank correlation summarizes agreement between non-flat methods for the first image.When
sanity_checkis enabled, the first image is re-attributed while model parameters are randomized layer by layer. A map that remains too similar after randomization has insufficient sensitivity to the learned parameters and should not be interpreted as a model-specific explanation.- Parameters:
model – Trained classifier.
images – Image tensor or iterable of tensors with shape
(C, H, W).methods – Attribution methods from
spacr.attribution.ATTRIBUTION_METHODS.Noneusesgradcam,saliency,integrated_gradients, andocclusion.masks – Optional per-image boolean object masks used by the pointing game.
target – Class index to explain.
Noneuses each image’s predicted class.target_layer – CAM target layer.
Noneselects the final convolutional layer.model_type – Optional architecture name used in diagnostic messages.
n_steps – Number of perturbation steps for deletion and insertion curves.
baseline – Replacement used for removed pixels:
"blur","zero","mean", or"uniform".sanity_check – Whether to run parameter-randomization analysis on the first image.
sanity_threshold – Maximum rank correlation at which a randomized map is considered sufficiently different.
verbose – Whether to print per-method validation results.
- Returns:
Mapping with
table,attributions,agreement,sanity, andnotes.
- spacr.deep_spacr.annotate_filter_vision(settings)[source]¶
Annotate and filter vision-model score CSVs, then optionally drop training images.
For every
srcCSV the plate metadata is corrected and annotated, rows whosefilter_columnvalue lies betweenlower_thresholdandupper_thresholdare dropped, and the result is written to<src>_annotated_filtered.csv. Only afterwards, and only whenremove_trainis set, are rows matching a PNG under the siblingdatasets/training/trainfolders removed and the same CSV rewritten.- Parameters:
settings – Settings dict with
src(path or list of paths); theannotate_conditionskeyscells,cell_loc,pathogens,pathogen_loc,treatmentsandtreatment_loc; the filter keysfilter_column(None, or a name absent from the frame, leaves it unfiltered),upper_thresholdandlower_threshold; andremove_train.- Returns:
None
- spacr.deep_spacr.apply_model(src, model_path, image_size=224, batch_size=64, normalize=True, n_jobs=10, input_statistics='symmetric', *, tta_enabled=False, tta_rotations=False, tta_horizontal_flip=False, tta_vertical_flip=False, tta_aggregation='probability_mean', tta_min_agreement=0.75, tta_max_std=0.15, score_threshold=0.5)[source]¶
Apply a trained PyTorch model to images in a directory.
The function loads a saved model, builds a dataset from the input images, runs batched inference, and saves prediction scores to a CSV file.
- Parameters:
src (str or os.PathLike) – Path to the directory containing the input images.
model_path (str) – Path to the saved PyTorch model.
image_size (int) – Final square crop size used before inference.
batch_size (int) – Number of images processed per batch.
normalize (bool) – Whether to normalize the image channels using mean 0.5 and standard deviation 0.5.
n_jobs (int) – Number of worker processes used by the DataLoader.
input_statistics – Normalization convention used when normalize is True.
tta_enabled – Enable multi-view scoring; False preserves ordinary inference.
tta_rotations – Include 90, 180 and 270-degree rotations; default False.
tta_horizontal_flip – Include left/right reflected views; default False.
tta_vertical_flip – Include up/down reflected views; default False.
tta_aggregation – probability_mean or majority_vote; ties prefer mean probability.
tta_min_agreement – Flag agreement below this fraction; default 0.75.
tta_max_std – Flag probability standard deviation above this value; default 0.15.
score_threshold – Positive-class cutoff used for binary TTA view labels.
- Returns:
DataFrame with image paths and prediction scores.
- Return type:
The returned DataFrame always contains the columns
pathandpred. A single-logit head is converted withtorch.sigmoid, sopredis the positive-class probability; a multi-logit head is converted withtorch.softmax, sopredis the probability of class 1 for two classes and the winning class’s confidence for more. With more than two classes the frame also carriespredicted_labeland oneprob_class_<i>column per class. Results are also written to a CSV file derived frommodel_pathand the current date.With
tta_enabled, both binary and multiclass outputs also retainoriginal_pred,original_predicted_label, per-class original and mean probabilities,prediction_std,transform_agreement,review_flagandtta_views. Orientation stability is not calibrated confidence. Training and held-out evaluation are unchanged.
- spacr.deep_spacr.apply_model_to_tar(settings=None)[source]¶
Apply a trained PyTorch model to images stored in a tar archive.
The function loads a saved model, reads images from a tar-based dataset, performs batched inference, post-processes prediction scores, and saves the results to a CSV file.
- Parameters:
settings (dict) – Dictionary of inference settings. Expected keys include
tar_path,model_path,image_size,batch_size,normalize,n_jobs,verbose, andscore_threshold. Optionaltta_enabled,tta_rotations,tta_horizontal_flip,tta_vertical_flip,tta_aggregation,tta_min_agreementandtta_max_stduse the same meanings and defaults asapply_model().- Returns:
DataFrame with processed prediction results.
- Return type:
The returned DataFrame contains at least the columns
pathandpred, plus the columns added byprocess_vision_results. A single-logit head is converted withtorch.sigmoid; a multi-logit head withtorch.softmax, giving the probability of class 1 for two classes and the winning class’s confidence for more. With more than two classes the frame also carriespredicted_labeland oneprob_class_<i>column per class, and itscv_predictionscolumn holds the predicted class index rather than a threshold onpred.Enabled test-time augmentation adds original predictions and stability diagnostics for every head type.
cv_predictionsfollows the selected aggregation method; with majority voting it can differ from thresholding the mean probability stored inpred.
- spacr.deep_spacr.attach_per_class_columns(metrics, classes=None)[source]¶
Add flat
acc_class_<name>keys tometrics, in place.Called on every epoch dict before it reaches
train.csv/validation.csv. The key set is fixed by the head size, which does not change inside a run, so the appended CSV keeps one stable header — seespacr.io._save_progress(), which writes the header only for the first chunk.- Parameters:
metrics – one epoch’s metrics dict; mutated and returned.
classes – optional class names in head order.
- spacr.deep_spacr.autocasting(on, device)[source]¶
Half precision for the block, or nothing at all.
A context manager either way, so the training loop has ONE shape rather than a branch around every forward pass.
- Parameters:
on – whether to autocast; falsy makes the block run unchanged.
device – the
torch.devicethe block runs on; itstypeis the autocast device type, and CPU uses bfloat16 where other devices use float16.
- spacr.deep_spacr.build_model_card(model_path, *, settings=None, classes=None, split_rule='', held_out=None, train_metrics=None, dataset_src=None, class_balance=None, module='train', epochs=None, history=None, extra=None)[source]¶
Assemble the record that travels with a checkpoint.
Answers, for a
.pthsomebody finds in six months: what was it trained on, how was the held-out split drawn, how balanced were the classes, how did it do per class, which spaCR wrote it, under which settings, when.- Parameters:
model_path – the checkpoint the card describes.
settings – the run’s settings; only the material ones are hashed and stored (
spacr.artifacts.material_settings()).classes – class names in head order.
split_rule – how the held-out set was drawn, in words — the field most often left implicit and most often the reason a number is wrong (“random 20 % of objects” leaks across wells; “grouped by well” does not).
held_out – a
held_out_report()dict.train_metrics – the training-split metrics of the same epoch.
dataset_src – dataset root, for the class balance on disk.
class_balance – override for the counted balance.
module – producing module key for the registry.
epochs – epochs requested, when known.
history – per-epoch metrics, trimmed into the card as a curve.
extra – anything else worth recording.
- Returns:
a JSON-safe dict.
- spacr.deep_spacr.class_labels(metrics, classes=None)[source]¶
Names for the classes
metricsdescribes, one per class.- Parameters:
metrics – a dict from
_binary_metrics()/_multiclass_metrics().classes – the folder names training read the classes from, in head order, when they are known. Omitted, the names
attach_per_class_columns()stamped intometricsare used — which is what lets the live plot and the model card name the classes without every helper having to be handed the list again.
- Returns:
list of
str, lengthnum_classes. Falls back toclass_0, class_1, …— never to an empty list, because the caller is about to index it per class.
- spacr.deep_spacr.cv_metric_keys(metrics) list[source]¶
Which metric columns to carry across folds, for THIS class count.
CV_METRIC_KEYSplus everyacc_class_<name>the epoch metrics carry – named byPER_CLASS_ACC_PREFIX, which is already the one spelling of that prefix in this module. Two classes get what they always got; three or more get their per-class accuracies as well, which is the only part of the summary that says anything about the classes.- Parameters:
metrics – a collection of metric names (a per-epoch metrics dict or a fold DataFrame’s columns), tested with
inand iterated for per-class accuracy keys.
- spacr.deep_spacr.dataset_class_balance(src, classes=None)[source]¶
Count the images the classifier was trained on, per split, per class.
Reads the
train/<class>/andtest/<class>/folder treespacr.io.generate_dataset()writes, because that tree is the training set — a class balance quoted from the settings would describe what was requested rather than what ended up on disk.- Parameters:
src – dataset root holding
train/(and optionallytest/).classes – class names to count; discovered from the folder names when omitted.
- Returns:
{split: {class: count}}for the splits that exist.
- spacr.deep_spacr.deep_spacr(settings=None)[source]¶
Run the full spacr deep-learning pipeline: build dataset, train, apply model, merge predictions into the measurements DB.
High-level driver that chains
spacr.io.generate_training_dataset()->train_test_model()->spacr.io.generate_dataset()(tar) ->apply_model_to_tar()->save_top_class_examples()->merge_predictions_into_db(). Each stage is toggled by a flag insettingsso the same call can (re)train from scratch, only apply a saved model, or only merge predictions.- Parameters:
settings –
Settings dict; canonicalized via
spacr.settings.deep_spacr_defaults(). Key flags/inputs:src— root folder(s) containing per-object PNGs fromspacr.measure.measure_crop().generate_training_dataset— buildtrain//test/splits via annotation rules before training.train/test— pass-through totrain_test_model().apply_model_to_dataset— run inference on a tar of PNGs.model_path— pretrained checkpoint to reuse whentrain=False.tar_path— pre-built dataset tar; regenerated if missing.n_top_examples— how many top-confidence images per class to copy intotop_examples/.crop_source—'auto'|'png'|'merged', passed straight through tospacr.io.generate_training_dataset()andspacr.io.generate_dataset().'merged'builds both the training split and the inference tar by cutting each crop out ofmerged/*.npythroughspacr.crops, so neither needs a pre-generated PNG folder and neither can be built from a stale one.Plus every key consumed by
train_test_model(),spacr.io.generate_training_dataset(), andspacr.io.generate_dataset().
- Returns:
None. Writes model checkpoints,
DL_model_settings.csv, a dataset tar,top_examples/and updates themeasurements.dbin-place.
Example
from spacr.deep_spacr import deep_spacr settings = { 'src': '/data/plate01', 'generate_training_dataset': True, 'train': True, 'test': True, 'apply_model_to_dataset': True, 'model_type': 'maxvit_t', 'classes': ['neg','pos'], 'epochs': 25, 'batch_size': 32, } deep_spacr(settings)
See also
train_test_model()— training-only entry point.spacr.io.generate_training_dataset()— labeling from annotation rules.apply_model_to_tar()— inference on a packed dataset.
- spacr.deep_spacr.evaluate_model_performance(model, loader, epoch, loss_type='auto', loss_fn=None, num_classes=None)[source]¶
Evaluate a binary or multiclass classifier and return metrics plus raw probs/labels.
Head size is inferred from the first batch — a single-logit head is treated as binary (BCE + sigmoid), otherwise softmax + CE metrics apply. If
loss_fnis None, one is constructed viabuild_loss.- Parameters:
model – PyTorch classifier.
loader – DataLoader yielding
(input, target, meta)batches.epoch – Current epoch (recorded in the returned dict).
loss_type – Loss selection passed to
build_losswhenloss_fnis None. Default'auto'.loss_fn – Optional callable
(logits, target) -> Tensor.num_classes – Class count when the loader is empty.
- Returns:
(metrics_dict, [probs, labels])— metrics includeloss,epochandAccuracy.probsis shape(N,)for binary or(N, C)for multiclass.
- spacr.deep_spacr.format_model_card(card)[source]¶
Render a card as Markdown — the version a human reads first.
- Parameters:
card – the model card dict, as built by
build_model_card(); missing keys render as?or “not recorded”.
- spacr.deep_spacr.format_per_class_accuracy(metrics, classes=None, prefix='')[source]¶
One line naming every class and how it actually did.
A 96 % aggregate hiding a class at 40 % is the commonest way a classifier looks finished and is not, and the aggregate is the only number the epoch line used to print. The worst class is flagged explicitly so it does not have to be spotted in a row of numbers.
- Parameters:
metrics – one epoch’s metrics dict.
classes – optional class names in head order.
prefix – text put in front of the line (“Train “, “Val “).
- Returns:
the line, or
''when there is no per-class breakdown.
- spacr.deep_spacr.generate_activation_map(settings)[source]¶
Generate saliency or Grad-CAM activation maps for every image in a tar dataset.
Loads the model, iterates the dataset, computes the requested map type per batch, saves per-image maps into class/plate/well folders, optionally plots batch grids, computes activation-image correlations, and pushes both maps and correlations into the measurement database.
- Parameters:
settings – Settings dict — see
settings.get_default_generate_activation_map_settingsfor keys (dataset,model_path,cam_type,target_layer,image_size,batch_size,channels,normalize,save,plot,correlation, …). Withcounterfactualson, up tocounterfactual_cropsof the crops also train a small class-conditional generator against the loaded model, and the held-out crops are morphed toward the other class with the classifier’s score written at every step (see_run_counterfactuals).- Returns:
None
- spacr.deep_spacr.held_out_report(y_true, probs, classes=None)[source]¶
Everything the card says about held-out performance, recomputable.
The card must not be the only place a number exists — a card that reports 0.96 with nothing to check it against is a claim, not a record. So this returns the confusion matrix alongside every derived figure, and each figure is exactly the standard function of that matrix:
accuracy = trace / totalandper_class_accuracy[c] = M[c, c] / M[c, :].sum(). Recomputing them fromconfusion_matrixmust reproduce them exactly, and the test suite pins that.- Parameters:
y_true – integer class ids, shape
(N,).probs –
(N,)positive-class probabilities for a single-logit head, or(N, C)softmax rows for a C-logit head. The same two shapesevaluate_model_performance()returns.classes – class names in head order, when known.
- Returns:
dict with
n,num_classes,classes,accuracy,f1_macro,per_class_accuracy,class_support,predicted_supportandconfusion_matrix.
The implementation lives in
spacr.active_learning.holdout_report(), which is torch-free, so a card written by a CNN round and a card written by an in-Annotate classical round carry the identical shape and are comparable side by side. Imported lazily: that module deliberately does not pull torch, and this one already has.
- spacr.deep_spacr.merge_predictions_into_db(df, db_path, table='png_list', pred_col='pred', class_col='cv_predictions')[source]¶
Write per-image prediction scores back into a spacr SQLite database.
Thin wrapper over
spacr.predictions.merge_cv_predictions(), which is the one merge path Classify (CV) and Classify (ML) share. It used to be implemented here, keyed onbasename(png_path), and collapsed repeated basenames with a plaindictassignment – so a run over two source folders whose plates were both calledplate1scored one plate with the other one’s predictions and said nothing. The replacement keys onprcfo, refuses a key that arrives with two different values instead of letting the last one win, counts every row it could not place, and runs in one transaction. Seespacr.predictions.- Parameters:
df – DataFrame with columns
path,predandcv_predictions.db_path – SQLite database file.
table – Target table. Default
'png_list'.pred_col – Database column for the probability. Default
'pred'.class_col – Database column for the class label. Default
'cv_predictions'.
- Returns:
Number of DB rows updated, or
Noneif the database is missing.
See also
spacr.predictions.merge_prediction_results()– the shared implementation, and the fullMergeReport.
- spacr.deep_spacr.model_card(model_path, *, registry=None, project=None, inputs=(), run_id='', **card_kwargs)[source]¶
Build, write and register a card for
model_pathin one call.- Parameters:
model_path – the checkpoint the card describes. Only the path is used: a checkpoint that does not exist still gets a card written beside it (its folder is created) and still registers, but with an empty content fingerprint, so that row is not content-addressed.
registry – an open
spacr.artifacts.Registryto store the row in; without one, a registry is opened atproject.project – project root recorded on the artifact, and where the registry is opened when
registryis None. Defaults to the checkpoint’s own folder, which is where anartifacts.dbthen appears. It still sets the recorded root whenregistryis passed.inputs – upstream artifact ids or
spacr.artifacts.Artifactobjects this checkpoint was derived from.run_id – the run this came out of, stored on the artifact row.
card_kwargs – passed to
build_model_card()—settings,classes,split_rule,held_outand the rest.
- Returns:
(card, card_path, artifact_or_None). On a successful registration the card is written twice, the second time carryingartifact_id. If the registry cannot be reached the artifact isNoneand the card keeps noartifact_id; nothing raises either way, because losing the card must not lose the weights.
- spacr.deep_spacr.model_fusion(model_paths, save_path, device='cpu', model_name='maxvit_t', pretrained=True, dropout_rate=None, use_checkpoint=False, aggregator='mean')[source]¶
Fuse the weights of several identically-shaped model checkpoints into one.
- Parameters:
model_paths – Paths to source checkpoints (dicts or
TorchModelobjects).save_path – Base output path; suffix
_<aggregator>.pthis appended.device – Torch device string. Default
'cpu'.model_name – TorchModel architecture name for the fused model.
pretrained – Whether pretrained weights are expected.
dropout_rate – Optional dropout rate.
use_checkpoint – Whether to enable gradient checkpointing.
aggregator – Reduction over stacked weights — one of
'mean','geomean','median','sum','max','min'. Default'mean'.
- Returns:
The fused
TorchModel.- Raises:
ValueError – on unsupported
aggregator, mismatched state dict keys, or unsupported checkpoint types.
- spacr.deep_spacr.model_knowledge_transfer(teacher_paths, student_save_path, data_loader, device='cpu', student_model_name='maxvit_t', pretrained=True, dropout_rate=None, use_checkpoint=False, alpha=0.5, temperature=2.0, lr=0.0001, epochs=10)[source]¶
Distil an ensemble of teacher models into a single student TorchModel.
- Parameters:
teacher_paths – Paths to the teacher checkpoints (each either a saved
TorchModelor a state dict).student_save_path – Destination for the trained student; the suffix
_KD.pthis appended.data_loader – Training DataLoader used during distillation.
device – Torch device string. Default
'cpu'.student_model_name – TorchModel architecture name for the student. Default
'maxvit_t'.pretrained – Whether the student uses pretrained weights.
dropout_rate – Optional dropout rate for the student.
use_checkpoint – Whether to enable gradient checkpointing.
alpha – Weight on the true-label loss vs. distillation loss. Default
0.5.temperature – Softmax temperature for distillation. Default
2.0.lr – Adam learning rate. Default
1e-4.epochs – Training epochs. Default
10.
- Returns:
The trained student model.
- Raises:
ValueError – on unsupported checkpoint types.
- spacr.deep_spacr.per_class_accuracy(metrics, classes=None)[source]¶
[(name, accuracy, support), …]for one epoch’s metrics.The single place that knows a binary head reports two classes and a multiclass head reports C, so nothing downstream branches on head shape.
- Parameters:
metrics – one epoch’s metrics dict.
classes – optional class names in head order.
- Returns:
list of
(name, float accuracy, int support); empty when the metrics carry no per-class breakdown at all.
- spacr.deep_spacr.pick_device(room_mb: int = GPU_ROOM_MB, what: str = 'this run')[source]¶
Select CUDA when sufficient memory is available, otherwise select CPU.
Availability alone does not ensure that a shared GPU has enough free memory for a new workload. When CUDA reports less than
room_mbfree, this function selects CPU and returns a user-facing note describing the available and required memory. If CUDA memory information is unavailable, CUDA is retained and allocation errors are allowed to surface from the workload.- Parameters:
room_mb – Minimum free GPU memory, in MiB, required to select CUDA.
what – Workload name included in the CPU-fallback note.
- Returns:
(torch.device, note).noteis empty unless low free GPU memory causes a CPU fallback.
- spacr.deep_spacr.read_model_card(model_path)[source]¶
The card beside
model_path, orNonewhen there is not one.- Parameters:
model_path – path to the model weights; the card is the JSON file with the same stem and the
.card.jsonsuffix.
- spacr.deep_spacr.register_model_card(model_path, card, *, project=None, registry=None, inputs=(), run_id='')[source]¶
Register the checkpoint and its card in the artifact registry.
Registering the weights with the card as
extra— rather than only dropping a JSON file next to them — is what makes the provenance real: the row carries the content fingerprint of the.pth, the settings hash, the spaCR version and the ids of the artifacts it was derived from, so “is this model stale?” has an answer that a hand-written note cannot give.- Parameters:
model_path – the checkpoint.
card – a
build_model_card()dict, stored as provenance.project – project root; defaults to the checkpoint’s own tree.
registry – an open
spacr.artifacts.Registry.inputs – upstream artifact ids or
spacr.artifacts.Artifact.run_id – the run this came out of.
- Returns:
the stored
spacr.artifacts.Artifact, orNonewhen the registry could not be written (a card on disk is still worth having, so this never raises the run down).
- spacr.deep_spacr.resolve_class_balance_loss(loss_type, class_balance, num_classes)[source]¶
Translate
class_balance='weighted_loss'into a concrete loss type.The weighted losses already exist in
spacr.utils.build_loss(); this only steers to them, so nothing about the loss maths changes here.- Parameters:
loss_type – the loss the user asked for.
class_balance – one of
spacr.io.CLASS_BALANCE_MODES.num_classes – size of the classifier head.
- Returns:
(loss_type, message)—messageis ‘’ when nothing changed.
- spacr.deep_spacr.resolve_mixed_precision(asked, device)[source]¶
(on, note). Whether to train in half precision on THIS machine.
WHY IT IS WORTH HAVING. The forward pass and the loss run in float16 while the weights and the optimiser stay in float32. Measured on an RTX 3090 over 30 training steps after 5 warm-up, at 224 px (
bench_amp.pyin the GPU queue folder reproduces it):model
speedup
peak memory
resnet50, batch 32
1.77x
0.58x
resnet50, batch 64
1.78x
0.55x
maxvit_t, batch 16
1.62x
0.60x
vit_b_16, batch 32
2.46x
0.67x
Half the memory is not a nicety on a screen: it is the difference between a batch of 32 and a batch of 64 at the same crop size.
CUDA ONLY, AND SAID SO.
torch.autocastaccepts a CPU device type and bfloat16, but on the CPUs spaCR runs on it is slower rather than faster, so asking for it there is answered rather than obeyed.- Parameters:
asked – what the
ampsetting says.device – the device training will actually run on.
- Returns:
(on, note)– the note is ‘’ when nothing needs saying.
- spacr.deep_spacr.save_top_class_examples(df, tar_path, dst, n=20, classes=None)[source]¶
Extract the
nmost confident images per class from a tar into class-labelled folders.For binary classification, class 0 keeps the lowest
predscores and class 1 keeps the highest. Multiclass output is ranked using the correspondingprob_class_<index>column.- Parameters:
df – DataFrame with columns
path(tar member name) andpred(probability). Multiclass results also containpredicted_labeland oneprob_class_<index>column per class.tar_path – Tar archive containing the images.
dst – Output root;
dst/class_<label>/subfolders are created.n – Number of images to keep per class. Default
20.classes – Optional display labels, in model-output order. When omitted, multiclass labels are inferred from the probability columns; binary output defaults to
[0, 1].
- Returns:
dst— for chaining.
- spacr.deep_spacr.summarize_cv_metrics(fold_df, metric_keys=None)[source]¶
Reduce per-fold metrics to mean plus the spread around it.
The spread is the whole point of k-fold: a single split can be lucky, and only the fold-to-fold standard deviation and range say by how much.
- Parameters:
fold_df – DataFrame with one row per fold.
metric_keys – metric columns to summarise. Defaults to
CV_METRIC_KEYSintersected with the columns present.
- Returns:
DataFrame indexed by metric with
n_folds,mean,std,min,max,rangeandcv_percentcolumns.
- spacr.deep_spacr.test_model_core(model, loader, loader_name, epoch, loss_type)[source]¶
Core test loop over
loader, compatible with binary & multiclass.- Parameters:
model – PyTorch classifier. Mutated in place: left in
evalmode and moved to CUDA whenever one is visible.loader – DataLoader yielding
(data, target, filenames)— a two-item batch raises. The third item is copied into the frame verbatim, so a tensor of ids stays a tensor rather than becoming a path. An empty loader takes the binary branch whatever the head is:num_classes2,accuracyNaN,loss0.0 and aclass_1_probabilitycolumn.epoch – Recorded as
int(epoch)and used for nothing else, so2.7lands as2andNoneraisesTypeError.loader_name – Accepted and ignored; no line of the body reads it.
loss_type – Accepted and ignored. The loss is always
spacr.utils.calculate_loss()withprefer_focal=True(gamma 2.0, alpha 1.0), so the reportedlossis a focal loss and is not on the same scale as the train/validation loss thatloss_typeselected — for the same logits it read 0.49 where plain cross-entropy read 0.95.
- Returns:
the 4-tuple
(metrics, probs, labels, results_df).metricsis the summary dict, withloss,epochandAccuracyadded.probsis shape(N,)for a single-logit head and(N, C)otherwise.labelsis the list of true class ids.results_dfholds one row per image withfilename,true_label,predicted_labeland eitherclass_1_probability(single-logit head) or oneprob_class_<k>column per class.predicted_labelthresholds a single-logit head at 0.5, not at theoptimal_thresholdthe metrics report.- Raises:
ValueError – when a batch does not unpack into three items.
- spacr.deep_spacr.test_model_performance(loaders, model, loader_name_list, epoch, loss_type)[source]¶
Evaluate
modelon a single loader and report the metrics as a frame.Thin wrapper around
test_model_core(), kept for API compatibility.- Parameters:
loaders – One DataLoader despite the plural name; passed straight through as the
loaderoftest_model_core().model – PyTorch classifier; the inner call leaves it in
evalmode on the evaluation device.loader_name_list – Forwarded to
test_model_core, which ignores it — no value of this changes the result.epoch – Copied into the summary row as
int(epoch).loss_type – Forwarded and likewise ignored; the reported
lossis the focal losstest_model_corealways computes, not this one.
- Returns:
(summary_metrics_dataframe, per_file_results_dataframe)— the first is the one-row frame of summary metrics, the second holds one row per image.per_class_accuracyandclass_supportare list-valued cells in that one row, which reach a CSV as theirrepr.
- spacr.deep_spacr.train_model(src, dst, model_type, train_loaders, epochs=100, learning_rate=0.0001, weight_decay=0.05, amsgrad=False, optimizer_type='adamw', use_checkpoint=False, dropout_rate=0, n_jobs=20, val_loaders=None, test_loaders=None, init_weights='imagenet', intermedeate_save=None, chan_dict=None, schedule=None, loss_type='auto', gradient_accumulation=False, gradient_accumulation_steps=4, channels=None, verbose=False, num_classes=2, image_size=224, plot=False, tensorboard=True, early_stopping_patience=0, custom_model_path=None, resume_checkpoint=None, preprocessing=None, classes=None, label_smoothing=0.1, focal_gamma=2.0, focal_alpha=None, logit_adjust_tau=1.0, settings=None, split_rule='', write_card=True)[source]¶
Train a classifier and return it together with its checkpoint path.
Supports 2-class and >2-class heads via CrossEntropy and a single-logit head via BCE; the loss itself is built by
spacr.utils.build_loss().- Parameters:
src – Dataset root. When
<src>/trainexists, its subfolder names become the class list and overrideclasses.dst – Output folder for checkpoints, progress CSVs and TensorBoard logs.
model_type – Architecture name passed to
spacr.utils.choose_model().train_loaders – DataLoader yielding
(data, target, filenames).epochs – Final epoch number to train through. Default
100.learning_rate – Optimizer learning rate. Default
0.0001.weight_decay – Optimizer weight decay. Default
0.05.amsgrad – AMSGrad variant, honoured by
adamwandadamonly.optimizer_type – One of
'adamw','adam','adamax','adagrad','adadelta','asgd','sgd','rmsprop','nadam','radam'. Default'adamw'.use_checkpoint – Enable gradient checkpointing in the architecture.
dropout_rate – Dropout rate passed to the architecture.
n_jobs – Unused; accepted for call-site compatibility.
val_loaders – Validation loader driving best-checkpoint selection and early stopping. Without one, training accuracy is used instead.
test_loaders – Only its batch count is printed; it is not evaluated here.
init_weights – Pretrained-weight selection, ignored (passed as
False) whencustom_model_pathorresume_checkpointis set.intermedeate_save – Accuracy thresholds that trigger intermediate checkpoints, forwarded to
spacr.io._save_model().chan_dict – Unused; accepted for call-site compatibility.
schedule –
None,'step_lr','reduce_lr_on_plateau','cosine','cosine_warm_restarts','exponential'or'linear'.loss_type – Loss identifier passed to
spacr.utils.build_loss();'auto'picks one from the head.gradient_accumulation – Accumulate gradients over several batches.
gradient_accumulation_steps – Batches per optimizer step when
gradient_accumulationis on. Default4.channels – Channel names recorded with the checkpoint. Default
['r', 'g', 'b'].verbose – Verbose architecture construction.
num_classes – Size of the classifier head;
1selects the binary BCE path. Default2.image_size – Square input size in pixels. Default
224.plot – Refresh a live training-curve figure after every epoch.
tensorboard – Write TensorBoard event files into
dst.early_stopping_patience – Number of epochs with no val improvement before stopping. Set to 0 to disable (original behavior).
custom_model_path – Checkpoint whose weights are fine-tuned.
resume_checkpoint – spaCR training artifact whose weights, optimizer, scheduler and epoch counter are restored.
preprocessing – Preprocessing description stored in the checkpoint.
classes – Class names, used when
<src>/traindoes not exist.label_smoothing – Label-smoothing epsilon for the smoothed losses. Default
0.1.focal_gamma – Focal-loss focusing parameter. Default
2.0.focal_alpha – Focal-loss class-balancing factor.
logit_adjust_tau – Strength of the logit adjustment;
0disables it. Default1.0.settings – the run’s settings dict, recorded (hashed) in the model card.
split_rule – how the held-out set was drawn, in words, for the card.
write_card – write
<model>.card.jsonbeside the weights and register it as an artifact. On by default: an uncarded checkpoint is a file nobody can audit six months later.
- Returns:
(model, model_path)— the trained model and the best checkpoint, which on a resumed run where no epoch beat the restored best metric isresume_checkpointitself, or(None, None)whenmodel_typecould not be built.- Raises:
ValueError – on an unknown
optimizer_type, a checkpoint whose class count differs fromnum_classes, aresume_checkpointcarrying no optimizer state, or a checkpoint that already completedepochs.FileNotFoundError – if
custom_model_pathorresume_checkpointdoes not exist.
- spacr.deep_spacr.train_test_model(settings)[source]¶
Train a vision classifier on a spacr training dataset and/or evaluate it on the held-out
test/split.Given a dataset folder
srclaid out astrain/<class>/*.pngandtest/<class>/*.png(as produced byspacr.io.generate_dataset()), this function optionally trains a torchvision-style model (model_type), then optionally scores the test split and copies misclassified images into a review folder. Best-checkpoint selection is automatic whentrain=Falseandtest=True.- Parameters:
settings –
Settings dict, canonicalized via
spacr.settings.get_train_test_model_settings(). Key entries:src— dataset root containingtrain/andtest/.model_type— e.g.'maxvit_t','resnet50'.classes— list of class names, must match subfolder names.epochs,batch_size,learning_rate,weight_decay.image_size,train_channels(e.g.['r','g','b']),normalize([low, high]percentiles).val_split— fraction pulled fromtrain/for validation.loss_type—'auto','cross_entropy','binary_cross_entropy_with_logits'.train/test— flip the two halves of the pipeline.cross_validation_enabled/cross_validation_folds— train with k-fold cross-validation overtrain/instead of a single validation split (enabling it with fewer than 2 folds uses 5, and 1 fold falls back to the single split);cv_group_bynames the grouping level used for the folds and the leakage audits.augment,dropout_rate,optimizer_type,early_stopping_patience,n_jobs,pin_memory.
- Returns:
When
train=True, the path to the saved best model — or, in cross-validation mode, the path to the per-fold metrics CSV, since there is no single model;Noneifmodel_typecould not be built. Whentrain=Falseandtest=True, the path to the test-result CSV.- Raises:
ValueError – if
settings['classes']is missing or empty.
Example
from spacr.deep_spacr import train_test_model settings = { 'src': '/data/dataset_v1', 'model_type': 'maxvit_t', 'classes': ['neg', 'pos'], 'epochs': 25, 'batch_size': 32, 'learning_rate': 1e-4, 'image_size': 224, 'train_channels': ['r','g','b'], 'train': True, 'test': True, } model_path = train_test_model(settings)
See also
spacr.deep_spacr.deep_spacr()— full end-to-end training + activation-map pipeline.spacr.io.generate_dataset()— build thetrain//test/folder tree.
- spacr.deep_spacr.visualize_classes(model, dtype, class_names, **kwargs)[source]¶
Show one synthesised class-visualisation image for class 0 and class 1.
The loop is hard-coded to the first two classes, so a model with more than two classes has only those two visualised.
- Parameters:
model – Trained classifier.
dtype – Tensor dtype used for optimisation.
class_names – Ordered class names; at least two are required, since indices 0 and 1 are both looked up.
kwargs – Extra keyword arguments forwarded to
utils.class_visualization.
- Returns:
None
- spacr.deep_spacr.visualize_integrated_gradients(src, model_path, target_label_idx=0, image_size=224, channels=None, normalize=True, save_integrated_grads=False, save_dir='integrated_grads')[source]¶
Compute and plot Integrated Gradients maps for every PNG under
src.- Parameters:
src – Folder of PNG images.
model_path – Path to the trained model checkpoint.
target_label_idx – Target class index for the attribution. Default
0.image_size – Square input size in pixels. Default
224.channels – Channel subset to keep. Default
[1, 2, 3].normalize – Apply per-channel normalisation. Default
True.save_integrated_grads – If True, save each map as PNG. Default
False.save_dir – Output folder for saved maps. Default
'integrated_grads'.
- Returns:
None
- spacr.deep_spacr.visualize_smooth_grad(src, model_path, target_label_idx, image_size=224, channels=None, normalize=True, save_smooth_grad=False, save_dir='smooth_grad')[source]¶
Compute and plot SmoothGrad maps for every PNG under
src.- Parameters:
src – Folder of PNG images.
model_path – Path to the trained model checkpoint.
target_label_idx – Target class index for the attribution.
image_size – Square input size in pixels. Default
224.channels – Channel subset to keep. Default
[1, 2, 3].normalize – Apply per-channel normalisation. Default
True.save_smooth_grad – If True, save each map as PNG. Default
False.save_dir – Output folder for saved maps. Default
'smooth_grad'.
- Returns:
None
- spacr.deep_spacr.write_model_card(model_path, card, *, markdown=True)[source]¶
Write
cardbesidemodel_path; return the JSON card’s path.- Parameters:
model_path – the checkpoint the card belongs to.
card – a
build_model_card()dict.markdown – also write the Markdown twin.
- Returns:
absolute path of the
.card.json.
Nested helpers¶
- _VirtualStainUNet.__init__.block(cin, cout)¶
Two convolution, normalisation and ReLU layers.
spacr/deep_spacr.py:4292
- _cross_validate_model._fit_one(train_loader, validation_loader, destination)¶
Train one fold model with a validation set not used for final scoring.
spacr/deep_spacr.py:1242
- _cross_validate_model._inner_loader(indices, *, training)¶
Build one inner loader from global indexes into the base dataset.
spacr/deep_spacr.py:1304
- _cross_validate_model._metrics_for_probabilities(labels, probabilities)¶
Compute legacy fold metrics for an ensemble probability matrix.
spacr/deep_spacr.py:1289
- _flowview_pipeline.decorate(function)¶
Return a wrapper that reports
functionlifecycle forfamily.spacr/deep_spacr.py:74
- _flowview_pipeline.decorate.observed(*args, **kwargs)¶
Call the pipeline, preserving its result or error while tracing lifecycle.
spacr/deep_spacr.py:77
- _vs_cellpose_segment.segment(plane)¶
Segment one 0-1 plane with Cellpose.
spacr/deep_spacr.py:4542
- annotate_filter_vision.filter_csv_by_png(csv_file)¶
Return a DataFrame with rows matching any PNG in the sibling
training/trainfolders removed.- Parameters:
csv_file – Path to the score CSV.
- Returns:
Filtered DataFrame.
spacr/deep_spacr.py:4144
- model_fusion.combine_tensors(tensor_list, mode='mean')¶
Given a list of Tensors, combine them using the chosen aggregator.
spacr/deep_spacr.py:4078