Download ovarian_xenium/heldout_split/README.md from theislab/InterScale: direct link, hf CLI and curl.
- Browser
- Download file 5.2 kB
-
https://huggingface.co/theislab/InterScale/resolve/main/ovarian_xenium/heldout_split/README.md
- Command line
-
hf download hf://theislab/InterScale/ovarian_xenium/heldout_split/README.md
-
curl -L -o README.md https://huggingface.co/theislab/InterScale/resolve/main/ovarian_xenium/heldout_split/README.md
license: bsd-3-clause
library_name: interscale
tags:
- spatial-transcriptomics
- xenium
- cell-cell-communication
- graph-neural-network
- transformer
- single-cell
InterScale — 10x Xenium human ovarian adenocarcinoma (held-out-split model)
Pre-trained InterScale model (Drummer, Jiménez et al.,
bioRxiv 2026) for the 10x Xenium human ovarian adenocarcinoma section used in the cell–cell
communication chapter of the single-cell best-practices book. It is the model trained in the
tutorial notebook notebooks/psls_ccc/interscale_ovarian.ipynb. Loading it lets you skip training
and go straight to the net-flow and gene-programme analyses.
InterScale combines a local GCN over the spatial neighbour graph with a global transformer
over all cells of a tissue window. Each component reconstructs masked expression through its own
decoder (dual_decoder: true). The transformer's cell-by-cell attention is what the net-flow
analysis reads as directed communication between cell types.
Files
| file | contents |
|---|---|
model.pt |
trained weights, InterScale save format ({"model_state_dict": ...}), 20 MB |
config.yaml |
full resolved config the weights were trained with; only the two local paths are blanked |
genes.tsv |
the 3,000 input genes in model order, with their Moran's I |
metrics.json |
scores of this exact file on the held-out test windows |
Loading
Needs interscale from main at or after commit c98a307, the version it was trained with.
from huggingface_hub import snapshot_download
import interscale
from interscale.config import load_config
d = snapshot_download("theislab/InterScale", allow_patterns="ovarian_xenium/heldout_split/*")
d = f"{d}/ovarian_xenium/heldout_split"
cfg = load_config(f"{d}/config.yaml")
# `adata` must be prepared as described under "Input" below
interscale.model.CombinedModel._setup_anndata(
adata=adata,
prediction_task="regression",
layer_key="log1p_norm",
sample_key_list=["sliding_window"],
split_key=None,
)
model = interscale.model.CombinedModel.load(
d, adata, cfg, model_name="", local_component=True, global_component=True
)
result = model.get_model_output(adata) # .obsm["_attn_matrix"], ["_local_emb"], ["_global_emb"],
# .layers["_y_pred_local"], ["_y_pred_global"]
load raises if the config does not describe the checkpoint, so a model that loads is the trained
model. It will not silently keep random weights. The recipe above was checked by reloading this
folder and comparing all weights bit for bit.
Input
The model expects the tutorial's preprocessing. Section 2 of interscale_ovarian.ipynb does all of
it:
- Expression:
adata.layers["log1p_norm"]=log1p(normalize_total(counts)). - Genes: exactly the 3,000 genes of
genes.tsv, in that order (adata = adata[:, genes].copy()). They are the most spatially variable genes of the 4,447-gene panel by Moran's I (radius-30 µm graph, whole slide). - Windows:
adata.obs["sliding_window"], 600 µm non-overlapping tiles of the slide made withinterscale.pp.sliding_window, with windows of fewer than 50 cells dropped. The model builds a radius-30 µm neighbour graph inside each window. - Window size limit: the largest window must have at most 3,167 cells, the config's
max_seq_len. For larger windows, raisemodel.global_component.parameters.max_seq_lenin the config. A too-small value silently subsamples windows. adata.obsm["spatial"]in µm.
Training
| data | one section, 400,600 cells, 199 windows (mean 2,013 cells) |
| split | over windows, 70 / 15 / 15 → 139 train / 29 val / 31 test, seed 44 |
| objective | node-level reconstruction, cell masking at 30 %, SmoothL1 on the masked cells |
| architecture | 2-layer GCN (hidden 512, dropout 0.1) → 2-layer transformer (4 heads, FF 512, dropout 0) → linear decoders, latent width 256 |
| optimisation | lr 0.003, weight decay 0.001, cosine schedule with 10-epoch warm-up, batch 2 windows, early stopping on val loss (stopped at epoch 242 of max 600) |
| hardware | 1× NVIDIA H100 80 GB, ~17 min |
The hyperparameters are the best of a 48-trial random sweep over masking strategy (cell 10/30/50 %, gene 25/50/75 %), latent width (32–256), GCN/transformer size, dropout, learning rate, weight decay and batch size. The best config was then re-trained at three seeds and was stable across them, with a spread under 0.01 in r.
Evaluation
Scored on the 31 held-out test windows (65,804 cells), as the median over genes of the per-gene Pearson r. The masks are fixed (seed 2026), so other models can be compared on the same entries.
| test condition | local decoder | global decoder |
|---|---|---|
| 30 % of cells fully masked (the training task) | 0.163 | 0.165 |
| 50 % of (cell, gene) entries masked | 0.165 | 0.167 |
no masking (what get_model_output returns) |
0.175 | 0.160 |
Citation
Drummer, F., Jiménez, S. et al. InterScale. bioRxiv (2026). Code: https://github.com/theislab/interscale