File size: 12,404 Bytes
1c61c4d
 
 
 
 
 
 
 
 
 
 
 
 
5852a98
1c61c4d
5852a98
546e75f
6a04155
 
 
 
 
1c61c4d
6a04155
 
 
 
1c61c4d
1ace6fc
 
 
1c61c4d
6a04155
1c61c4d
6a04155
1c61c4d
6a04155
 
 
5852a98
1c61c4d
6a04155
 
 
3439070
6a04155
1c61c4d
 
546e75f
ba369a5
 
546e75f
6a04155
 
 
ba369a5
6a04155
1c61c4d
 
1ace6fc
 
 
6a04155
75e6b12
 
 
6a04155
 
 
1c61c4d
6a04155
1c61c4d
 
 
 
 
 
546e75f
 
1c61c4d
6a04155
 
 
 
 
1c61c4d
 
 
6a04155
1c61c4d
 
 
6a04155
 
 
1c61c4d
 
6a04155
 
 
1c61c4d
 
 
 
 
 
 
 
6a04155
1c61c4d
 
 
 
6a04155
1c61c4d
 
 
6a04155
1c61c4d
 
6a04155
1c61c4d
 
6a04155
546e75f
 
1c61c4d
546e75f
6a04155
546e75f
 
 
 
 
 
 
 
 
 
1ace6fc
 
546e75f
 
 
 
 
6a04155
 
 
1c61c4d
6a04155
 
 
 
 
1c61c4d
6a04155
 
1c61c4d
6a04155
 
 
 
1ace6fc
 
 
1c61c4d
302f80f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6a04155
1c61c4d
302f80f
 
 
 
1c61c4d
 
d22e698
1c61c4d
d22e698
 
 
1c61c4d
 
d22e698
 
1c61c4d
 
6a04155
 
546e75f
 
4461349
546e75f
302f80f
75e6b12
ba369a5
 
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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
---
license: cc-by-nc-sa-4.0
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

