File size: 7,583 Bytes
1c61c4d cb57b1d 1c61c4d 5852a98 1c61c4d ef50b39 1c61c4d ef50b39 0bbccd6 1c61c4d 6a04155 1c61c4d 6a04155 1c61c4d 6a04155 ef50b39 5852a98 1c61c4d ef50b39 f506320 ef50b39 3439070 ef50b39 1c61c4d ef50b39 1c61c4d ef50b39 75e6b12 ef50b39 1c61c4d ef50b39 f506320 1c61c4d f506320 ef50b39 1c61c4d ef50b39 1c61c4d ef50b39 602a878 f506320 ef50b39 6a04155 1c61c4d 6a04155 ef50b39 1c61c4d 6a04155 1c61c4d 6a04155 1c61c4d 6a04155 ef50b39 1c61c4d f506320 f566690 f506320 f566690 f506320 f566690 f506320 f566690 ef50b39 0bbccd6 ef50b39 302f80f 6a04155 1c61c4d cb57b1d f506320 ef50b39 1c61c4d ef50b39 1c61c4d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | ---
license: mit
library_name: pytorch
pipeline_tag: graph-ml
tags:
- graph-neural-networks
- histopathology
- self-supervised-learning
- pytorch-geometric
- graph-representation-learning
- edge-features
---
# GrapHist++: Edge-Informed Graph Self-Supervised Learning for Histopathology
Pre-trained weights, cell graphs and embeddings for the edge-informed extension of
[GrapHist](https://huggingface.co/papers/2603.00143). GrapHist encodes a slide as a sparse graph
of cells and pre-trains an ACM-GIN encoder with masked feature reconstruction. GrapHist++ keeps
that recipe and changes two things: each edge carries a 75-dimensional descriptor of the tissue
between the two cells, and a VICReg variance/covariance term is added to the objective to stop
the representation collapsing.
- **Original paper:** [arXiv:2603.00143](https://arxiv.org/abs/2603.00143) · [model](https://huggingface.co/ogutsevda/graphist)
- **Code:** [Ace3Z/GrapHist-V2](https://github.com/Ace3Z/GrapHist-V2)
- **Data manual:** [`DATA.md`](DATA.md), mapping every artifact here to the result it reproduces
## Results
Slide-level MIL, transfer to unseen cohorts (test macro-F1 %, best of three MIL heads):
| | BRACS | BreakHis | BACH |
|---|:--:|:--:|:--:|
| GrapHist | 60.30 | 89.37 | **69.16** |
| **GrapHist++** | **69.00** | **95.53** | 68.98 |
Survival on TCGA-BRCA (Cox PH, C-index): **0.793**, against 0.763 for GrapHist, 0.724 MAE,
0.632 DINOv2. Cell-type identification (macro-F1 %): PanNuke 20× breast **58.57**, 40× breast
**58.38**, NuCLS 7-class **27.09**. The encoder is 7.98 M parameters, 9.29 M with the projection `embed()` runs through, inside a
10.53 M pre-training checkpoint; it embeds a patch in 0.093 ms at 0.327 GB peak memory (BACH,
batch size 48, H200).
Without VICReg the encoder collapses (`pca_1` ≈ 0.5, effective dimension ≈ 2 of 512); with it
the same 100-epoch run finishes at 0.17 and 11.9. The term is training-only.
## What's here
```
graphist_v2.pt the released encoder (127 MB, md5 81a2e6b91cefff0bbbc13c6fd318ee78)
modeling/ build_model factory and the ACM-GINEConv backbone
graphs/ cell graphs: TCGA-BRCA, BACH, BRACS, BreakHis, SPIDER-breast
embeddings/ precomputed slide- and cell-level embeddings
baselines/ DINOv2, MAE and GrapHist v1 embeddings for comparison
labels/ slide labels and the TCGA-BRCA clinical export
studies/ homophily, AdapterGNN and preprocessing-runtime artifacts
upstream_v1/ the original GrapHist graphs, unchanged
```
The repository is ~1.05 TB, so fetch file by file rather than cloning it. `DATA.md` gives the
per-cohort commands; the model alone is the six files in the snippet below.
## Requirements
```bash
pip install torch torch-geometric huggingface_hub pandas numpy
```
`pandas` and `numpy` are needed only by `modeling/graphist_utils.py`, which holds the input
transforms.
Graphs are PyTorch Geometric objects with `x` `(n, 96)`, `edge_index` `(2, e)`, `edge_attr`
`(e, 75)` and `batch`. Column 0 of `edge_attr` is the centroid distance in µm and is used as the
message weight, not as a feature.
## Usage
```python
import os, sys, torch
from huggingface_hub import hf_hub_download
# Fetch file by file. snapshot_download(allow_patterns=...) is equivalent on
# huggingface-hub >= 1.27, but silently skips LFS files on 1.7.1, which is the
# version the code repository pins, so it would return no checkpoint there.
for f in ["graphist_v2.pt", "modeling/graphist_utils.py",
"modeling/models/__init__.py", "modeling/models/acm_gin.py",
"modeling/models/acm_gineconv.py", "modeling/models/edcoder.py",
"modeling/models/utils.py"]:
hf_hub_download(repo_id="Ace3Z/graphist-v2", filename=f)
path = os.path.dirname(hf_hub_download(repo_id="Ace3Z/graphist-v2",
filename="graphist_v2.pt"))
sys.path.insert(0, f"{path}/modeling")
from models import build_model
class Args:
encoder = decoder = "acm_gineconv"
num_features = 96 # per-cell features
num_edge_features = 75 # projection sees 74; distance excluded
num_hidden = 512
num_layers = 5
concat_hidden = True # load-critical
encoder_norm = "layer" # load-critical
edge_distance_in_proj = False # load-critical
input_norm = "none"
batchnorm = False
activation = "prelu"
loss_fn = "sce"
alpha_l = 3
mask_rate = 0.5
replace_rate = 0.1
drop_edge_rate = 0.0
vicreg_var_weight = 0.05 # training only
vicreg_cov_weight = 0.002
vicreg_gamma = 1.0
model = build_model(Args())
ckpt = torch.load(f"{path}/graphist_v2.pt", map_location="cpu", weights_only=False)
model.load_state_dict(ckpt["model_state_dict"], strict=True)
model.eval()
```
A graph has to go through the same three transforms the release was trained and evaluated with,
or the embeddings will not match. They ship here, in `modeling/graphist_utils.py`:
```python
import json
from torch_geometric.data import Batch
from torch_geometric.transforms import ToUndirected
from graphist_utils import NormalizeData, AddVirtualNode
scale_vals = json.load(open("normalization.json")) # ships beside each cohort's graphs
graph = torch.load("some_graph.pt", weights_only=False)
for t in (ToUndirected(),
NormalizeData(scale_vals, edge_attr_skip_cols=[0], min_std=0.01, clip=10),
AddVirtualNode(mean_edge_distance=scale_vals["edge_attr"]["mean"][0])):
graph = t(graph)
batch = Batch.from_data_list([graph])
with torch.no_grad():
h = model.embed(batch.x, batch.edge_index, batch.edge_attr, batch.batch)
```
Skipping the transforms raises no error; it just yields different numbers. `embed()` returns one
row per node **including the synthetic virtual node**, so a 16-cell graph gives `(17, 512)`; drop
the last row before pooling to a patch vector.
Three arguments decide whether the weights load at all. `encoder_norm` must be `"layer"` and
`edge_distance_in_proj` must be `False` (both defaults are wrong for this checkpoint), and
`concat_hidden` must be `True`, which has no default. Anything else raises a shape or key error.
## Licence and citation
Released under the MIT licence, matching the code repository.
That covers what this repository adds. It cannot relicense the source data, and three upstream
terms travel with the derivatives:
| What | Upstream terms |
|---|---|
| `upstream_v1/`, `studies/adaptergnn/graphs_v1/` | **`cc-by-nc-sa-4.0`** from the GrapHist v1 datasets: non-commercial **and share-alike** |
| `graphs/spider_breast/` | `cc-by-nc-4.0`, **research use only** |
| `baselines/graphist_v1/graphist_v1.pt` | `apache-2.0`, byte-identical to the released GrapHist v1 checkpoint |
`labels/tcga_brca_clinical.tsv` is the open-access GDC clinical export, redistributed under
TCGA's open-access terms. The source cohorts keep their own licences, so cite their papers
alongside GrapHist.
The architecture adapts [GraphMAE](https://github.com/THUDM/GraphMAE) and
[ACM-GNN](https://github.com/SitaoLuan/ACM-GNN); the regularizer follows
[VICReg](https://arxiv.org/abs/2105.04906).
```bibtex
@misc{ogut2026graphist,
title = {GrapHist: Graph Self-Supervised Learning for Histopathology},
author = {Sevda {\"O}{\u{g}}{\"u}t and C{\'e}dric Vincent-Cuaz and Natalia Dubljevic and
Carlos Hurtado and Vaishnavi Subramanian and Pascal Frossard and Dorina Thanou},
year = {2026},
eprint = {2603.00143},
url = {https://arxiv.org/abs/2603.00143},
}
```
|