GrapHist++ encodes a histopathology tile as a **cell graph** (one node per nucleus, edges
from a Delaunay triangulation pruned at 100 µm) and embeds it with a self-supervised
**ACM-GINEConv** encoder. It extends [GrapHist](https://huggingface.co/ogutsevda/graphist)
([arXiv:2603.00143](https://arxiv.org/abs/2603.00143)) by making the **edges carry
information**: each edge holds a 75-dimensional descriptor of the tissue between two cells,
and the encoder injects those features into message passing instead of treating edges as mere
connectivity.

**Trained on 11,149,499 cell graphs from TCGA-BRCA**, 100 epochs, batch 2048, no labels. The
objective is GraphMAE-style masked node-feature reconstruction (mask 50 %, scaled cosine
error, α = 3) plus a **VICReg** variance/covariance term on the pooled graph embedding, which
keeps all embedding dimensions in use (final `pca_1` 0.17, effective dimension 11.9).

Encoder 7.98 M parameters (9.29 M on the inference path, which also runs the projection;
10.53 M for the full pre-training model), 512-dim embeddings, 0.093 ms/patch at batch 48 on an
H200.

## Results

Slide-level MIL, transfer to unseen cohorts (test macro-F1 %, best of three MIL heads):

| | BRACS | BreakHis | BACH |
|---|:--:|:--:|:--:|
| GrapHist (v1) | 60.30 | 89.37 | **69.16** |
| **GrapHist++** | **69.00** | **95.53** | 68.98 |

Survival on TCGA-BRCA (Cox PH, C-index): **0.793**, vs 0.763 for v1, 0.724 MAE, 0.632 DINOv2.
Cell-type identification and patch-level subtyping are in [`DATA.md`](DATA.md), which maps
every artifact here to the result it reproduces.

## What's in this repo

```
graphist_v2.pt        the model. 126,597,010 B, md5 81a2e6b91cefff0bbbc13c6fd318ee78
modeling/             code to load and run it, plus the graph-path helper
graphs/               cell graphs: TCGA-BRCA (11.1 M, pre-training), BACH, BRACS,
                      BreakHis, SPIDER-breast
embeddings/           embeddings from this model: slide-level (4 cohorts), cell-level (22 sets)
baselines/            DINOv2, MAE and GrapHist v1 features for the comparison rows
labels/               TCGA-BRCA clinical table and slide labels
studies/              data for the side analyses: homophily, AdapterGNN, preprocessing runtime
upstream_v1/          mirror of the original GrapHist v1 releases
```

To run the model on your own graphs you need only `graphist_v2.pt` and `modeling/`. To
reproduce a published number you also need that dataset's `normalization.json` from
`graphs/<cohort>/`, since the transforms are part of the pipeline. See [`DATA.md`](DATA.md).

Training, evaluation and analysis code lives in
[github.com/Ace3Z/GrapHist-V2](https://github.com/Ace3Z/GrapHist-V2).

> ⚠️ **If you use `graphs/`, run `modeling/rebase_graph_paths.py` first.** The label CSVs store
> bare filenames and the loader resolves them against the working directory, so without this
> step every graph is silently dropped. `DATA.md` has the commands and the expected counts.

## Usage

```python
from huggingface_hub import snapshot_download
path = snapshot_download(repo_id="Ace3Z/graphist-v2")
```

Three arguments are **load-critical**. `build_model` reads two of them with defaults that do
not match this checkpoint, and the third has no default at all:

| Argument | Must be | If wrong |
|---|---|---|
| `edge_distance_in_proj` | `False` | `edge_input_proj` built as (512, **75**); checkpoint has (512, **74**) |
| `encoder_norm` | `"layer"` | `encoder.layer_norms.*` missing from the model |
| `concat_hidden` | `True` | `AttributeError` if omitted; (512, 512) instead of (512, **2560**) if `False` |

```python
import sys, torch
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      # per-edge features (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)   # note the key name
model.eval()

# x: [num_nodes, 96]  edge_index: [2, num_edges]  edge_attr: [num_edges, 75]
# batch: [num_nodes] graph assignment (zeros for a single graph)
with torch.no_grad():
    node_emb = model.embed(x, edge_index, edge_attr, batch)    # -> [num_nodes, 512]
```

Region- and slide-level embeddings are means over node embeddings. To match the published
numbers, apply the transforms used at training time: `NormalizeData` with the dataset's
`normalization.json`, then `AddVirtualNode`. Both are in `modeling/graphist_utils.py`.

### Requirements

Inference needs only `torch`, `torch_geometric`, `numpy` and `pandas`.

| | Trained with | Also verified on |
|---|---|---|
| Python | 3.10 | 3.10 |
| torch | 2.2.2 (CUDA 11.8) | 2.10.0 (CUDA 12.8) |
| torch_geometric | 2.5.2 | 2.7.0 |
| numpy | 1.26.4 | 2.2.6 |
| pandas | 2.2.2 | 2.3.3 |

Tested at both ends of that range, and on both numpy 1.x and 2.x. Newer versions also work;
these are floors, not a supported ceiling. CPU-only inference works.

Using the released data needs a little more: `h5py` (the embedding files are HDF5),
`scikit-learn` 1.5+ for the cell-level probe, and `lifelines` 0.30 for the survival analysis.

> `modeling/models/acm_gin.py` is required even though this model never uses it:
> `edcoder.py` imports it at module level.

## Graph format

| Tensor | Shape | Meaning |
|---|---|---|
| `x` | `[num_nodes, 96]` | per-cell morphology, texture and colour features |
| `edge_index` | `[2, num_edges]` | Delaunay edges, pruned at 100 µm |
| `edge_attr` | `[num_edges, 75]` | column 0 = centroid distance (µm); 1–74 describe the inter-cellular region |

The v1 releases use a 1-dimensional `edge_attr` (distance only) and are **not** interchangeable
with this model in either direction.

## Verification

`build_model` + `load_state_dict(strict=True)` returns 0 missing / 0 unexpected keys using only
the files shipped here. All 397 BACH slide embeddings regenerate from this checkpoint at
minimum cosine similarity **0.9999999997** against the published set. As a control, a
different checkpoint scores 0.256 mean cosine on the same comparison, so the test discriminates
and these weights are the ones behind the released embeddings.

## Datasets used

This release is built from seven public cohorts. If you use it, please cite GrapHist **and**
the source cohort(s) your work touches.

| Cohort | Used for | Source |
|---|---|---|
| **TCGA-BRCA** | pre-training (11.1 M graphs), slide-level evaluation, survival | [GDC Data Portal](https://portal.gdc.cancer.gov/) |
| **BACH** (ICIAR 2018) | slide-level subtyping, homophily | [Grand Challenge](https://iciar2018-challenge.grand-challenge.org/) |
| **BRACS** | slide-level subtyping, homophily | [bracs.icar.cnr.it](https://www.bracs.icar.cnr.it/) |
| **BreakHis** | slide-level subtyping, homophily | [P&D Lab, UFPR](https://web.inf.ufpr.br/vri/databases/breast-cancer-histopathological-database-breakhis/) |
| **NuCLS** | cell-type identification, homophily | [NuCLS](https://sites.google.com/view/nucls/home) |
| **PanNuke** | cell-type identification, homophily | [TIA Centre, Warwick](https://warwick.ac.uk/fac/sci/dcs/research/tia/data/pannuke/) |
| **SPIDER-breast** | patch-level subtyping | [histai/SPIDER-breast](https://huggingface.co/datasets/histai/SPIDER-breast) |

<details>
<summary>BibTeX for the source cohorts</summary>

```bibtex
@article{weinstein2013cancer,
  title={The cancer genome atlas pan-cancer analysis project},
  author={Weinstein, John N and Collisson, Eric A and Mills, Gordon B and Shaw, Kenna R and
          Ozenberger, Brad A and Ellrott, Kyle and Shmulevich, Ilya and Sander, Chris and
          Stuart, Joshua M},
  journal={Nature Genetics}, volume={45}, number={10}, pages={1113--1120}, year={2013},
  publisher={Nature Publishing Group}
}

@article{aresta2019bach,
  title={{BACH}: Grand challenge on breast cancer histology images},
  author={Aresta, Guilherme and Ara{\'u}jo, Teresa and Kwok, Scotty and
          Chennamsetty, Sai Saketh and Safwan, Mohammed and Alex, Varghese and others},
  journal={Medical Image Analysis}, volume={56}, pages={122--139}, year={2019},
  publisher={Elsevier}
}

@article{brancati2022bracs,
  title={{BRACS}: A Dataset for BReAst Carcinoma Subtyping in {H\&E} Histology Images},
  author={Brancati, Nadia and Anniciello, Anna Maria and Pati, Pushpak and Riccio, Daniel and
          Scognamiglio, Giosu{\`e} and Jaume, Guillaume and De Pietro, Giuseppe and
          Di Bonito, Maurizio and Foncubierta, Antonio and Botti, Gerardo and others},
  journal={Database}, volume={2022}, pages={baac093}, year={2022},
  publisher={Oxford University Press UK}
}

@article{spanhol2015dataset,
  title={A dataset for breast cancer histopathological image classification},
  author={Spanhol, Fabio A and Oliveira, Luiz S and Petitjean, Caroline and Heutte, Laurent},
  journal={IEEE Transactions on Biomedical Engineering}, volume={63}, number={7},
  pages={1455--1462}, year={2015}, publisher={IEEE}
}

@article{amgad2022nucls,
  title={{NuCLS}: A scalable crowdsourcing approach and dataset for nucleus classification and
         segmentation in breast cancer},
  author={Amgad, Mohamed and Atteya, Lamees A and Hussein, Hagar and Mohammed, Kareem Hosny and
          Hafiz, Ehab and Elsebaie, Maha AT and Alhusseiny, Ahmed M and
          AlMoslemany, Mohamed Atef and Elmatboly, Abdelmagid M and Pappalardo, Philip A and others},
  journal={GigaScience}, volume={11}, pages={giac037}, year={2022},
  publisher={Oxford University Press}
}

@article{gamper2020pannuke,
  title={{PanNuke} dataset extension, insights and baselines},
  author={Gamper, Jevgenij and Koohbanani, Navid Alemi and Benes, Ksenija and Graham, Simon and
          Jahanifar, Mostafa and Khurram, Syed Ali and Azam, Ayesha and Hewitt, Katherine and
          Rajpoot, Nasir},
  journal={arXiv preprint arXiv:2003.10778}, year={2020}
}

@article{nechaev2025spider,
  title={{SPIDER}: A Comprehensive Multi-Organ Supervised Pathology Dataset and Baseline Models},
  author={Nechaev, Dmitry and Pchelnikov, Alexey and Ivanova, Ekaterina},
  year={2025}, eprint={2503.02876}, archivePrefix={arXiv}, primaryClass={cs.CV}
}
```
</details>

## Licence and citation

Released `cc-by-nc-sa-4.0`. Everything here is *derived cell-level features*, not images.
SPIDER-breast is `cc-by-nc-4.0`, research use only, and its terms travel with the derived
graphs. `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.

```bibtex
@article{ogut2026graphist,
  title  = {GrapHist: Graph Self-Supervised Learning for Histopathology},
  author = {{\"O}{\u{g}}{\"u}t, Sevda and Vincent-Cuaz, C{\'e}dric and
            Dubljevic, Natalia and Hurtado, Carlos and Subramanian, Vaishnavi and
            Frossard, Pascal and Thanou, Dorina},
  year   = {2026},
  eprint = {2603.00143},
  archivePrefix = {arXiv},
  primaryClass  = {cs.CV}
}
```

Built on GraphMAE (Hou et al., 2022), ACM (Luan et al., 2022), GINEConv (Hu et al., 2020) and
VICReg (Bardes et al., 2022).

This work was done by [**Mahbod Tajdini**](https://mahbodtajdini.com) and [**Tomás Gadea Alcaide**](https://tomasgadea.com/), supervised by members of
[LTS4, EPFL](https://www.epfl.ch/labs/lts4/).

Training, evaluation and analysis code:
[github.com/Ace3Z/GrapHist-V2](https://github.com/Ace3Z/GrapHist-V2). This repository holds the
model, the code needed to load it, and the data.