king159 commited on
Commit
30e5a24
·
verified ·
1 Parent(s): a2cce2f

Release 10 SimpleP2G single-patch checkpoints (fold 0, seed 42)

Browse files
Files changed (39) hide show
  1. LICENSE +21 -0
  2. README.md +81 -0
  3. checksums.json +40 -0
  4. model_index.json +276 -0
  5. models/single-patch/brain/hmhvg/config.json +87 -0
  6. models/single-patch/brain/hmhvg/genes.json +202 -0
  7. models/single-patch/brain/hmhvg/model.safetensors +3 -0
  8. models/single-patch/brain/hvg/config.json +87 -0
  9. models/single-patch/brain/hvg/genes.json +202 -0
  10. models/single-patch/brain/hvg/model.safetensors +3 -0
  11. models/single-patch/ccrcc/hmhvg/config.json +97 -0
  12. models/single-patch/ccrcc/hmhvg/genes.json +202 -0
  13. models/single-patch/ccrcc/hmhvg/model.safetensors +3 -0
  14. models/single-patch/ccrcc/hvg/config.json +97 -0
  15. models/single-patch/ccrcc/hvg/genes.json +202 -0
  16. models/single-patch/ccrcc/hvg/model.safetensors +3 -0
  17. models/single-patch/her2st/hmhvg/config.json +109 -0
  18. models/single-patch/her2st/hmhvg/genes.json +202 -0
  19. models/single-patch/her2st/hmhvg/model.safetensors +3 -0
  20. models/single-patch/her2st/hvg/config.json +109 -0
  21. models/single-patch/her2st/hvg/genes.json +202 -0
  22. models/single-patch/her2st/hvg/model.safetensors +3 -0
  23. models/single-patch/lung/hmhvg/config.json +93 -0
  24. models/single-patch/lung/hmhvg/genes.json +202 -0
  25. models/single-patch/lung/hmhvg/model.safetensors +3 -0
  26. models/single-patch/lung/hvg/config.json +93 -0
  27. models/single-patch/lung/hvg/genes.json +202 -0
  28. models/single-patch/lung/hvg/model.safetensors +3 -0
  29. models/single-patch/prad/hmhvg/config.json +96 -0
  30. models/single-patch/prad/hmhvg/genes.json +202 -0
  31. models/single-patch/prad/hmhvg/model.safetensors +3 -0
  32. models/single-patch/prad/hvg/config.json +96 -0
  33. models/single-patch/prad/hvg/genes.json +202 -0
  34. models/single-patch/prad/hvg/model.safetensors +3 -0
  35. requirements.txt +3 -0
  36. src/__init__.py +1 -0
  37. src/pretrained.py +74 -0
  38. src/simpleP2G.py +350 -0
  39. src/simpleP2G_neigh.py +92 -0
LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2025 SichenZhu
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
README.md ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: mit
3
+ language:
4
+ - en
5
+ library_name: pytorch
6
+ datasets:
7
+ - MahmoodLab/hest
8
+ tags:
9
+ - biology
10
+ - spatial-transcriptomics
11
+ - computational-pathology
12
+ - gene-expression
13
+ - safetensors
14
+ ---
15
+
16
+ # SimpleP2G pretrained prediction heads
17
+
18
+ This repository contains **10 SimpleP2G checkpoints**: five HEST-1K datasets × two 200-gene panels × 1 setting(s), using **fold 0 and seed 42**.
19
+ Each checkpoint was selected by validation-slide PCC-200 after a 100-epoch training run. The released weights are the EMA weights used for the saved test predictions.
20
+
21
+ The models consume frozen 2,560-dimensional Virchow2 embeddings and predict gene expression in `log2(raw_count + 1)` units. **Virchow2 weights, image embeddings, tissue images, expression data, optimizer states and training logs are not included.** Obtain the image encoder separately from [paige-ai/Virchow2](https://huggingface.co/paige-ai/Virchow2).
22
+
23
+ ## Checkpoints
24
+
25
+ | Setting | Dataset | Panel | Test slide | Selected epoch | Test PCC-200 |
26
+ | --- | --- | --- | --- | ---: | ---: |
27
+ | single-patch | Brain | [HMHVG-200](https://huggingface.co/king159/SimpleP2G/tree/main/models/single-patch/brain/hmhvg) | NCBI667 | 12 | 0.3803 |
28
+ | single-patch | Brain | [HVG-200](https://huggingface.co/king159/SimpleP2G/tree/main/models/single-patch/brain/hvg) | NCBI667 | 16 | 0.1690 |
29
+ | single-patch | ccRCC | [HMHVG-200](https://huggingface.co/king159/SimpleP2G/tree/main/models/single-patch/ccrcc/hmhvg) | INT2 | 19 | 0.2704 |
30
+ | single-patch | ccRCC | [HVG-200](https://huggingface.co/king159/SimpleP2G/tree/main/models/single-patch/ccrcc/hvg) | INT2 | 7 | 0.1098 |
31
+ | single-patch | HER2ST | [HMHVG-200](https://huggingface.co/king159/SimpleP2G/tree/main/models/single-patch/her2st/hmhvg) | SPA148 | 21 | 0.7089 |
32
+ | single-patch | HER2ST | [HVG-200](https://huggingface.co/king159/SimpleP2G/tree/main/models/single-patch/her2st/hvg) | SPA148 | 37 | 0.3798 |
33
+ | single-patch | Lung | [HMHVG-200](https://huggingface.co/king159/SimpleP2G/tree/main/models/single-patch/lung/hmhvg) | NCBI856 | 7 | 0.8717 |
34
+ | single-patch | Lung | [HVG-200](https://huggingface.co/king159/SimpleP2G/tree/main/models/single-patch/lung/hvg) | NCBI856 | 8 | 0.4954 |
35
+ | single-patch | PRAD | [HMHVG-200](https://huggingface.co/king159/SimpleP2G/tree/main/models/single-patch/prad/hmhvg) | MEND145 | 9 | 0.5561 |
36
+ | single-patch | PRAD | [HVG-200](https://huggingface.co/king159/SimpleP2G/tree/main/models/single-patch/prad/hvg) | MEND145 | 12 | 0.2199 |
37
+
38
+ These are the scores of the released fold only, not means across the three evaluation folds. Panels are selected using training slides and can contain different genes across datasets. Keep the exact output-column order in each checkpoint’s `genes.json`.
39
+
40
+ ## Download
41
+
42
+ ```python
43
+ from huggingface_hub import snapshot_download
44
+
45
+ snapshot_download("king159/SimpleP2G", local_dir="simplep2g-checkpoints")
46
+ ```
47
+
48
+ ## Load and predict
49
+
50
+ The repository includes the small prediction-head implementation and a loader. From the downloaded repository directory (or an up-to-date SimpleP2G source checkout), install `torch`, `safetensors` and `huggingface_hub`, then:
51
+
52
+ ```python
53
+ import torch
54
+ from src.pretrained import load_pretrained
55
+
56
+ model, genes, metadata = load_pretrained(
57
+ "king159/SimpleP2G", dataset="brain", panel="hmhvg", setting="single-patch", device="cpu"
58
+ )
59
+
60
+ # Supply your precomputed image embeddings: shape (batch, 2560).
61
+ embeddings = torch.load("target_embeddings.pt", map_location="cpu", weights_only=True).float()
62
+ with torch.inference_mode():
63
+ mean, log_variance = model(embeddings[:16])
64
+ # mean[:, i] predicts genes[i] in log2(count + 1) units.
65
+ ```
66
+
67
+ To load offline, pass the downloaded repository directory as the first argument. To pin a particular release, pass its Hub commit hash as `revision=`.
68
+
69
+ The image feature convention is the CLS token concatenated with the mean of patch tokens (register tokens excluded), using the encoder’s prescribed preprocessing. Each model’s `config.json` records architecture, input/output conventions, split IDs, selection rule and metrics.
70
+
71
+ ## Files
72
+
73
+ `models/<setting>/<dataset>/<panel>/` contains `model.safetensors`, `config.json`, and `genes.json`. `model_index.json` lists all checkpoints; `checksums.json` records SHA-256 hashes. Weights are exported losslessly and checked against the training implementation using strict state-dictionary loading and CPU forward comparisons.
74
+
75
+ ## Scope
76
+
77
+ These are research models for predicting measured expression from image features. The fixed gene panels and tissue cohorts define their evaluated scope; the release does not include a clinical validation or cell-type classifier.
78
+
79
+ ## License
80
+
81
+ This release follows the project’s MIT license; see [LICENSE](LICENSE). The separately obtained image encoder and source datasets retain their own terms.
checksums.json ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "LICENSE": "bc54668eb751e259d8cba32c737cc18713f1d8559a2215dbc70bb0841f8d7f92",
3
+ "README.md": "1fcb8245c14139fab21fcf130f538ca1eddb60153a3549b6b3a33ff0d2eff32a",
4
+ "model_index.json": "50ac11c642bbfb80229de50504b2f8802eb3c5389b3c8cdc15d24fdedf46e15b",
5
+ "models/single-patch/brain/hmhvg/config.json": "f5e8ea3c5c366ba9f2678992cbb8d0f77cb5f83c9b65413af6fde5e319bff9c0",
6
+ "models/single-patch/brain/hmhvg/genes.json": "2d5649cf126a6910d2671651d95491e44c23a9c9730d58ff70d5a1dfcafa8814",
7
+ "models/single-patch/brain/hmhvg/model.safetensors": "30e10f1adc24365ff8ae5d3e7851e3336dfdd1775b0a8640ba94fd46630633de",
8
+ "models/single-patch/brain/hvg/config.json": "4902b72f8d6a95f111c41915ec3a2926f9837db3bb63f7c75ab6cfa64a8e31fc",
9
+ "models/single-patch/brain/hvg/genes.json": "9f1b13b2b3be4158e50f8dede0259b880a9e789b30a88612f4da899b22744eb7",
10
+ "models/single-patch/brain/hvg/model.safetensors": "a671becb75830a258455a6136e1be92f5f45ae822c6875290f61edb0f90a9eaa",
11
+ "models/single-patch/ccrcc/hmhvg/config.json": "ee9418e61c755b41c390541c2cad5fe7ef86fb2e8164fcbc76e2342f3429d4bc",
12
+ "models/single-patch/ccrcc/hmhvg/genes.json": "ff93267954d744e7e3db035f7d920e281b41cca703413841d6d52b27e1dc4815",
13
+ "models/single-patch/ccrcc/hmhvg/model.safetensors": "c913908cfee0f4712e5680140c1e3d5ee86baac1278bf65a7da97f24985f8aa2",
14
+ "models/single-patch/ccrcc/hvg/config.json": "0c7f5c18b7c5c120c87a3b1f784cae8115b48d6ec711c17e138cd77c42d28b66",
15
+ "models/single-patch/ccrcc/hvg/genes.json": "fc7c6641ec375172b1e19d671f6b5c9d016b7678b4fc49d5116f81c87dbc1922",
16
+ "models/single-patch/ccrcc/hvg/model.safetensors": "19a643e778694859ee2e25614c7839a5aa237436d575e0c2d1034501311480fb",
17
+ "models/single-patch/her2st/hmhvg/config.json": "53c6ada123c0df0add70da1723727122503ee399abc4c1278c9ecd4a0dfaf1b8",
18
+ "models/single-patch/her2st/hmhvg/genes.json": "280e7e0593a090cce56a3288bddb6faf65be9d7ad24a1e1122e24bd82bc6e77f",
19
+ "models/single-patch/her2st/hmhvg/model.safetensors": "0022fa86b49afcfaa4c9151d0eaf5c106425dc7cf428c2c19c349455dbdef4dd",
20
+ "models/single-patch/her2st/hvg/config.json": "9ee562a453368b8417446dff676b746e98462dacbac5f3e283854b771a4db152",
21
+ "models/single-patch/her2st/hvg/genes.json": "1807423efcd65ee9358dd4a26fe2c3164dbcb80c0141878674e623689023ba7b",
22
+ "models/single-patch/her2st/hvg/model.safetensors": "254fc5a129245998360cdcac313dd3d1c84b2a3feefbf4ce33689a81509c740d",
23
+ "models/single-patch/lung/hmhvg/config.json": "42276a98dcd0db5323082add208743170033080beacba623befd680fd0f02bc9",
24
+ "models/single-patch/lung/hmhvg/genes.json": "8a3a986d63531aeff3abb02d59014533ff3893738961e3d4e15735c9c0bf53ca",
25
+ "models/single-patch/lung/hmhvg/model.safetensors": "dcbde320a1df51a876a4c0797983d160f5deb3e4bae0f402af6af97b52ccc2f5",
26
+ "models/single-patch/lung/hvg/config.json": "5b4d6426c97c17e1876d8ef9ba1e09689c423da409d86fc6bd6e39839b65971c",
27
+ "models/single-patch/lung/hvg/genes.json": "b8661251c651801dad15bda1ceaaad59736790fdb3d110d4adb5f8c3aeff0026",
28
+ "models/single-patch/lung/hvg/model.safetensors": "f41735851688f4b7368d890c84527a2ba93a620c3df10095029149a5f0d5db6d",
29
+ "models/single-patch/prad/hmhvg/config.json": "19ddd3b57706c2ea759d1a3066428b35596fec2d19ccfd74498e689681566fc8",
30
+ "models/single-patch/prad/hmhvg/genes.json": "d08cd995114d1fa0bff9574535425e8f8e1f1dfb27b490ff0ac135ed695c93fa",
31
+ "models/single-patch/prad/hmhvg/model.safetensors": "ce7d28e32b4a84c0f0cba6f0561b22a997de7e9202c970968e767b2e71257142",
32
+ "models/single-patch/prad/hvg/config.json": "5900eebd65c4d4a7c55f5a18abaa9cdd51a1a1362ed214b288a3a7527f351409",
33
+ "models/single-patch/prad/hvg/genes.json": "7ec83111bb5c60fbe0cc4d7a524e63a604bddc377fb99a719f13618680445e2d",
34
+ "models/single-patch/prad/hvg/model.safetensors": "4f297f40eab72aa2e7706892106ee4428584e7604d0ef91a12272acde8aa60cf",
35
+ "requirements.txt": "98762691a6e741f153f12f9d4f741f710158d7c38903017e3ec166588f7a5499",
36
+ "src/__init__.py": "ef6563e43196efa4bff258400d603b6dea99dab3de9960df39872f7b9d17f8ca",
37
+ "src/pretrained.py": "7e6fd794dd9a88f7ebe7c76a679fc62558398af6e44fcb56198de6b6426c4386",
38
+ "src/simpleP2G.py": "8d7b01abc5318cfe92142a56a39ce9c1a31f2e9276392e78f9bac8998065cdd0",
39
+ "src/simpleP2G_neigh.py": "3db1bfade62c5a884011671476ac294f526c8b46a6ad79e2261857a32b374929"
40
+ }
model_index.json ADDED
@@ -0,0 +1,276 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "format_version": 1,
3
+ "repo_id": "king159/SimpleP2G",
4
+ "models": [
5
+ {
6
+ "setting": "single-patch",
7
+ "dataset": "brain",
8
+ "panel": "hmhvg",
9
+ "directory": "models/single-patch/brain/hmhvg",
10
+ "fold": 0,
11
+ "seed": 42,
12
+ "test_slide": "NCBI667",
13
+ "validation_slide": "NCBI671",
14
+ "checkpoint_epoch": 12,
15
+ "parameters": 45971074,
16
+ "test_pcc200": 0.3803240847090443,
17
+ "files": {
18
+ "model.safetensors": {
19
+ "sha256": "30e10f1adc24365ff8ae5d3e7851e3336dfdd1775b0a8640ba94fd46630633de",
20
+ "bytes": 183903592
21
+ },
22
+ "config.json": {
23
+ "sha256": "f5e8ea3c5c366ba9f2678992cbb8d0f77cb5f83c9b65413af6fde5e319bff9c0",
24
+ "bytes": 1899
25
+ },
26
+ "genes.json": {
27
+ "sha256": "2d5649cf126a6910d2671651d95491e44c23a9c9730d58ff70d5a1dfcafa8814",
28
+ "bytes": 2214
29
+ }
30
+ }
31
+ },
32
+ {
33
+ "setting": "single-patch",
34
+ "dataset": "brain",
35
+ "panel": "hvg",
36
+ "directory": "models/single-patch/brain/hvg",
37
+ "fold": 0,
38
+ "seed": 42,
39
+ "test_slide": "NCBI667",
40
+ "validation_slide": "NCBI671",
41
+ "checkpoint_epoch": 16,
42
+ "parameters": 45971074,
43
+ "test_pcc200": 0.1689760419646251,
44
+ "files": {
45
+ "model.safetensors": {
46
+ "sha256": "a671becb75830a258455a6136e1be92f5f45ae822c6875290f61edb0f90a9eaa",
47
+ "bytes": 183903592
48
+ },
49
+ "config.json": {
50
+ "sha256": "4902b72f8d6a95f111c41915ec3a2926f9837db3bb63f7c75ab6cfa64a8e31fc",
51
+ "bytes": 1904
52
+ },
53
+ "genes.json": {
54
+ "sha256": "9f1b13b2b3be4158e50f8dede0259b880a9e789b30a88612f4da899b22744eb7",
55
+ "bytes": 2279
56
+ }
57
+ }
58
+ },
59
+ {
60
+ "setting": "single-patch",
61
+ "dataset": "ccrcc",
62
+ "panel": "hmhvg",
63
+ "directory": "models/single-patch/ccrcc/hmhvg",
64
+ "fold": 0,
65
+ "seed": 42,
66
+ "test_slide": "INT2",
67
+ "validation_slide": "INT9",
68
+ "checkpoint_epoch": 19,
69
+ "parameters": 45971074,
70
+ "test_pcc200": 0.27036171397452496,
71
+ "files": {
72
+ "model.safetensors": {
73
+ "sha256": "c913908cfee0f4712e5680140c1e3d5ee86baac1278bf65a7da97f24985f8aa2",
74
+ "bytes": 183903592
75
+ },
76
+ "config.json": {
77
+ "sha256": "ee9418e61c755b41c390541c2cad5fe7ef86fb2e8164fcbc76e2342f3429d4bc",
78
+ "bytes": 2008
79
+ },
80
+ "genes.json": {
81
+ "sha256": "ff93267954d744e7e3db035f7d920e281b41cca703413841d6d52b27e1dc4815",
82
+ "bytes": 2197
83
+ }
84
+ }
85
+ },
86
+ {
87
+ "setting": "single-patch",
88
+ "dataset": "ccrcc",
89
+ "panel": "hvg",
90
+ "directory": "models/single-patch/ccrcc/hvg",
91
+ "fold": 0,
92
+ "seed": 42,
93
+ "test_slide": "INT2",
94
+ "validation_slide": "INT9",
95
+ "checkpoint_epoch": 7,
96
+ "parameters": 45971074,
97
+ "test_pcc200": 0.10978539095367261,
98
+ "files": {
99
+ "model.safetensors": {
100
+ "sha256": "19a643e778694859ee2e25614c7839a5aa237436d575e0c2d1034501311480fb",
101
+ "bytes": 183903592
102
+ },
103
+ "config.json": {
104
+ "sha256": "0c7f5c18b7c5c120c87a3b1f784cae8115b48d6ec711c17e138cd77c42d28b66",
105
+ "bytes": 2010
106
+ },
107
+ "genes.json": {
108
+ "sha256": "fc7c6641ec375172b1e19d671f6b5c9d016b7678b4fc49d5116f81c87dbc1922",
109
+ "bytes": 2188
110
+ }
111
+ }
112
+ },
113
+ {
114
+ "setting": "single-patch",
115
+ "dataset": "her2st",
116
+ "panel": "hmhvg",
117
+ "directory": "models/single-patch/her2st/hmhvg",
118
+ "fold": 0,
119
+ "seed": 42,
120
+ "test_slide": "SPA148",
121
+ "validation_slide": "SPA127",
122
+ "checkpoint_epoch": 21,
123
+ "parameters": 45971074,
124
+ "test_pcc200": 0.70892135019349,
125
+ "files": {
126
+ "model.safetensors": {
127
+ "sha256": "0022fa86b49afcfaa4c9151d0eaf5c106425dc7cf428c2c19c349455dbdef4dd",
128
+ "bytes": 183903592
129
+ },
130
+ "config.json": {
131
+ "sha256": "53c6ada123c0df0add70da1723727122503ee399abc4c1278c9ecd4a0dfaf1b8",
132
+ "bytes": 2236
133
+ },
134
+ "genes.json": {
135
+ "sha256": "280e7e0593a090cce56a3288bddb6faf65be9d7ad24a1e1122e24bd82bc6e77f",
136
+ "bytes": 2197
137
+ }
138
+ }
139
+ },
140
+ {
141
+ "setting": "single-patch",
142
+ "dataset": "her2st",
143
+ "panel": "hvg",
144
+ "directory": "models/single-patch/her2st/hvg",
145
+ "fold": 0,
146
+ "seed": 42,
147
+ "test_slide": "SPA148",
148
+ "validation_slide": "SPA127",
149
+ "checkpoint_epoch": 37,
150
+ "parameters": 45971074,
151
+ "test_pcc200": 0.3798230854871934,
152
+ "files": {
153
+ "model.safetensors": {
154
+ "sha256": "254fc5a129245998360cdcac313dd3d1c84b2a3feefbf4ce33689a81509c740d",
155
+ "bytes": 183903592
156
+ },
157
+ "config.json": {
158
+ "sha256": "9ee562a453368b8417446dff676b746e98462dacbac5f3e283854b771a4db152",
159
+ "bytes": 2238
160
+ },
161
+ "genes.json": {
162
+ "sha256": "1807423efcd65ee9358dd4a26fe2c3164dbcb80c0141878674e623689023ba7b",
163
+ "bytes": 2223
164
+ }
165
+ }
166
+ },
167
+ {
168
+ "setting": "single-patch",
169
+ "dataset": "lung",
170
+ "panel": "hmhvg",
171
+ "directory": "models/single-patch/lung/hmhvg",
172
+ "fold": 0,
173
+ "seed": 42,
174
+ "test_slide": "NCBI856",
175
+ "validation_slide": "NCBI860",
176
+ "checkpoint_epoch": 7,
177
+ "parameters": 45971074,
178
+ "test_pcc200": 0.8717158056511088,
179
+ "files": {
180
+ "model.safetensors": {
181
+ "sha256": "dcbde320a1df51a876a4c0797983d160f5deb3e4bae0f402af6af97b52ccc2f5",
182
+ "bytes": 183903592
183
+ },
184
+ "config.json": {
185
+ "sha256": "42276a98dcd0db5323082add208743170033080beacba623befd680fd0f02bc9",
186
+ "bytes": 1997
187
+ },
188
+ "genes.json": {
189
+ "sha256": "8a3a986d63531aeff3abb02d59014533ff3893738961e3d4e15735c9c0bf53ca",
190
+ "bytes": 2196
191
+ }
192
+ }
193
+ },
194
+ {
195
+ "setting": "single-patch",
196
+ "dataset": "lung",
197
+ "panel": "hvg",
198
+ "directory": "models/single-patch/lung/hvg",
199
+ "fold": 0,
200
+ "seed": 42,
201
+ "test_slide": "NCBI856",
202
+ "validation_slide": "NCBI860",
203
+ "checkpoint_epoch": 8,
204
+ "parameters": 45971074,
205
+ "test_pcc200": 0.4954411997870103,
206
+ "files": {
207
+ "model.safetensors": {
208
+ "sha256": "f41735851688f4b7368d890c84527a2ba93a620c3df10095029149a5f0d5db6d",
209
+ "bytes": 183903592
210
+ },
211
+ "config.json": {
212
+ "sha256": "5b4d6426c97c17e1876d8ef9ba1e09689c423da409d86fc6bd6e39839b65971c",
213
+ "bytes": 1996
214
+ },
215
+ "genes.json": {
216
+ "sha256": "b8661251c651801dad15bda1ceaaad59736790fdb3d110d4adb5f8c3aeff0026",
217
+ "bytes": 4216
218
+ }
219
+ }
220
+ },
221
+ {
222
+ "setting": "single-patch",
223
+ "dataset": "prad",
224
+ "panel": "hmhvg",
225
+ "directory": "models/single-patch/prad/hmhvg",
226
+ "fold": 0,
227
+ "seed": 42,
228
+ "test_slide": "MEND145",
229
+ "validation_slide": "MEND142",
230
+ "checkpoint_epoch": 9,
231
+ "parameters": 45971074,
232
+ "test_pcc200": 0.556121254362732,
233
+ "files": {
234
+ "model.safetensors": {
235
+ "sha256": "ce7d28e32b4a84c0f0cba6f0561b22a997de7e9202c970968e767b2e71257142",
236
+ "bytes": 183903592
237
+ },
238
+ "config.json": {
239
+ "sha256": "19ddd3b57706c2ea759d1a3066428b35596fec2d19ccfd74498e689681566fc8",
240
+ "bytes": 2045
241
+ },
242
+ "genes.json": {
243
+ "sha256": "d08cd995114d1fa0bff9574535425e8f8e1f1dfb27b490ff0ac135ed695c93fa",
244
+ "bytes": 2188
245
+ }
246
+ }
247
+ },
248
+ {
249
+ "setting": "single-patch",
250
+ "dataset": "prad",
251
+ "panel": "hvg",
252
+ "directory": "models/single-patch/prad/hvg",
253
+ "fold": 0,
254
+ "seed": 42,
255
+ "test_slide": "MEND145",
256
+ "validation_slide": "MEND142",
257
+ "checkpoint_epoch": 12,
258
+ "parameters": 45971074,
259
+ "test_pcc200": 0.2199021112938024,
260
+ "files": {
261
+ "model.safetensors": {
262
+ "sha256": "4f297f40eab72aa2e7706892106ee4428584e7604d0ef91a12272acde8aa60cf",
263
+ "bytes": 183903592
264
+ },
265
+ "config.json": {
266
+ "sha256": "5900eebd65c4d4a7c55f5a18abaa9cdd51a1a1362ed214b288a3a7527f351409",
267
+ "bytes": 2051
268
+ },
269
+ "genes.json": {
270
+ "sha256": "7ec83111bb5c60fbe0cc4d7a524e63a604bddc377fb99a719f13618680445e2d",
271
+ "bytes": 2242
272
+ }
273
+ }
274
+ }
275
+ ]
276
+ }
models/single-patch/brain/hmhvg/config.json ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "format_version": 1,
3
+ "architecture": "SimpleP2G",
4
+ "setting": "single-patch",
5
+ "dataset": "brain",
6
+ "panel": "hmhvg",
7
+ "fold": 0,
8
+ "seed": 42,
9
+ "model_config": {
10
+ "decoder_depth": 12,
11
+ "num_genes": 200,
12
+ "hidden_size": 384,
13
+ "cond_size": 2560,
14
+ "num_cond_tokens": 4,
15
+ "num_heads": 6,
16
+ "loss_name": "gaussian_nll",
17
+ "dropout": 0.05
18
+ },
19
+ "input": {
20
+ "representation": "frozen Virchow2 CLS token concatenated with mean patch tokens",
21
+ "embedding_dimension": 2560,
22
+ "image_encoder_weights_included": false
23
+ },
24
+ "output": {
25
+ "num_genes": 200,
26
+ "gene_order": "genes.json",
27
+ "expression_scale": "log2(raw_count + 1)",
28
+ "returns": [
29
+ "expression_mean",
30
+ "log_variance"
31
+ ]
32
+ },
33
+ "checkpoint": {
34
+ "epoch": 12,
35
+ "weights": "ema",
36
+ "selection": "highest validation-slide PCC-200; earliest epoch breaks ties"
37
+ },
38
+ "training": {
39
+ "epochs": 100,
40
+ "batch_size": 256,
41
+ "optimizer": {
42
+ "name": "adamw",
43
+ "lr": 5e-05,
44
+ "weight_decay": 0.05,
45
+ "betas": [
46
+ 0.9,
47
+ 0.999
48
+ ]
49
+ },
50
+ "loss": "gaussian_nll",
51
+ "precision": "fp16",
52
+ "ema_decay": 0.999,
53
+ "sampling": "pooled spots"
54
+ },
55
+ "split": {
56
+ "training_slides": [
57
+ "NCBI658",
58
+ "NCBI659",
59
+ "NCBI660",
60
+ "NCBI661",
61
+ "NCBI662",
62
+ "NCBI663",
63
+ "NCBI664",
64
+ "NCBI665",
65
+ "NCBI666",
66
+ "NCBI668",
67
+ "NCBI669",
68
+ "NCBI670"
69
+ ],
70
+ "validation_slide": "NCBI671",
71
+ "test_slide": "NCBI667"
72
+ },
73
+ "validation_metrics": {
74
+ "PCC10": 0.6837345136688756,
75
+ "PCC50": 0.5748279101783605,
76
+ "PCC200": 0.4576825647353083,
77
+ "MSE": 0.7553753852844238,
78
+ "MAE": 0.6992919445037842
79
+ },
80
+ "test_metrics": {
81
+ "PCC10": 0.5845393964585056,
82
+ "PCC50": 0.5154498406392661,
83
+ "PCC200": 0.3803240847090443,
84
+ "MSE": 0.9970911145210266,
85
+ "MAE": 0.7918735146522522
86
+ }
87
+ }
models/single-patch/brain/hmhvg/genes.json ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ "1110008P14Rik",
3
+ "6330403K07Rik",
4
+ "Apod",
5
+ "Apoe",
6
+ "App",
7
+ "Arpp19",
8
+ "Arpp21",
9
+ "Atp1a1",
10
+ "Atp1a2",
11
+ "Atp1b1",
12
+ "Atp2a2",
13
+ "Atp2b2",
14
+ "Atp5b",
15
+ "Atp5e",
16
+ "Atp5g1",
17
+ "Atp5o",
18
+ "Atp6v1e1",
19
+ "Baiap2",
20
+ "Basp1",
21
+ "Bc1",
22
+ "Bex2",
23
+ "Bsg",
24
+ "Calm2",
25
+ "Calm3",
26
+ "Camk2a",
27
+ "Camk2n1",
28
+ "Camkv",
29
+ "Cartpt",
30
+ "Cck",
31
+ "Cd81",
32
+ "Cfl1",
33
+ "Chgb",
34
+ "Chn1",
35
+ "Chst1",
36
+ "Ckb",
37
+ "Clstn1",
38
+ "Cnp",
39
+ "Cox5a",
40
+ "Cox7b",
41
+ "Cox7c",
42
+ "Cox8a",
43
+ "Cplx1",
44
+ "Cplx2",
45
+ "Cryab",
46
+ "Cst3",
47
+ "Ctsd",
48
+ "Ctxn1",
49
+ "Dbi",
50
+ "Dclk1",
51
+ "Dnm1",
52
+ "Dpysl2",
53
+ "Dynll1",
54
+ "Dynll2",
55
+ "Eef1a1",
56
+ "Enc1",
57
+ "Eno1",
58
+ "Eno2",
59
+ "Fis1",
60
+ "Fkbp1a",
61
+ "Fkbp8",
62
+ "Fth1",
63
+ "Gaa",
64
+ "Gabra1",
65
+ "Gad1",
66
+ "Gdi1",
67
+ "Gm42418",
68
+ "Gnao1",
69
+ "Gnas",
70
+ "Gng3",
71
+ "Gpi1",
72
+ "Gpm6a",
73
+ "Gpr88",
74
+ "Gprasp1",
75
+ "Hba-a1",
76
+ "Hba-a2",
77
+ "Hbb-bs",
78
+ "Hint1",
79
+ "Hpca",
80
+ "Hspa8",
81
+ "Kif1a",
82
+ "Kif5a",
83
+ "Lrrc17",
84
+ "Ly6h",
85
+ "Maged1",
86
+ "Malat1",
87
+ "Mbp",
88
+ "Mdh2",
89
+ "Meg3",
90
+ "Mlf2",
91
+ "Mobp",
92
+ "Mrfap1",
93
+ "Mt1",
94
+ "Myl6",
95
+ "Naca",
96
+ "Nap1l5",
97
+ "Ncdn",
98
+ "Ndfip1",
99
+ "Ndrg2",
100
+ "Ndufa12",
101
+ "Ndufa3",
102
+ "Ndufa4",
103
+ "Ndufb4",
104
+ "Ndufb9",
105
+ "Ndufc1",
106
+ "Nisch",
107
+ "Nnat",
108
+ "Nptxr",
109
+ "Nrgn",
110
+ "Nsf",
111
+ "Oaz1",
112
+ "Ociad1",
113
+ "Olfm1",
114
+ "Pcp4",
115
+ "Pde1b",
116
+ "Pea15a",
117
+ "Penk",
118
+ "Pfdn5",
119
+ "Pja2",
120
+ "Plp1",
121
+ "Ppp1r1b",
122
+ "Ppp3ca",
123
+ "Prkar1b",
124
+ "Ptgds",
125
+ "Ptma",
126
+ "Ptprn",
127
+ "Pvalb",
128
+ "Rab3a",
129
+ "Rac1",
130
+ "Rpl10",
131
+ "Rpl13",
132
+ "Rpl14",
133
+ "Rpl18",
134
+ "Rpl18a",
135
+ "Rpl19",
136
+ "Rpl22l1",
137
+ "Rpl23a",
138
+ "Rpl27",
139
+ "Rpl32",
140
+ "Rpl34",
141
+ "Rpl36a",
142
+ "Rpl37",
143
+ "Rpl39",
144
+ "Rpl4",
145
+ "Rpl5",
146
+ "Rpl6",
147
+ "Rpl7",
148
+ "Rpl9",
149
+ "Rps12",
150
+ "Rps15a",
151
+ "Rps17",
152
+ "Rps18",
153
+ "Rps19",
154
+ "Rps2",
155
+ "Rps23",
156
+ "Rps24",
157
+ "Rps27a",
158
+ "Rps3",
159
+ "Rps4x",
160
+ "Rps6",
161
+ "Rps7",
162
+ "Rtn4",
163
+ "Scd2",
164
+ "Scn1b",
165
+ "Selenow",
166
+ "Serf2",
167
+ "Sez6l2",
168
+ "Slc17a7",
169
+ "Slc1a2",
170
+ "Slc22a17",
171
+ "Slc25a5",
172
+ "Snap25",
173
+ "Snap47",
174
+ "Snca",
175
+ "Snrpn",
176
+ "Sod1",
177
+ "Sparcl1",
178
+ "Sst",
179
+ "Stmn1",
180
+ "Stmn3",
181
+ "Stmn4",
182
+ "Sub1",
183
+ "Syn1",
184
+ "Syn2",
185
+ "Syngr1",
186
+ "Syt11",
187
+ "Tmsb10",
188
+ "Tmsb4x",
189
+ "Tpi1",
190
+ "Trf",
191
+ "Tuba1a",
192
+ "Tubb2a",
193
+ "Tubb4a",
194
+ "Tubb5",
195
+ "Ubl5",
196
+ "Uchl1",
197
+ "Uqcrh",
198
+ "Vsnl1",
199
+ "Wbp2",
200
+ "Ywhag",
201
+ "Ywhah"
202
+ ]
models/single-patch/brain/hmhvg/model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:30e10f1adc24365ff8ae5d3e7851e3336dfdd1775b0a8640ba94fd46630633de
3
+ size 183903592
models/single-patch/brain/hvg/config.json ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "format_version": 1,
3
+ "architecture": "SimpleP2G",
4
+ "setting": "single-patch",
5
+ "dataset": "brain",
6
+ "panel": "hvg",
7
+ "fold": 0,
8
+ "seed": 42,
9
+ "model_config": {
10
+ "decoder_depth": 12,
11
+ "num_genes": 200,
12
+ "hidden_size": 384,
13
+ "cond_size": 2560,
14
+ "num_cond_tokens": 4,
15
+ "num_heads": 6,
16
+ "loss_name": "gaussian_nll",
17
+ "dropout": 0.05
18
+ },
19
+ "input": {
20
+ "representation": "frozen Virchow2 CLS token concatenated with mean patch tokens",
21
+ "embedding_dimension": 2560,
22
+ "image_encoder_weights_included": false
23
+ },
24
+ "output": {
25
+ "num_genes": 200,
26
+ "gene_order": "genes.json",
27
+ "expression_scale": "log2(raw_count + 1)",
28
+ "returns": [
29
+ "expression_mean",
30
+ "log_variance"
31
+ ]
32
+ },
33
+ "checkpoint": {
34
+ "epoch": 16,
35
+ "weights": "ema",
36
+ "selection": "highest validation-slide PCC-200; earliest epoch breaks ties"
37
+ },
38
+ "training": {
39
+ "epochs": 100,
40
+ "batch_size": 256,
41
+ "optimizer": {
42
+ "name": "adamw",
43
+ "lr": 5e-05,
44
+ "weight_decay": 0.05,
45
+ "betas": [
46
+ 0.9,
47
+ 0.999
48
+ ]
49
+ },
50
+ "loss": "gaussian_nll",
51
+ "precision": "fp16",
52
+ "ema_decay": 0.999,
53
+ "sampling": "pooled spots"
54
+ },
55
+ "split": {
56
+ "training_slides": [
57
+ "NCBI658",
58
+ "NCBI659",
59
+ "NCBI660",
60
+ "NCBI661",
61
+ "NCBI662",
62
+ "NCBI663",
63
+ "NCBI664",
64
+ "NCBI665",
65
+ "NCBI666",
66
+ "NCBI668",
67
+ "NCBI669",
68
+ "NCBI670"
69
+ ],
70
+ "validation_slide": "NCBI671",
71
+ "test_slide": "NCBI667"
72
+ },
73
+ "validation_metrics": {
74
+ "PCC10": 0.5519836169944861,
75
+ "PCC50": 0.41539179241866847,
76
+ "PCC200": 0.21614730186065806,
77
+ "MSE": 0.20960445702075958,
78
+ "MAE": 0.2335881143808365
79
+ },
80
+ "test_metrics": {
81
+ "PCC10": 0.47346420145244456,
82
+ "PCC50": 0.34249158576801364,
83
+ "PCC200": 0.1689760419646251,
84
+ "MSE": 0.22083990275859833,
85
+ "MAE": 0.24713166058063507
86
+ }
87
+ }
models/single-patch/brain/hvg/genes.json ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ "1700052K11Rik",
3
+ "1810010H24Rik",
4
+ "2810468N07Rik",
5
+ "4932438A13Rik",
6
+ "9530059O14Rik",
7
+ "A930004D18Rik",
8
+ "Ackr1",
9
+ "Acta2",
10
+ "Aebp1",
11
+ "Ahnak",
12
+ "Aldh1a1",
13
+ "Anapc16",
14
+ "Anln",
15
+ "Apod",
16
+ "Arid4a",
17
+ "As3mt",
18
+ "Ascc2",
19
+ "Ascl1",
20
+ "Atg4c",
21
+ "B930036N10Rik",
22
+ "Bbs2",
23
+ "Bcas1",
24
+ "Bfsp2",
25
+ "C1qc",
26
+ "C1ql1",
27
+ "C3",
28
+ "C4b",
29
+ "C78859",
30
+ "Cadm1",
31
+ "Calb2",
32
+ "Car2",
33
+ "Card19",
34
+ "Cartpt",
35
+ "Ccdc153",
36
+ "Ccl24",
37
+ "Cd2ap",
38
+ "Cd74",
39
+ "Cd9",
40
+ "Cdr1os",
41
+ "Celsr3",
42
+ "Cldn11",
43
+ "Cnp",
44
+ "Coro1b",
45
+ "Cort",
46
+ "Cplx3",
47
+ "Cryab",
48
+ "Cryl1",
49
+ "Csrp1",
50
+ "Dbndd2",
51
+ "Dexi",
52
+ "Enpp2",
53
+ "Enpp6",
54
+ "Eps8l2",
55
+ "Ermn",
56
+ "Fa2h",
57
+ "Fabp3",
58
+ "Fam53b",
59
+ "Fcgr2b",
60
+ "Fkbp9",
61
+ "Fnbp1",
62
+ "Foxc1",
63
+ "Fuca1",
64
+ "Fxyd1",
65
+ "Gal3st1",
66
+ "Gask1b",
67
+ "Gatm",
68
+ "Gfap",
69
+ "Gjc2",
70
+ "Gjc3",
71
+ "Gm16323",
72
+ "Gm20594",
73
+ "Gm30906",
74
+ "Gm33195",
75
+ "Gnrh1",
76
+ "Gpr37",
77
+ "Gpx3",
78
+ "Grb14",
79
+ "Gsn",
80
+ "Hba-a1",
81
+ "Hba-a2",
82
+ "Hbb-bs",
83
+ "Hbb-bt",
84
+ "Iars",
85
+ "Igf2",
86
+ "Il17rc",
87
+ "Kap",
88
+ "Kcna4",
89
+ "Kcnmb4",
90
+ "Kif21b",
91
+ "Kif7",
92
+ "Larp4",
93
+ "Lars2",
94
+ "Lcn2",
95
+ "Litaf",
96
+ "Lpar1",
97
+ "Lyz2",
98
+ "Lzic",
99
+ "Mag",
100
+ "Mal",
101
+ "Map6d1",
102
+ "Mdm2",
103
+ "Metrn",
104
+ "Mfsd14b",
105
+ "Mgp",
106
+ "Mobp",
107
+ "Mog",
108
+ "Myoc",
109
+ "N4bp2l1",
110
+ "Nab1",
111
+ "Ndrg1",
112
+ "Neat1",
113
+ "Nif3l1",
114
+ "Nit1",
115
+ "Nnat",
116
+ "Npy",
117
+ "Nr3c1",
118
+ "Nyap1",
119
+ "Opalin",
120
+ "Ostf1",
121
+ "Pacs2",
122
+ "Padi2",
123
+ "Pcdhga7",
124
+ "Pcsk6",
125
+ "Pdlim2",
126
+ "Pgd",
127
+ "Phf6",
128
+ "Phldb1",
129
+ "Pisd",
130
+ "Plekhb1",
131
+ "Pllp",
132
+ "Plp1",
133
+ "Poglut1",
134
+ "Ppard",
135
+ "Ppp1r14a",
136
+ "Prkcd",
137
+ "Prr18",
138
+ "Ptgds",
139
+ "Pth2",
140
+ "Pvalb",
141
+ "Pxn",
142
+ "Rab7b",
143
+ "Rad1",
144
+ "Rarres2",
145
+ "Rhog",
146
+ "Rnf122",
147
+ "Rpap3",
148
+ "Rps19bp1",
149
+ "S100a6",
150
+ "S100a8",
151
+ "S100a9",
152
+ "Sac3d1",
153
+ "Samd1",
154
+ "Scgb1a1",
155
+ "Sepsecs",
156
+ "Sept4",
157
+ "Sgcb",
158
+ "Shtn1",
159
+ "Sirt4",
160
+ "Slain1",
161
+ "Slc17a7",
162
+ "Slc44a1",
163
+ "Slc6a13",
164
+ "Slc6a3",
165
+ "Smg6",
166
+ "Smim1",
167
+ "Sox10",
168
+ "Sox2ot",
169
+ "Sspo",
170
+ "Sst",
171
+ "Steap4",
172
+ "Tap1",
173
+ "Tgif1",
174
+ "Th",
175
+ "Thbs4",
176
+ "Timp1",
177
+ "Tm7sf3",
178
+ "Tmbim1",
179
+ "Tmem178b",
180
+ "Tmem189",
181
+ "Tmem212",
182
+ "Tmem63a",
183
+ "Tmem87b",
184
+ "Tmem88b",
185
+ "Tppp3",
186
+ "Trf",
187
+ "Trim12c",
188
+ "Trim59",
189
+ "Tspan2",
190
+ "Tyrobp",
191
+ "Ucn",
192
+ "Ugt8a",
193
+ "Usp4",
194
+ "Vim",
195
+ "Vip",
196
+ "Vkorc1",
197
+ "Vmac",
198
+ "Vtn",
199
+ "Zfp101",
200
+ "Zfp606",
201
+ "Zfp950"
202
+ ]
models/single-patch/brain/hvg/model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a671becb75830a258455a6136e1be92f5f45ae822c6875290f61edb0f90a9eaa
3
+ size 183903592
models/single-patch/ccrcc/hmhvg/config.json ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "format_version": 1,
3
+ "architecture": "SimpleP2G",
4
+ "setting": "single-patch",
5
+ "dataset": "ccrcc",
6
+ "panel": "hmhvg",
7
+ "fold": 0,
8
+ "seed": 42,
9
+ "model_config": {
10
+ "decoder_depth": 12,
11
+ "num_genes": 200,
12
+ "hidden_size": 384,
13
+ "cond_size": 2560,
14
+ "num_cond_tokens": 4,
15
+ "num_heads": 6,
16
+ "loss_name": "gaussian_nll",
17
+ "dropout": 0.1
18
+ },
19
+ "input": {
20
+ "representation": "frozen Virchow2 CLS token concatenated with mean patch tokens",
21
+ "embedding_dimension": 2560,
22
+ "image_encoder_weights_included": false
23
+ },
24
+ "output": {
25
+ "num_genes": 200,
26
+ "gene_order": "genes.json",
27
+ "expression_scale": "log2(raw_count + 1)",
28
+ "returns": [
29
+ "expression_mean",
30
+ "log_variance"
31
+ ]
32
+ },
33
+ "checkpoint": {
34
+ "epoch": 19,
35
+ "weights": "ema",
36
+ "selection": "highest validation-slide PCC-200; earliest epoch breaks ties"
37
+ },
38
+ "training": {
39
+ "epochs": 100,
40
+ "batch_size": 256,
41
+ "optimizer": {
42
+ "name": "adamw",
43
+ "lr": 3e-05,
44
+ "weight_decay": 0.1,
45
+ "betas": [
46
+ 0.9,
47
+ 0.999
48
+ ]
49
+ },
50
+ "loss": "gaussian_nll",
51
+ "precision": "fp16",
52
+ "ema_decay": 0.999,
53
+ "sampling": "pooled spots"
54
+ },
55
+ "split": {
56
+ "training_slides": [
57
+ "INT1",
58
+ "INT10",
59
+ "INT11",
60
+ "INT12",
61
+ "INT13",
62
+ "INT14",
63
+ "INT15",
64
+ "INT16",
65
+ "INT17",
66
+ "INT18",
67
+ "INT19",
68
+ "INT20",
69
+ "INT21",
70
+ "INT22",
71
+ "INT23",
72
+ "INT24",
73
+ "INT3",
74
+ "INT4",
75
+ "INT5",
76
+ "INT6",
77
+ "INT7",
78
+ "INT8"
79
+ ],
80
+ "validation_slide": "INT9",
81
+ "test_slide": "INT2"
82
+ },
83
+ "validation_metrics": {
84
+ "PCC10": 0.6926724980557916,
85
+ "PCC50": 0.6391818018883983,
86
+ "PCC200": 0.42965969649900465,
87
+ "MSE": 2.185840368270874,
88
+ "MAE": 1.17231023311615
89
+ },
90
+ "test_metrics": {
91
+ "PCC10": 0.502469291003792,
92
+ "PCC50": 0.4121004550758145,
93
+ "PCC200": 0.27036171397452496,
94
+ "MSE": 1.6523619890213013,
95
+ "MAE": 0.9979413747787476
96
+ }
97
+ }
models/single-patch/ccrcc/hmhvg/genes.json ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ "A2M",
3
+ "ACTA2",
4
+ "ACTB",
5
+ "ADIRF",
6
+ "AEBP1",
7
+ "ANGPTL4",
8
+ "ANPEP",
9
+ "ANXA2",
10
+ "APOC1",
11
+ "APOE",
12
+ "APOL1",
13
+ "APP",
14
+ "ARF1",
15
+ "ARPC1B",
16
+ "ARPC2",
17
+ "ATP1A1",
18
+ "ATP1B1",
19
+ "ATP5F1B",
20
+ "ATP5MC2",
21
+ "ATP5ME",
22
+ "B2M",
23
+ "BGN",
24
+ "BIRC3",
25
+ "BSG",
26
+ "BST2",
27
+ "C19orf33",
28
+ "C1QA",
29
+ "C1QB",
30
+ "C1QC",
31
+ "C1R",
32
+ "C1S",
33
+ "C3",
34
+ "CA12",
35
+ "CALD1",
36
+ "CANX",
37
+ "CCDC91",
38
+ "CCN2",
39
+ "CCNI",
40
+ "CD24",
41
+ "CD44",
42
+ "CD63",
43
+ "CD74",
44
+ "CD81",
45
+ "CD99",
46
+ "CEBPD",
47
+ "CHCHD2",
48
+ "CIRBP",
49
+ "CLU",
50
+ "COL18A1",
51
+ "COL1A1",
52
+ "COL1A2",
53
+ "COL3A1",
54
+ "COL4A1",
55
+ "COL4A2",
56
+ "COL6A1",
57
+ "COL6A2",
58
+ "COL6A3",
59
+ "CP",
60
+ "CPE",
61
+ "CRYAB",
62
+ "CST3",
63
+ "CSTB",
64
+ "CTSB",
65
+ "CTSD",
66
+ "CTSZ",
67
+ "CYB5A",
68
+ "CYB5R3",
69
+ "DCN",
70
+ "DDIT4",
71
+ "DDX17",
72
+ "DEPP1",
73
+ "DUSP1",
74
+ "EEF1G",
75
+ "EIF1",
76
+ "EIF4G2",
77
+ "EIF4H",
78
+ "ENPP3",
79
+ "FABP7",
80
+ "FGB",
81
+ "FKBP5",
82
+ "FLNA",
83
+ "FN1",
84
+ "FOS",
85
+ "FTH1",
86
+ "FTL",
87
+ "FXYD2",
88
+ "GABARAP",
89
+ "GLUL",
90
+ "GPX3",
91
+ "GSN",
92
+ "GSTP1",
93
+ "HINT1",
94
+ "HIST1H4C",
95
+ "HLA-A",
96
+ "HLA-DPA1",
97
+ "HLA-DPB1",
98
+ "HLA-DQB1",
99
+ "HLA-DRA",
100
+ "HLA-DRB1",
101
+ "HNRNPA2B1",
102
+ "HNRNPA3",
103
+ "HSP90AA1",
104
+ "HSP90B1",
105
+ "HSPA8",
106
+ "HSPD1",
107
+ "HTRA1",
108
+ "IFI27",
109
+ "IFI30",
110
+ "IFI6",
111
+ "IFITM2",
112
+ "IGFBP3",
113
+ "IGFBP4",
114
+ "IGFBP5",
115
+ "IGFBP7",
116
+ "IGHA1",
117
+ "IGHG1",
118
+ "IGHG2",
119
+ "IGHG3",
120
+ "IGHG4",
121
+ "IGHM",
122
+ "IGKC",
123
+ "IGLC1",
124
+ "IL32",
125
+ "ITGA3",
126
+ "ITGB1",
127
+ "JCHAIN",
128
+ "KRT8",
129
+ "LAPTM5",
130
+ "LGALS1",
131
+ "LGALS3BP",
132
+ "LY6E",
133
+ "LYZ",
134
+ "MGP",
135
+ "MIF",
136
+ "MMP7",
137
+ "MMP9",
138
+ "MYH9",
139
+ "MYL9",
140
+ "NDRG1",
141
+ "NDUFA4L2",
142
+ "NME2",
143
+ "NPC2",
144
+ "NUPR1",
145
+ "P4HB",
146
+ "PARK7",
147
+ "PCBP1",
148
+ "PCBP2",
149
+ "PDIA6",
150
+ "PDK4",
151
+ "PDZK1IP1",
152
+ "PFDN5",
153
+ "PFKP",
154
+ "PGAM1",
155
+ "PGF",
156
+ "PLEC",
157
+ "PLIN2",
158
+ "PLOD2",
159
+ "PPDPF",
160
+ "PRDX6",
161
+ "PRR13",
162
+ "PTMA",
163
+ "PTMS",
164
+ "PTTG1IP",
165
+ "RARRES2",
166
+ "RGS5",
167
+ "RHOB",
168
+ "RNASET2",
169
+ "S100A11",
170
+ "S100A6",
171
+ "SAT1",
172
+ "SCD",
173
+ "SERPINA1",
174
+ "SERPINE1",
175
+ "SERPING1",
176
+ "SOD2",
177
+ "SPARC",
178
+ "SPP1",
179
+ "SQSTM1",
180
+ "SRRM2",
181
+ "SSR4",
182
+ "TAGLN",
183
+ "TAGLN2",
184
+ "TGFBI",
185
+ "TGM2",
186
+ "TIMP1",
187
+ "TIMP3",
188
+ "TMBIM6",
189
+ "TMSB4X",
190
+ "TOMM7",
191
+ "TPM1",
192
+ "TPM2",
193
+ "TSC22D3",
194
+ "TUBA1B",
195
+ "TXNIP",
196
+ "TYROBP",
197
+ "UBC",
198
+ "UQCRQ",
199
+ "VEGFA",
200
+ "VIM",
201
+ "VWF"
202
+ ]
models/single-patch/ccrcc/hmhvg/model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c913908cfee0f4712e5680140c1e3d5ee86baac1278bf65a7da97f24985f8aa2
3
+ size 183903592
models/single-patch/ccrcc/hvg/config.json ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "format_version": 1,
3
+ "architecture": "SimpleP2G",
4
+ "setting": "single-patch",
5
+ "dataset": "ccrcc",
6
+ "panel": "hvg",
7
+ "fold": 0,
8
+ "seed": 42,
9
+ "model_config": {
10
+ "decoder_depth": 12,
11
+ "num_genes": 200,
12
+ "hidden_size": 384,
13
+ "cond_size": 2560,
14
+ "num_cond_tokens": 4,
15
+ "num_heads": 6,
16
+ "loss_name": "gaussian_nll",
17
+ "dropout": 0.1
18
+ },
19
+ "input": {
20
+ "representation": "frozen Virchow2 CLS token concatenated with mean patch tokens",
21
+ "embedding_dimension": 2560,
22
+ "image_encoder_weights_included": false
23
+ },
24
+ "output": {
25
+ "num_genes": 200,
26
+ "gene_order": "genes.json",
27
+ "expression_scale": "log2(raw_count + 1)",
28
+ "returns": [
29
+ "expression_mean",
30
+ "log_variance"
31
+ ]
32
+ },
33
+ "checkpoint": {
34
+ "epoch": 7,
35
+ "weights": "ema",
36
+ "selection": "highest validation-slide PCC-200; earliest epoch breaks ties"
37
+ },
38
+ "training": {
39
+ "epochs": 100,
40
+ "batch_size": 256,
41
+ "optimizer": {
42
+ "name": "adamw",
43
+ "lr": 3e-05,
44
+ "weight_decay": 0.1,
45
+ "betas": [
46
+ 0.9,
47
+ 0.999
48
+ ]
49
+ },
50
+ "loss": "gaussian_nll",
51
+ "precision": "fp16",
52
+ "ema_decay": 0.999,
53
+ "sampling": "pooled spots"
54
+ },
55
+ "split": {
56
+ "training_slides": [
57
+ "INT1",
58
+ "INT10",
59
+ "INT11",
60
+ "INT12",
61
+ "INT13",
62
+ "INT14",
63
+ "INT15",
64
+ "INT16",
65
+ "INT17",
66
+ "INT18",
67
+ "INT19",
68
+ "INT20",
69
+ "INT21",
70
+ "INT22",
71
+ "INT23",
72
+ "INT24",
73
+ "INT3",
74
+ "INT4",
75
+ "INT5",
76
+ "INT6",
77
+ "INT7",
78
+ "INT8"
79
+ ],
80
+ "validation_slide": "INT9",
81
+ "test_slide": "INT2"
82
+ },
83
+ "validation_metrics": {
84
+ "PCC10": 0.5082438063563466,
85
+ "PCC50": 0.2864946574885263,
86
+ "PCC200": 0.11651308085853335,
87
+ "MSE": 0.5486487746238708,
88
+ "MAE": 0.4507647454738617
89
+ },
90
+ "test_metrics": {
91
+ "PCC10": 0.3779823666623128,
92
+ "PCC50": 0.24105083678052494,
93
+ "PCC200": 0.10978539095367261,
94
+ "MSE": 0.5488066077232361,
95
+ "MAE": 0.4156813621520996
96
+ }
97
+ }
models/single-patch/ccrcc/hvg/genes.json ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ "ACKR1",
3
+ "ACTA2",
4
+ "ACTC1",
5
+ "ACTG2",
6
+ "AEBP1",
7
+ "AIF1L",
8
+ "ALDOB",
9
+ "ANKRD1",
10
+ "APOD",
11
+ "AQP1",
12
+ "ARPC3",
13
+ "BANK1",
14
+ "BLK",
15
+ "BRIX1",
16
+ "C11orf96",
17
+ "C1orf198",
18
+ "C7",
19
+ "CAMP",
20
+ "CBL",
21
+ "CCDC80",
22
+ "CCDC91",
23
+ "CCL14",
24
+ "CCL18",
25
+ "CCL19",
26
+ "CCL2",
27
+ "CCL21",
28
+ "CCL5",
29
+ "CCL8",
30
+ "CCN2",
31
+ "CCN3",
32
+ "CD209",
33
+ "CD79A",
34
+ "CD8A",
35
+ "CFAP97D1",
36
+ "CHIT1",
37
+ "CLDN5",
38
+ "CLIC6",
39
+ "CLU",
40
+ "CNN1",
41
+ "COL1A1",
42
+ "COL1A2",
43
+ "CR2",
44
+ "CRIP1",
45
+ "CRYBG3",
46
+ "CTSK",
47
+ "CTSS",
48
+ "CXCL10",
49
+ "CXCL11",
50
+ "CXCL12",
51
+ "CXCL13",
52
+ "CXCL8",
53
+ "CXCL9",
54
+ "DCN",
55
+ "DERL3",
56
+ "DES",
57
+ "DGKA",
58
+ "DSG4",
59
+ "ELMO1",
60
+ "ELN",
61
+ "ENPP2",
62
+ "F13A1",
63
+ "FABP7",
64
+ "FAM102A",
65
+ "FBLN1",
66
+ "FBLN2",
67
+ "FBLN5",
68
+ "FBXW7",
69
+ "FCRL1",
70
+ "FDCSP",
71
+ "FN1",
72
+ "FOS",
73
+ "FOSB",
74
+ "FRZB",
75
+ "G0S2",
76
+ "GART",
77
+ "GJA9",
78
+ "GNLY",
79
+ "GPNMB",
80
+ "GREM1",
81
+ "GUCY2D",
82
+ "GZMB",
83
+ "HBA1",
84
+ "HBA2",
85
+ "HP",
86
+ "HSPA1A",
87
+ "HSPA1B",
88
+ "HSPA6",
89
+ "HSPB6",
90
+ "IGF1",
91
+ "IGHA1",
92
+ "IGHA2",
93
+ "IGHD",
94
+ "IGHG1",
95
+ "IGHG2",
96
+ "IGHG3",
97
+ "IGHG4",
98
+ "IGHJ2",
99
+ "IGHJ6",
100
+ "IGHM",
101
+ "IGHV1-46",
102
+ "IGHV5-10-1",
103
+ "IGHV6-1",
104
+ "IGKC",
105
+ "IGKV4-1",
106
+ "IGKV5-2",
107
+ "IGLC1",
108
+ "IGLC7",
109
+ "IGLV3-1",
110
+ "IGLV6-57",
111
+ "IGLV9-49",
112
+ "IL2RG",
113
+ "IL7R",
114
+ "INHBA",
115
+ "INMT",
116
+ "ISG15",
117
+ "ITGB6",
118
+ "JCHAIN",
119
+ "KCNK6",
120
+ "KLK10",
121
+ "KRT7",
122
+ "LCN2",
123
+ "LCP1",
124
+ "LHFPL6",
125
+ "LMOD1",
126
+ "LTB",
127
+ "LTBP2",
128
+ "LTF",
129
+ "LUM",
130
+ "MFAP4",
131
+ "MFGE8",
132
+ "MFSD11",
133
+ "MGP",
134
+ "MMP11",
135
+ "MMP2",
136
+ "MMP7",
137
+ "MMP9",
138
+ "MT1G",
139
+ "MT1H",
140
+ "MT1X",
141
+ "MTRNR2L8",
142
+ "MUSTN1",
143
+ "MYH10",
144
+ "MYLK",
145
+ "MYLPF",
146
+ "MZB1",
147
+ "NDUFAF4",
148
+ "NR4A1",
149
+ "PCDH7",
150
+ "PIGR",
151
+ "PIM2",
152
+ "PIP5K1C",
153
+ "PLN",
154
+ "POSTN",
155
+ "POU2AF1",
156
+ "PPP1R14A",
157
+ "PRELP",
158
+ "PRKCB",
159
+ "PSMC3",
160
+ "PTCHD4",
161
+ "PTGDS",
162
+ "PTGIS",
163
+ "PTPRC",
164
+ "REN",
165
+ "RGCC",
166
+ "RNASE1",
167
+ "S100A2",
168
+ "S100A8",
169
+ "S100A9",
170
+ "SAA1",
171
+ "SAA2",
172
+ "SETDB1",
173
+ "SFRP1",
174
+ "SFRP2",
175
+ "SFRP4",
176
+ "SLC11A1",
177
+ "SLPI",
178
+ "SLTM",
179
+ "SOCS3",
180
+ "SOD3",
181
+ "SORBS1",
182
+ "SPP1",
183
+ "SULF1",
184
+ "SVEP1",
185
+ "SYNPO2",
186
+ "TACSTD2",
187
+ "TAGLN",
188
+ "TENT5C",
189
+ "THBS1",
190
+ "THBS2",
191
+ "THBS4",
192
+ "TIMP3",
193
+ "TNC",
194
+ "TNXB",
195
+ "TPM2",
196
+ "TPSB2",
197
+ "TRBC2",
198
+ "TRPM2",
199
+ "TTC27",
200
+ "VWF",
201
+ "YEATS2"
202
+ ]
models/single-patch/ccrcc/hvg/model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:19a643e778694859ee2e25614c7839a5aa237436d575e0c2d1034501311480fb
3
+ size 183903592
models/single-patch/her2st/hmhvg/config.json ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "format_version": 1,
3
+ "architecture": "SimpleP2G",
4
+ "setting": "single-patch",
5
+ "dataset": "her2st",
6
+ "panel": "hmhvg",
7
+ "fold": 0,
8
+ "seed": 42,
9
+ "model_config": {
10
+ "decoder_depth": 12,
11
+ "num_genes": 200,
12
+ "hidden_size": 384,
13
+ "cond_size": 2560,
14
+ "num_cond_tokens": 4,
15
+ "num_heads": 6,
16
+ "loss_name": "gaussian_nll",
17
+ "dropout": 0.0
18
+ },
19
+ "input": {
20
+ "representation": "frozen Virchow2 CLS token concatenated with mean patch tokens",
21
+ "embedding_dimension": 2560,
22
+ "image_encoder_weights_included": false
23
+ },
24
+ "output": {
25
+ "num_genes": 200,
26
+ "gene_order": "genes.json",
27
+ "expression_scale": "log2(raw_count + 1)",
28
+ "returns": [
29
+ "expression_mean",
30
+ "log_variance"
31
+ ]
32
+ },
33
+ "checkpoint": {
34
+ "epoch": 21,
35
+ "weights": "ema",
36
+ "selection": "highest validation-slide PCC-200; earliest epoch breaks ties"
37
+ },
38
+ "training": {
39
+ "epochs": 100,
40
+ "batch_size": 256,
41
+ "optimizer": {
42
+ "name": "adamw",
43
+ "lr": 0.0001,
44
+ "weight_decay": 0.05,
45
+ "betas": [
46
+ 0.9,
47
+ 0.999
48
+ ]
49
+ },
50
+ "loss": "gaussian_nll",
51
+ "precision": "fp16",
52
+ "ema_decay": 0.999,
53
+ "sampling": "pooled spots"
54
+ },
55
+ "split": {
56
+ "training_slides": [
57
+ "SPA119",
58
+ "SPA120",
59
+ "SPA121",
60
+ "SPA122",
61
+ "SPA123",
62
+ "SPA124",
63
+ "SPA125",
64
+ "SPA126",
65
+ "SPA128",
66
+ "SPA129",
67
+ "SPA130",
68
+ "SPA131",
69
+ "SPA132",
70
+ "SPA133",
71
+ "SPA134",
72
+ "SPA135",
73
+ "SPA136",
74
+ "SPA137",
75
+ "SPA138",
76
+ "SPA139",
77
+ "SPA140",
78
+ "SPA141",
79
+ "SPA142",
80
+ "SPA143",
81
+ "SPA144",
82
+ "SPA145",
83
+ "SPA146",
84
+ "SPA147",
85
+ "SPA149",
86
+ "SPA150",
87
+ "SPA151",
88
+ "SPA152",
89
+ "SPA153",
90
+ "SPA154"
91
+ ],
92
+ "validation_slide": "SPA127",
93
+ "test_slide": "SPA148"
94
+ },
95
+ "validation_metrics": {
96
+ "PCC10": 0.456390537005097,
97
+ "PCC50": 0.30044265527694825,
98
+ "PCC200": 0.15609376481639806,
99
+ "MSE": 0.7690321803092957,
100
+ "MAE": 0.6974937915802002
101
+ },
102
+ "test_metrics": {
103
+ "PCC10": 0.8710780333678818,
104
+ "PCC50": 0.822812513630561,
105
+ "PCC200": 0.70892135019349,
106
+ "MSE": 0.8401367664337158,
107
+ "MAE": 0.7023175954818726
108
+ }
109
+ }
models/single-patch/her2st/hmhvg/genes.json ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ "A2M",
3
+ "ACTB",
4
+ "ACTG1",
5
+ "ACTN4",
6
+ "ADAM15",
7
+ "AEBP1",
8
+ "AES",
9
+ "ALDOA",
10
+ "AP000769.1",
11
+ "APOC1",
12
+ "APOE",
13
+ "ARHGDIA",
14
+ "ATG10",
15
+ "ATP5B",
16
+ "ATP5E",
17
+ "ATP6V0B",
18
+ "AZGP1",
19
+ "B2M",
20
+ "BEST1",
21
+ "BGN",
22
+ "BSG",
23
+ "BST2",
24
+ "C12orf57",
25
+ "C1QA",
26
+ "C3",
27
+ "CALM2",
28
+ "CALML5",
29
+ "CALR",
30
+ "CCT3",
31
+ "CD24",
32
+ "CD63",
33
+ "CD74",
34
+ "CFL1",
35
+ "CHCHD2",
36
+ "CHPF",
37
+ "CIB1",
38
+ "CLDN3",
39
+ "CLDN4",
40
+ "CNN3",
41
+ "COL18A1",
42
+ "COL1A1",
43
+ "COL1A2",
44
+ "COL3A1",
45
+ "COL6A2",
46
+ "COMP",
47
+ "COPE",
48
+ "COPS9",
49
+ "COX4I1",
50
+ "COX5B",
51
+ "COX6B1",
52
+ "COX6C",
53
+ "COX7C",
54
+ "CRIP2",
55
+ "CST3",
56
+ "CTSB",
57
+ "CTSD",
58
+ "CYBA",
59
+ "DDX5",
60
+ "DHCR24",
61
+ "EDF1",
62
+ "EEF1D",
63
+ "EEF2",
64
+ "EIF4G1",
65
+ "ELOVL1",
66
+ "ENO1",
67
+ "ERBB2",
68
+ "FASN",
69
+ "FAU",
70
+ "FLNA",
71
+ "FN1",
72
+ "FNBP1L",
73
+ "FTH1",
74
+ "FTL",
75
+ "GAPDH",
76
+ "GNAS",
77
+ "GPX4",
78
+ "GRB7",
79
+ "GRINA",
80
+ "GUK1",
81
+ "H2AFJ",
82
+ "HLA-A",
83
+ "HLA-B",
84
+ "HLA-C",
85
+ "HLA-DRA",
86
+ "HLA-E",
87
+ "HNRNPA2B1",
88
+ "HSP90AA1",
89
+ "HSP90AB1",
90
+ "HSP90B1",
91
+ "HSPA8",
92
+ "HSPB1",
93
+ "IDH2",
94
+ "IFI27",
95
+ "IGFBP2",
96
+ "IGHA1",
97
+ "IGHG1",
98
+ "IGHG3",
99
+ "IGHG4",
100
+ "IGHM",
101
+ "IGKC",
102
+ "IGLC2",
103
+ "IGLC3",
104
+ "INTS1",
105
+ "ISG15",
106
+ "JTB",
107
+ "KDELR1",
108
+ "KRT18",
109
+ "KRT19",
110
+ "KRT7",
111
+ "KRT81",
112
+ "LAPTM4A",
113
+ "LAPTM5",
114
+ "LASP1",
115
+ "LGALS1",
116
+ "LGALS3",
117
+ "LGALS3BP",
118
+ "LMAN2",
119
+ "LMNA",
120
+ "LUM",
121
+ "LY6E",
122
+ "MAPKAPK2",
123
+ "MDK",
124
+ "MGP",
125
+ "MIDN",
126
+ "MIEN1",
127
+ "MLLT6",
128
+ "MMACHC",
129
+ "MMP14",
130
+ "MUC1",
131
+ "MUCL1",
132
+ "MYL6",
133
+ "MYL9",
134
+ "MZT2B",
135
+ "NBL1",
136
+ "NDUFB9",
137
+ "NUCKS1",
138
+ "NUPR1",
139
+ "ORMDL3",
140
+ "P4HB",
141
+ "PCGF2",
142
+ "PEBP1",
143
+ "PERP",
144
+ "PFDN5",
145
+ "PGAP3",
146
+ "PHB",
147
+ "PIP4K2B",
148
+ "PLD3",
149
+ "PNMT",
150
+ "POSTN",
151
+ "PPDPF",
152
+ "PPP1CA",
153
+ "PPP1R1B",
154
+ "PRDX1",
155
+ "PRRC2A",
156
+ "PRSS8",
157
+ "PSMB3",
158
+ "PSMB4",
159
+ "PSMD3",
160
+ "PTMA",
161
+ "PTMS",
162
+ "PTPRF",
163
+ "RACK1",
164
+ "S100A14",
165
+ "S100A6",
166
+ "S100A8",
167
+ "S100A9",
168
+ "SCAND1",
169
+ "SCD",
170
+ "SDC1",
171
+ "SEC61A1",
172
+ "SEPW1",
173
+ "SERF2",
174
+ "SF3B5",
175
+ "SH3BGRL3",
176
+ "SLC9A3R1",
177
+ "SNRPB",
178
+ "SPARC",
179
+ "SPDEF",
180
+ "SPINT2",
181
+ "SSR2",
182
+ "SSR4",
183
+ "STARD10",
184
+ "STARD3",
185
+ "SUPT6H",
186
+ "SYNGR2",
187
+ "TAGLN",
188
+ "TAPBP",
189
+ "TFF3",
190
+ "TIMP1",
191
+ "TMSB10",
192
+ "TPT1",
193
+ "TSPO",
194
+ "TUBB",
195
+ "TXNIP",
196
+ "UBA52",
197
+ "UBC",
198
+ "UBE2M",
199
+ "UQCRQ",
200
+ "VIM",
201
+ "ZYX"
202
+ ]
models/single-patch/her2st/hmhvg/model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0022fa86b49afcfaa4c9151d0eaf5c106425dc7cf428c2c19c349455dbdef4dd
3
+ size 183903592
models/single-patch/her2st/hvg/config.json ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "format_version": 1,
3
+ "architecture": "SimpleP2G",
4
+ "setting": "single-patch",
5
+ "dataset": "her2st",
6
+ "panel": "hvg",
7
+ "fold": 0,
8
+ "seed": 42,
9
+ "model_config": {
10
+ "decoder_depth": 12,
11
+ "num_genes": 200,
12
+ "hidden_size": 384,
13
+ "cond_size": 2560,
14
+ "num_cond_tokens": 4,
15
+ "num_heads": 6,
16
+ "loss_name": "gaussian_nll",
17
+ "dropout": 0.0
18
+ },
19
+ "input": {
20
+ "representation": "frozen Virchow2 CLS token concatenated with mean patch tokens",
21
+ "embedding_dimension": 2560,
22
+ "image_encoder_weights_included": false
23
+ },
24
+ "output": {
25
+ "num_genes": 200,
26
+ "gene_order": "genes.json",
27
+ "expression_scale": "log2(raw_count + 1)",
28
+ "returns": [
29
+ "expression_mean",
30
+ "log_variance"
31
+ ]
32
+ },
33
+ "checkpoint": {
34
+ "epoch": 37,
35
+ "weights": "ema",
36
+ "selection": "highest validation-slide PCC-200; earliest epoch breaks ties"
37
+ },
38
+ "training": {
39
+ "epochs": 100,
40
+ "batch_size": 256,
41
+ "optimizer": {
42
+ "name": "adamw",
43
+ "lr": 0.0001,
44
+ "weight_decay": 0.05,
45
+ "betas": [
46
+ 0.9,
47
+ 0.999
48
+ ]
49
+ },
50
+ "loss": "gaussian_nll",
51
+ "precision": "fp16",
52
+ "ema_decay": 0.999,
53
+ "sampling": "pooled spots"
54
+ },
55
+ "split": {
56
+ "training_slides": [
57
+ "SPA119",
58
+ "SPA120",
59
+ "SPA121",
60
+ "SPA122",
61
+ "SPA123",
62
+ "SPA124",
63
+ "SPA125",
64
+ "SPA126",
65
+ "SPA128",
66
+ "SPA129",
67
+ "SPA130",
68
+ "SPA131",
69
+ "SPA132",
70
+ "SPA133",
71
+ "SPA134",
72
+ "SPA135",
73
+ "SPA136",
74
+ "SPA137",
75
+ "SPA138",
76
+ "SPA139",
77
+ "SPA140",
78
+ "SPA141",
79
+ "SPA142",
80
+ "SPA143",
81
+ "SPA144",
82
+ "SPA145",
83
+ "SPA146",
84
+ "SPA147",
85
+ "SPA149",
86
+ "SPA150",
87
+ "SPA151",
88
+ "SPA152",
89
+ "SPA153",
90
+ "SPA154"
91
+ ],
92
+ "validation_slide": "SPA127",
93
+ "test_slide": "SPA148"
94
+ },
95
+ "validation_metrics": {
96
+ "PCC10": 0.43139689241917323,
97
+ "PCC50": 0.20696065692979265,
98
+ "PCC200": 0.0662583081649352,
99
+ "MSE": 0.2628522515296936,
100
+ "MAE": 0.31125587224960327
101
+ },
102
+ "test_metrics": {
103
+ "PCC10": 0.751352123780151,
104
+ "PCC50": 0.6407706227872064,
105
+ "PCC200": 0.3798230854871934,
106
+ "MSE": 0.3085944652557373,
107
+ "MAE": 0.2869880795478821
108
+ }
109
+ }
models/single-patch/her2st/hvg/genes.json ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ "A2M",
3
+ "ACKR1",
4
+ "ADIRF",
5
+ "AGR2",
6
+ "AKAP9",
7
+ "AMDHD2",
8
+ "ANKRD36",
9
+ "ANKRD36C",
10
+ "APOC1",
11
+ "APOD",
12
+ "ARID4A",
13
+ "ARMC9",
14
+ "ATP5D",
15
+ "BAG6",
16
+ "BRCA1",
17
+ "BRD4",
18
+ "C3",
19
+ "C4orf48",
20
+ "CACNA2D1",
21
+ "CCDC34",
22
+ "CCL19",
23
+ "CCL21",
24
+ "CD3D",
25
+ "CD7",
26
+ "CDK5RAP3",
27
+ "CDR1",
28
+ "CEP135",
29
+ "CEP162",
30
+ "CEP290",
31
+ "CFD",
32
+ "CHCHD6",
33
+ "CLDN5",
34
+ "CPSF3",
35
+ "CRABP2",
36
+ "CST6",
37
+ "CTNNBL1",
38
+ "CWF19L2",
39
+ "CX3CL1",
40
+ "CXCL14",
41
+ "CXCL9",
42
+ "DDX60L",
43
+ "DECR1",
44
+ "DNAJC15",
45
+ "DNAJC2",
46
+ "DNTTIP2",
47
+ "DOCK11",
48
+ "DYNC1H1",
49
+ "EIF2B3",
50
+ "ENPP1",
51
+ "ENY2",
52
+ "EPB41L1",
53
+ "ERCC1",
54
+ "ERICH1",
55
+ "EXOSC10",
56
+ "FKBP11",
57
+ "FMNL2",
58
+ "FRA10AC1",
59
+ "FRMD4B",
60
+ "G0S2",
61
+ "GBP2",
62
+ "GDPD3",
63
+ "GLTSCR2",
64
+ "GMFG",
65
+ "GNL2",
66
+ "GNL3L",
67
+ "GNLY",
68
+ "GPX3",
69
+ "GTF2I",
70
+ "HLA-DPB1",
71
+ "HLA-F",
72
+ "HOOK3",
73
+ "HSPB11",
74
+ "IFI27L2",
75
+ "IFT81",
76
+ "IFT88",
77
+ "IGHA1",
78
+ "IGHG1",
79
+ "IGHG3",
80
+ "IGHG4",
81
+ "IGHM",
82
+ "IGKC",
83
+ "IGLC2",
84
+ "IGLC3",
85
+ "IGLC7",
86
+ "ITGB1",
87
+ "ITPR2",
88
+ "JCHAIN",
89
+ "KDM7A",
90
+ "KMT2E",
91
+ "KNTC1",
92
+ "KRT15",
93
+ "KRT17",
94
+ "LRRC29",
95
+ "LSM6",
96
+ "LTA4H",
97
+ "LTF",
98
+ "LYZ",
99
+ "MAP4K1",
100
+ "MAP7D3",
101
+ "MCUR1",
102
+ "MGP",
103
+ "MICAL3",
104
+ "MMP9",
105
+ "MPND",
106
+ "MRPL21",
107
+ "MRPL52",
108
+ "MSRB2",
109
+ "MUCL1",
110
+ "MUTYH",
111
+ "MYH3",
112
+ "NAP1L1",
113
+ "NDUFA1",
114
+ "NELFE",
115
+ "NIT2",
116
+ "NPW",
117
+ "NRDC",
118
+ "NTN4",
119
+ "NUP214",
120
+ "NUP37",
121
+ "OCEL1",
122
+ "OCIAD2",
123
+ "OFD1",
124
+ "OPTN",
125
+ "PDCD5",
126
+ "PDE3B",
127
+ "PHF14",
128
+ "PIP",
129
+ "PITX1",
130
+ "PLAC8",
131
+ "PLAC9",
132
+ "PLIN1",
133
+ "PLIN4",
134
+ "PLK2",
135
+ "PNMT",
136
+ "PPIH",
137
+ "PPP1R1A",
138
+ "PPP1R1B",
139
+ "PREX2",
140
+ "PRMT7",
141
+ "PSMD1",
142
+ "PTGDS",
143
+ "PTPN6",
144
+ "R3HDM2",
145
+ "RAD50",
146
+ "RBP1",
147
+ "RBP7",
148
+ "RFC1",
149
+ "RNF181",
150
+ "RNPC3",
151
+ "ROCK1",
152
+ "SAA1",
153
+ "SCAPER",
154
+ "SCFD1",
155
+ "SCGB3A1",
156
+ "SFRP4",
157
+ "SFSWAP",
158
+ "SLF1",
159
+ "SLIRP",
160
+ "SLPI",
161
+ "SMCHD1",
162
+ "SNRNP48",
163
+ "SOD1",
164
+ "SP100",
165
+ "SRSF11",
166
+ "SRSF7",
167
+ "STAT4",
168
+ "SUGP1",
169
+ "SVIL",
170
+ "SYCP2",
171
+ "TEX10",
172
+ "TFF3",
173
+ "TFPT",
174
+ "THOC5",
175
+ "TIMM50",
176
+ "TJP3",
177
+ "TMEM258",
178
+ "TMEM40",
179
+ "TNNI2",
180
+ "TPR",
181
+ "TRAF3IP1",
182
+ "TRAP1",
183
+ "TRBC2",
184
+ "TRPV2",
185
+ "TXN",
186
+ "TXNDC17",
187
+ "UACA",
188
+ "UPF2",
189
+ "UPP1",
190
+ "USE1",
191
+ "USP48",
192
+ "UTRN",
193
+ "UXT",
194
+ "VARS",
195
+ "VWF",
196
+ "WDR60",
197
+ "WWP1",
198
+ "ZBTB20",
199
+ "ZNF638",
200
+ "ZNF880",
201
+ "ZRANB2"
202
+ ]
models/single-patch/her2st/hvg/model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:254fc5a129245998360cdcac313dd3d1c84b2a3feefbf4ce33689a81509c740d
3
+ size 183903592
models/single-patch/lung/hmhvg/config.json ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "format_version": 1,
3
+ "architecture": "SimpleP2G",
4
+ "setting": "single-patch",
5
+ "dataset": "lung",
6
+ "panel": "hmhvg",
7
+ "fold": 0,
8
+ "seed": 42,
9
+ "model_config": {
10
+ "decoder_depth": 12,
11
+ "num_genes": 200,
12
+ "hidden_size": 384,
13
+ "cond_size": 2560,
14
+ "num_cond_tokens": 4,
15
+ "num_heads": 6,
16
+ "loss_name": "gaussian_nll",
17
+ "dropout": 0.0
18
+ },
19
+ "input": {
20
+ "representation": "frozen Virchow2 CLS token concatenated with mean patch tokens",
21
+ "embedding_dimension": 2560,
22
+ "image_encoder_weights_included": false
23
+ },
24
+ "output": {
25
+ "num_genes": 200,
26
+ "gene_order": "genes.json",
27
+ "expression_scale": "log2(raw_count + 1)",
28
+ "returns": [
29
+ "expression_mean",
30
+ "log_variance"
31
+ ]
32
+ },
33
+ "checkpoint": {
34
+ "epoch": 7,
35
+ "weights": "ema",
36
+ "selection": "highest validation-slide PCC-200; earliest epoch breaks ties"
37
+ },
38
+ "training": {
39
+ "epochs": 100,
40
+ "batch_size": 256,
41
+ "optimizer": {
42
+ "name": "adamw",
43
+ "lr": 5e-05,
44
+ "weight_decay": 0.05,
45
+ "betas": [
46
+ 0.9,
47
+ 0.999
48
+ ]
49
+ },
50
+ "loss": "gaussian_nll",
51
+ "precision": "fp16",
52
+ "ema_decay": 0.999,
53
+ "sampling": "pooled spots"
54
+ },
55
+ "split": {
56
+ "training_slides": [
57
+ "NCBI857",
58
+ "NCBI858",
59
+ "NCBI859",
60
+ "NCBI861",
61
+ "NCBI864",
62
+ "NCBI865",
63
+ "NCBI866",
64
+ "NCBI867",
65
+ "NCBI870",
66
+ "NCBI873",
67
+ "NCBI875",
68
+ "NCBI876",
69
+ "NCBI879",
70
+ "NCBI880",
71
+ "NCBI881",
72
+ "NCBI882",
73
+ "NCBI883",
74
+ "NCBI884"
75
+ ],
76
+ "validation_slide": "NCBI860",
77
+ "test_slide": "NCBI856"
78
+ },
79
+ "validation_metrics": {
80
+ "PCC10": 0.9362276377737937,
81
+ "PCC50": 0.9226602827904639,
82
+ "PCC200": 0.8183084345389446,
83
+ "MSE": 1.1610033512115479,
84
+ "MAE": 0.7474100589752197
85
+ },
86
+ "test_metrics": {
87
+ "PCC10": 0.970405946201667,
88
+ "PCC50": 0.9624952765742016,
89
+ "PCC200": 0.8717158056511088,
90
+ "MSE": 1.2483162879943848,
91
+ "MAE": 0.8023096919059753
92
+ }
93
+ }
models/single-patch/lung/hmhvg/genes.json ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ "ACKR1",
3
+ "ACTA2",
4
+ "AGER",
5
+ "AGR3",
6
+ "AIF1",
7
+ "AKR1C1",
8
+ "AKR1C2",
9
+ "ANKRD28",
10
+ "ATF3",
11
+ "ATF4",
12
+ "ATG7",
13
+ "ATP2A3",
14
+ "AXIN2",
15
+ "AXL",
16
+ "BANK1",
17
+ "BCL2L1",
18
+ "BCL2L11",
19
+ "BMPR2",
20
+ "BPIFA1",
21
+ "C20orf85",
22
+ "CCL18",
23
+ "CCL2",
24
+ "CCL21",
25
+ "CCN2",
26
+ "CD14",
27
+ "CD2",
28
+ "CD34",
29
+ "CD3E",
30
+ "CD4",
31
+ "CD44",
32
+ "CD52",
33
+ "CD68",
34
+ "CD69",
35
+ "CD79A",
36
+ "CD8A",
37
+ "CEACAM5",
38
+ "CEACAM6",
39
+ "COL15A1",
40
+ "COL1A1",
41
+ "COL1A2",
42
+ "COL3A1",
43
+ "CPA3",
44
+ "CST3",
45
+ "CTHRC1",
46
+ "CTNNB1",
47
+ "CXCL13",
48
+ "CXCL14",
49
+ "CXCL9",
50
+ "CXCR4",
51
+ "DCN",
52
+ "DMBT1",
53
+ "DNAJB9",
54
+ "DUOX1",
55
+ "EGFR",
56
+ "EHMT1",
57
+ "EPAS1",
58
+ "EPCAM",
59
+ "ERLEC1",
60
+ "FABP4",
61
+ "FAS",
62
+ "FCER1G",
63
+ "FCGR3A",
64
+ "FCN3",
65
+ "FGF7",
66
+ "FKBP11",
67
+ "FN1",
68
+ "FOXJ1",
69
+ "GCLM",
70
+ "GNG11",
71
+ "GPR183",
72
+ "GSR",
73
+ "GZMA",
74
+ "HAVCR2",
75
+ "HERPUD1",
76
+ "HES1",
77
+ "HIF1A",
78
+ "HIST1H1C",
79
+ "HLA-DQA1",
80
+ "HLA-DQB1",
81
+ "HLA-DRA",
82
+ "HMGA1",
83
+ "HMOX1",
84
+ "HSPA5",
85
+ "HYOU1",
86
+ "ICAM1",
87
+ "IDH1",
88
+ "IFIT1",
89
+ "IFIT2",
90
+ "IFIT3",
91
+ "IL7R",
92
+ "IRF1",
93
+ "ITGA3",
94
+ "ITGAM",
95
+ "ITGAV",
96
+ "ITGAX",
97
+ "ITGB1",
98
+ "ITGB6",
99
+ "ITM2C",
100
+ "JCHAIN",
101
+ "KDR",
102
+ "KIT",
103
+ "KRT15",
104
+ "KRT17",
105
+ "KRT18",
106
+ "KRT5",
107
+ "KRT6A",
108
+ "KRT8",
109
+ "LAMP3",
110
+ "LGALS1",
111
+ "LMAN1",
112
+ "LTF",
113
+ "LUM",
114
+ "LYZ",
115
+ "MANF",
116
+ "MARCO",
117
+ "MCEMP1",
118
+ "MEG3",
119
+ "MGST1",
120
+ "MMP7",
121
+ "MRC1",
122
+ "MS4A1",
123
+ "MS4A7",
124
+ "MSLN",
125
+ "MUC5B",
126
+ "MYC",
127
+ "MYDGF",
128
+ "NAPSA",
129
+ "NFKB1",
130
+ "NKX2-1",
131
+ "NUCB2",
132
+ "NUTF2",
133
+ "OAS2",
134
+ "OAS3",
135
+ "PCNA",
136
+ "PDGFRA",
137
+ "PDGFRB",
138
+ "PDIA3",
139
+ "PDIA4",
140
+ "PDIA6",
141
+ "PECAM1",
142
+ "PGC",
143
+ "PIM2",
144
+ "PKM",
145
+ "PLIN2",
146
+ "PLVAP",
147
+ "POSTN",
148
+ "PPARG",
149
+ "PRDX4",
150
+ "PTGDS",
151
+ "PTPRC",
152
+ "RHOA",
153
+ "RNASE1",
154
+ "RTKN2",
155
+ "S100A12",
156
+ "S100A2",
157
+ "S100A8",
158
+ "S100A9",
159
+ "SAA2",
160
+ "SCGB1A1",
161
+ "SCGB3A2",
162
+ "SEC11C",
163
+ "SELENOS",
164
+ "SFRP2",
165
+ "SFRP4",
166
+ "SFTA2",
167
+ "SFTPC",
168
+ "SFTPD",
169
+ "SLC1A3",
170
+ "SLC25A4",
171
+ "SMAD4",
172
+ "SNAI2",
173
+ "SOD2",
174
+ "SOX4",
175
+ "SOX9",
176
+ "SPARCL1",
177
+ "SPCS2",
178
+ "SPCS3",
179
+ "SPP1",
180
+ "SPRY2",
181
+ "SSR3",
182
+ "STAT1",
183
+ "STAT6",
184
+ "TGFB1",
185
+ "TGFB3",
186
+ "TNFRSF13C",
187
+ "TOP1",
188
+ "TPSAB1",
189
+ "TRAC",
190
+ "TTC19",
191
+ "UBE2J1",
192
+ "UCHL3",
193
+ "UGDH",
194
+ "VEGFA",
195
+ "VIM",
196
+ "WFDC2",
197
+ "WNT5A",
198
+ "WWTR1",
199
+ "XBP1",
200
+ "YAP1",
201
+ "ZEB1"
202
+ ]
models/single-patch/lung/hmhvg/model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:dcbde320a1df51a876a4c0797983d160f5deb3e4bae0f402af6af97b52ccc2f5
3
+ size 183903592
models/single-patch/lung/hvg/config.json ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "format_version": 1,
3
+ "architecture": "SimpleP2G",
4
+ "setting": "single-patch",
5
+ "dataset": "lung",
6
+ "panel": "hvg",
7
+ "fold": 0,
8
+ "seed": 42,
9
+ "model_config": {
10
+ "decoder_depth": 12,
11
+ "num_genes": 200,
12
+ "hidden_size": 384,
13
+ "cond_size": 2560,
14
+ "num_cond_tokens": 4,
15
+ "num_heads": 6,
16
+ "loss_name": "gaussian_nll",
17
+ "dropout": 0.0
18
+ },
19
+ "input": {
20
+ "representation": "frozen Virchow2 CLS token concatenated with mean patch tokens",
21
+ "embedding_dimension": 2560,
22
+ "image_encoder_weights_included": false
23
+ },
24
+ "output": {
25
+ "num_genes": 200,
26
+ "gene_order": "genes.json",
27
+ "expression_scale": "log2(raw_count + 1)",
28
+ "returns": [
29
+ "expression_mean",
30
+ "log_variance"
31
+ ]
32
+ },
33
+ "checkpoint": {
34
+ "epoch": 8,
35
+ "weights": "ema",
36
+ "selection": "highest validation-slide PCC-200; earliest epoch breaks ties"
37
+ },
38
+ "training": {
39
+ "epochs": 100,
40
+ "batch_size": 256,
41
+ "optimizer": {
42
+ "name": "adamw",
43
+ "lr": 5e-05,
44
+ "weight_decay": 0.05,
45
+ "betas": [
46
+ 0.9,
47
+ 0.999
48
+ ]
49
+ },
50
+ "loss": "gaussian_nll",
51
+ "precision": "fp16",
52
+ "ema_decay": 0.999,
53
+ "sampling": "pooled spots"
54
+ },
55
+ "split": {
56
+ "training_slides": [
57
+ "NCBI857",
58
+ "NCBI858",
59
+ "NCBI859",
60
+ "NCBI861",
61
+ "NCBI864",
62
+ "NCBI865",
63
+ "NCBI866",
64
+ "NCBI867",
65
+ "NCBI870",
66
+ "NCBI873",
67
+ "NCBI875",
68
+ "NCBI876",
69
+ "NCBI879",
70
+ "NCBI880",
71
+ "NCBI881",
72
+ "NCBI882",
73
+ "NCBI883",
74
+ "NCBI884"
75
+ ],
76
+ "validation_slide": "NCBI860",
77
+ "test_slide": "NCBI856"
78
+ },
79
+ "validation_metrics": {
80
+ "PCC10": 0.9030630133389671,
81
+ "PCC50": 0.8287717950429099,
82
+ "PCC200": 0.4339199710155945,
83
+ "MSE": 0.606461763381958,
84
+ "MAE": 0.42725834250450134
85
+ },
86
+ "test_metrics": {
87
+ "PCC10": 0.9472604745563193,
88
+ "PCC50": 0.8581366731430391,
89
+ "PCC200": 0.4954411997870103,
90
+ "MSE": 0.7060865759849548,
91
+ "MAE": 0.4992806017398834
92
+ }
93
+ }
models/single-patch/lung/hvg/genes.json ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ "ACKR1",
3
+ "ACTA2",
4
+ "AGR3",
5
+ "AIF1",
6
+ "APLN",
7
+ "ASCL1",
8
+ "BPIFA1",
9
+ "C20orf85",
10
+ "CCL18",
11
+ "CCL21",
12
+ "CCL22",
13
+ "CCNA1",
14
+ "CD1A",
15
+ "CD52",
16
+ "CD68",
17
+ "CD8A",
18
+ "CDKN2A",
19
+ "CEACAM6",
20
+ "COL1A1",
21
+ "COL3A1",
22
+ "CXCL13",
23
+ "CXCL14",
24
+ "CXCL9",
25
+ "CXCR5",
26
+ "DMBT1",
27
+ "EHMT1",
28
+ "EREG",
29
+ "FABP4",
30
+ "FGF2",
31
+ "FGFBP2",
32
+ "FOXJ1",
33
+ "GDF15",
34
+ "GZMA",
35
+ "HAS1",
36
+ "HLA-DRA",
37
+ "HMGA1",
38
+ "HMOX1",
39
+ "IFIT1",
40
+ "IL7R",
41
+ "IRF1",
42
+ "IRF7",
43
+ "ITGAV",
44
+ "JCHAIN",
45
+ "KRT14",
46
+ "KRT15",
47
+ "KRT17",
48
+ "KRT18",
49
+ "KRT8",
50
+ "LAMP3",
51
+ "LTB",
52
+ "LTF",
53
+ "LY6D",
54
+ "LYZ",
55
+ "MARCO",
56
+ "MCEMP1",
57
+ "MFAP5",
58
+ "MMP7",
59
+ "MUC5AC",
60
+ "MUC5B",
61
+ "NAPSA",
62
+ "NegControlCodeword_0501",
63
+ "NegControlCodeword_0502",
64
+ "NegControlCodeword_0504",
65
+ "NegControlCodeword_0508",
66
+ "NegControlCodeword_0511",
67
+ "NegControlCodeword_0512",
68
+ "NegControlCodeword_0514",
69
+ "NegControlCodeword_0515",
70
+ "NegControlCodeword_0516",
71
+ "NegControlCodeword_0517",
72
+ "NegControlCodeword_0518",
73
+ "NegControlCodeword_0520",
74
+ "NegControlCodeword_0524",
75
+ "NegControlCodeword_0526",
76
+ "NegControlCodeword_0527",
77
+ "NegControlCodeword_0528",
78
+ "NegControlCodeword_0530",
79
+ "NegControlCodeword_0534",
80
+ "NegControlCodeword_0536",
81
+ "NegControlCodeword_0537",
82
+ "NegControlCodeword_0540",
83
+ "NegControlProbe_00002",
84
+ "NegControlProbe_00003",
85
+ "NegControlProbe_00004",
86
+ "NegControlProbe_00012",
87
+ "NegControlProbe_00013",
88
+ "NegControlProbe_00014",
89
+ "NegControlProbe_00016",
90
+ "NegControlProbe_00017",
91
+ "NegControlProbe_00019",
92
+ "NegControlProbe_00022",
93
+ "NegControlProbe_00024",
94
+ "NegControlProbe_00025",
95
+ "NegControlProbe_00031",
96
+ "NegControlProbe_00033",
97
+ "NegControlProbe_00034",
98
+ "NegControlProbe_00039",
99
+ "NegControlProbe_00041",
100
+ "PCNA",
101
+ "PDCD1",
102
+ "PGC",
103
+ "PLIN2",
104
+ "POSTN",
105
+ "PPARG",
106
+ "PTPRC",
107
+ "RETN",
108
+ "S100A12",
109
+ "S100A2",
110
+ "S100A8",
111
+ "S100A9",
112
+ "SAA2",
113
+ "SCGB1A1",
114
+ "SCGB3A2",
115
+ "SFRP2",
116
+ "SFRP4",
117
+ "SFTPC",
118
+ "SFTPD",
119
+ "SLC25A4",
120
+ "SPP1",
121
+ "TERT",
122
+ "UGDH",
123
+ "UnassignedCodeword_0000",
124
+ "UnassignedCodeword_0001",
125
+ "UnassignedCodeword_0011",
126
+ "UnassignedCodeword_0014",
127
+ "UnassignedCodeword_0028",
128
+ "UnassignedCodeword_0034",
129
+ "UnassignedCodeword_0043",
130
+ "UnassignedCodeword_0044",
131
+ "UnassignedCodeword_0045",
132
+ "UnassignedCodeword_0048",
133
+ "UnassignedCodeword_0050",
134
+ "UnassignedCodeword_0052",
135
+ "UnassignedCodeword_0055",
136
+ "UnassignedCodeword_0057",
137
+ "UnassignedCodeword_0063",
138
+ "UnassignedCodeword_0066",
139
+ "UnassignedCodeword_0068",
140
+ "UnassignedCodeword_0071",
141
+ "UnassignedCodeword_0082",
142
+ "UnassignedCodeword_0085",
143
+ "UnassignedCodeword_0095",
144
+ "UnassignedCodeword_0104",
145
+ "UnassignedCodeword_0107",
146
+ "UnassignedCodeword_0112",
147
+ "UnassignedCodeword_0118",
148
+ "UnassignedCodeword_0122",
149
+ "UnassignedCodeword_0123",
150
+ "UnassignedCodeword_0127",
151
+ "UnassignedCodeword_0129",
152
+ "UnassignedCodeword_0131",
153
+ "UnassignedCodeword_0139",
154
+ "UnassignedCodeword_0148",
155
+ "UnassignedCodeword_0150",
156
+ "UnassignedCodeword_0155",
157
+ "UnassignedCodeword_0162",
158
+ "UnassignedCodeword_0166",
159
+ "UnassignedCodeword_0168",
160
+ "UnassignedCodeword_0172",
161
+ "UnassignedCodeword_0174",
162
+ "UnassignedCodeword_0185",
163
+ "UnassignedCodeword_0188",
164
+ "UnassignedCodeword_0198",
165
+ "UnassignedCodeword_0201",
166
+ "UnassignedCodeword_0205",
167
+ "UnassignedCodeword_0210",
168
+ "UnassignedCodeword_0213",
169
+ "UnassignedCodeword_0214",
170
+ "UnassignedCodeword_0219",
171
+ "UnassignedCodeword_0224",
172
+ "UnassignedCodeword_0236",
173
+ "UnassignedCodeword_0241",
174
+ "UnassignedCodeword_0245",
175
+ "UnassignedCodeword_0252",
176
+ "UnassignedCodeword_0258",
177
+ "UnassignedCodeword_0259",
178
+ "UnassignedCodeword_0260",
179
+ "UnassignedCodeword_0261",
180
+ "UnassignedCodeword_0266",
181
+ "UnassignedCodeword_0275",
182
+ "UnassignedCodeword_0280",
183
+ "UnassignedCodeword_0282",
184
+ "UnassignedCodeword_0285",
185
+ "UnassignedCodeword_0290",
186
+ "UnassignedCodeword_0292",
187
+ "UnassignedCodeword_0299",
188
+ "UnassignedCodeword_0300",
189
+ "UnassignedCodeword_0305",
190
+ "UnassignedCodeword_0312",
191
+ "UnassignedCodeword_0322",
192
+ "UnassignedCodeword_0323",
193
+ "UnassignedCodeword_0324",
194
+ "UnassignedCodeword_0327",
195
+ "UnassignedCodeword_0328",
196
+ "UnassignedCodeword_0330",
197
+ "UnassignedCodeword_0332",
198
+ "UnassignedCodeword_0413",
199
+ "VIM",
200
+ "WFDC2",
201
+ "WNT3A"
202
+ ]
models/single-patch/lung/hvg/model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f41735851688f4b7368d890c84527a2ba93a620c3df10095029149a5f0d5db6d
3
+ size 183903592
models/single-patch/prad/hmhvg/config.json ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "format_version": 1,
3
+ "architecture": "SimpleP2G",
4
+ "setting": "single-patch",
5
+ "dataset": "prad",
6
+ "panel": "hmhvg",
7
+ "fold": 0,
8
+ "seed": 42,
9
+ "model_config": {
10
+ "decoder_depth": 12,
11
+ "num_genes": 200,
12
+ "hidden_size": 384,
13
+ "cond_size": 2560,
14
+ "num_cond_tokens": 4,
15
+ "num_heads": 6,
16
+ "loss_name": "gaussian_nll",
17
+ "dropout": 0.1
18
+ },
19
+ "input": {
20
+ "representation": "frozen Virchow2 CLS token concatenated with mean patch tokens",
21
+ "embedding_dimension": 2560,
22
+ "image_encoder_weights_included": false
23
+ },
24
+ "output": {
25
+ "num_genes": 200,
26
+ "gene_order": "genes.json",
27
+ "expression_scale": "log2(raw_count + 1)",
28
+ "returns": [
29
+ "expression_mean",
30
+ "log_variance"
31
+ ]
32
+ },
33
+ "checkpoint": {
34
+ "epoch": 9,
35
+ "weights": "ema",
36
+ "selection": "highest validation-slide PCC-200; earliest epoch breaks ties"
37
+ },
38
+ "training": {
39
+ "epochs": 100,
40
+ "batch_size": 256,
41
+ "optimizer": {
42
+ "name": "adamw",
43
+ "lr": 3e-05,
44
+ "weight_decay": 0.1,
45
+ "betas": [
46
+ 0.9,
47
+ 0.999
48
+ ]
49
+ },
50
+ "loss": "gaussian_nll",
51
+ "precision": "fp16",
52
+ "ema_decay": 0.999,
53
+ "sampling": "pooled spots"
54
+ },
55
+ "split": {
56
+ "training_slides": [
57
+ "MEND139",
58
+ "MEND140",
59
+ "MEND141",
60
+ "MEND143",
61
+ "MEND144",
62
+ "MEND146",
63
+ "MEND147",
64
+ "MEND148",
65
+ "MEND149",
66
+ "MEND150",
67
+ "MEND151",
68
+ "MEND152",
69
+ "MEND153",
70
+ "MEND154",
71
+ "MEND156",
72
+ "MEND157",
73
+ "MEND158",
74
+ "MEND159",
75
+ "MEND160",
76
+ "MEND161",
77
+ "MEND162"
78
+ ],
79
+ "validation_slide": "MEND142",
80
+ "test_slide": "MEND145"
81
+ },
82
+ "validation_metrics": {
83
+ "PCC10": 0.735454567647998,
84
+ "PCC50": 0.6725363606552629,
85
+ "PCC200": 0.5097357986212281,
86
+ "MSE": 0.9369765520095825,
87
+ "MAE": 0.7383893728256226
88
+ },
89
+ "test_metrics": {
90
+ "PCC10": 0.7297544680010257,
91
+ "PCC50": 0.681781272744159,
92
+ "PCC200": 0.556121254362732,
93
+ "MSE": 1.0525509119033813,
94
+ "MAE": 0.7671422362327576
95
+ }
96
+ }
models/single-patch/prad/hmhvg/genes.json ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ "A2M",
3
+ "ACPP",
4
+ "ACTA2",
5
+ "ACTB",
6
+ "ACTG1",
7
+ "ACTG2",
8
+ "ADIRF",
9
+ "AGR2",
10
+ "AMD1",
11
+ "ANPEP",
12
+ "APLP2",
13
+ "ATP5F1E",
14
+ "ATP5MD",
15
+ "ATP5MF",
16
+ "ATP5MPL",
17
+ "AZGP1",
18
+ "B2M",
19
+ "BTF3",
20
+ "C12orf57",
21
+ "C19orf48",
22
+ "CALM2",
23
+ "CALR",
24
+ "CD63",
25
+ "CD74",
26
+ "CD81",
27
+ "CD9",
28
+ "CD99",
29
+ "CFD",
30
+ "CFL1",
31
+ "CHCHD2",
32
+ "CIRBP",
33
+ "CKB",
34
+ "CLU",
35
+ "CNN1",
36
+ "COMMD6",
37
+ "COX4I1",
38
+ "COX5B",
39
+ "COX6A1",
40
+ "COX6C",
41
+ "COX7A2",
42
+ "COX7B",
43
+ "COX7C",
44
+ "COX8A",
45
+ "CPE",
46
+ "CSRP1",
47
+ "CST3",
48
+ "DBI",
49
+ "DDT",
50
+ "DES",
51
+ "DHRS7",
52
+ "DSTN",
53
+ "DUSP1",
54
+ "EDF1",
55
+ "EEF1A1",
56
+ "EEF1B2",
57
+ "EEF2",
58
+ "EIF1",
59
+ "EIF3L",
60
+ "ELOB",
61
+ "FABP5",
62
+ "FASN",
63
+ "FAU",
64
+ "FBLN1",
65
+ "FLNA",
66
+ "FOS",
67
+ "FTH1",
68
+ "FTL",
69
+ "FXYD3",
70
+ "GAPDH",
71
+ "GPX4",
72
+ "H2AFJ",
73
+ "H3F3A",
74
+ "H3F3B",
75
+ "HERPUD1",
76
+ "HINT1",
77
+ "HLA-B",
78
+ "HLA-C",
79
+ "HLA-DRA",
80
+ "HMGN2",
81
+ "HNRNPA1",
82
+ "HOXB13",
83
+ "HSPA5",
84
+ "HSPA8",
85
+ "HSPB1",
86
+ "IGHA1",
87
+ "IGKC",
88
+ "IGLC2",
89
+ "ITM2B",
90
+ "KDELR2",
91
+ "KLK2",
92
+ "KLK3",
93
+ "KLK4",
94
+ "KRT18",
95
+ "KRT8",
96
+ "LGALS1",
97
+ "LTF",
98
+ "MALAT1",
99
+ "MDK",
100
+ "MGP",
101
+ "MIF",
102
+ "MINOS1",
103
+ "MPC2",
104
+ "MSMB",
105
+ "MYH11",
106
+ "MYL6",
107
+ "MYL9",
108
+ "MYLK",
109
+ "MZT2B",
110
+ "NACA",
111
+ "NBL1",
112
+ "NCAPD3",
113
+ "NDRG1",
114
+ "NDUFB1",
115
+ "NDUFB11",
116
+ "NDUFB4",
117
+ "NDUFS5",
118
+ "NEAT1",
119
+ "NEFH",
120
+ "NKX3-1",
121
+ "NME4",
122
+ "NPM1",
123
+ "NPY",
124
+ "NR4A1",
125
+ "NUPR1",
126
+ "OAZ1",
127
+ "OST4",
128
+ "PABPC1",
129
+ "PARK7",
130
+ "PCAT4",
131
+ "PDLIM5",
132
+ "PFDN5",
133
+ "PLA2G2A",
134
+ "PLPP1",
135
+ "PMEPA1",
136
+ "POLR2L",
137
+ "PPDPF",
138
+ "PPIA",
139
+ "PRAC1",
140
+ "PRDX2",
141
+ "PRDX6",
142
+ "PTGDS",
143
+ "PTMA",
144
+ "RACK1",
145
+ "RDH11",
146
+ "ROMO1",
147
+ "S100A11",
148
+ "S100A6",
149
+ "SARAF",
150
+ "SAT1",
151
+ "SEC11C",
152
+ "SEC61B",
153
+ "SEC61G",
154
+ "SELENOP",
155
+ "SELENOW",
156
+ "SERF2",
157
+ "SERP1",
158
+ "SKP1",
159
+ "SLC25A6",
160
+ "SLC45A3",
161
+ "SNHG19",
162
+ "SNHG25",
163
+ "SNHG8",
164
+ "SNRPD2",
165
+ "SORD",
166
+ "SPDEF",
167
+ "SPINT2",
168
+ "SPON2",
169
+ "SRP14",
170
+ "SSR4",
171
+ "STEAP2",
172
+ "TAGLN",
173
+ "TFF3",
174
+ "TIMP1",
175
+ "TMBIM6",
176
+ "TMEFF2",
177
+ "TMEM141",
178
+ "TMEM258",
179
+ "TMEM59",
180
+ "TMPRSS2",
181
+ "TMSB10",
182
+ "TMSB4X",
183
+ "TOMM7",
184
+ "TPM1",
185
+ "TPM2",
186
+ "TPT1",
187
+ "TRPM4",
188
+ "TSC22D3",
189
+ "TSPAN1",
190
+ "TSTD1",
191
+ "TXN",
192
+ "UBA52",
193
+ "UBB",
194
+ "UBL5",
195
+ "UQCR10",
196
+ "UQCRB",
197
+ "UQCRH",
198
+ "UQCRQ",
199
+ "VEGFA",
200
+ "VIM",
201
+ "ZFAS1"
202
+ ]
models/single-patch/prad/hmhvg/model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ce7d28e32b4a84c0f0cba6f0561b22a997de7e9202c970968e767b2e71257142
3
+ size 183903592
models/single-patch/prad/hvg/config.json ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "format_version": 1,
3
+ "architecture": "SimpleP2G",
4
+ "setting": "single-patch",
5
+ "dataset": "prad",
6
+ "panel": "hvg",
7
+ "fold": 0,
8
+ "seed": 42,
9
+ "model_config": {
10
+ "decoder_depth": 12,
11
+ "num_genes": 200,
12
+ "hidden_size": 384,
13
+ "cond_size": 2560,
14
+ "num_cond_tokens": 4,
15
+ "num_heads": 6,
16
+ "loss_name": "gaussian_nll",
17
+ "dropout": 0.1
18
+ },
19
+ "input": {
20
+ "representation": "frozen Virchow2 CLS token concatenated with mean patch tokens",
21
+ "embedding_dimension": 2560,
22
+ "image_encoder_weights_included": false
23
+ },
24
+ "output": {
25
+ "num_genes": 200,
26
+ "gene_order": "genes.json",
27
+ "expression_scale": "log2(raw_count + 1)",
28
+ "returns": [
29
+ "expression_mean",
30
+ "log_variance"
31
+ ]
32
+ },
33
+ "checkpoint": {
34
+ "epoch": 12,
35
+ "weights": "ema",
36
+ "selection": "highest validation-slide PCC-200; earliest epoch breaks ties"
37
+ },
38
+ "training": {
39
+ "epochs": 100,
40
+ "batch_size": 256,
41
+ "optimizer": {
42
+ "name": "adamw",
43
+ "lr": 3e-05,
44
+ "weight_decay": 0.1,
45
+ "betas": [
46
+ 0.9,
47
+ 0.999
48
+ ]
49
+ },
50
+ "loss": "gaussian_nll",
51
+ "precision": "fp16",
52
+ "ema_decay": 0.999,
53
+ "sampling": "pooled spots"
54
+ },
55
+ "split": {
56
+ "training_slides": [
57
+ "MEND139",
58
+ "MEND140",
59
+ "MEND141",
60
+ "MEND143",
61
+ "MEND144",
62
+ "MEND146",
63
+ "MEND147",
64
+ "MEND148",
65
+ "MEND149",
66
+ "MEND150",
67
+ "MEND151",
68
+ "MEND152",
69
+ "MEND153",
70
+ "MEND154",
71
+ "MEND156",
72
+ "MEND157",
73
+ "MEND158",
74
+ "MEND159",
75
+ "MEND160",
76
+ "MEND161",
77
+ "MEND162"
78
+ ],
79
+ "validation_slide": "MEND142",
80
+ "test_slide": "MEND145"
81
+ },
82
+ "validation_metrics": {
83
+ "PCC10": 0.7139566340145835,
84
+ "PCC50": 0.5177275273410492,
85
+ "PCC200": 0.20855663886632447,
86
+ "MSE": 0.4681999087333679,
87
+ "MAE": 0.32622313499450684
88
+ },
89
+ "test_metrics": {
90
+ "PCC10": 0.6859417787277124,
91
+ "PCC50": 0.4673065945925007,
92
+ "PCC200": 0.2199021112938024,
93
+ "MSE": 0.29881447553634644,
94
+ "MAE": 0.22787906229496002
95
+ }
96
+ }
models/single-patch/prad/hvg/genes.json ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ "A2M",
3
+ "ABCB8",
4
+ "ACKR1",
5
+ "ACPP",
6
+ "ACTG2",
7
+ "ADAP2",
8
+ "ADCY5",
9
+ "AGBL1",
10
+ "AGR2",
11
+ "AKTIP",
12
+ "AL133492.1",
13
+ "AL355075.4",
14
+ "AL359220.1",
15
+ "ANGPTL7",
16
+ "ANKRD42",
17
+ "AP4E1",
18
+ "APOC1",
19
+ "APOD",
20
+ "AQP1",
21
+ "ASF1B",
22
+ "ATF3",
23
+ "ATP10D",
24
+ "AZGP1",
25
+ "C19orf33",
26
+ "C1orf52",
27
+ "CAMK1D",
28
+ "CCDC144A",
29
+ "CCDC180",
30
+ "CCL19",
31
+ "CCL21",
32
+ "CCL4",
33
+ "CCL4L2",
34
+ "CCL5",
35
+ "CCM2L",
36
+ "CDA",
37
+ "CDH19",
38
+ "CDH3",
39
+ "CDK11A",
40
+ "CFD",
41
+ "CFHR5",
42
+ "CH25H",
43
+ "CHGA",
44
+ "CKAP2",
45
+ "CLDN5",
46
+ "CNOT4",
47
+ "COL15A1",
48
+ "COL6A1",
49
+ "CPXM2",
50
+ "CST1",
51
+ "CXCL10",
52
+ "CXCL9",
53
+ "DDX20",
54
+ "DEPP1",
55
+ "DES",
56
+ "DNM3OS",
57
+ "EIF5A2",
58
+ "ELF3",
59
+ "ELMO1",
60
+ "EMILIN2",
61
+ "EPM2A",
62
+ "ETV6",
63
+ "FILIP1L",
64
+ "FOSB",
65
+ "FOSL1",
66
+ "FYCO1",
67
+ "GLI4",
68
+ "GRIN2A",
69
+ "GZMA",
70
+ "HBA1",
71
+ "HBA2",
72
+ "HBB",
73
+ "HIVEP2",
74
+ "ICA1L",
75
+ "IFT52",
76
+ "IGF2BP2",
77
+ "IGFBP3",
78
+ "IGHA1",
79
+ "IGHG1",
80
+ "IGHG2",
81
+ "IGHG3",
82
+ "IGHG4",
83
+ "IGHM",
84
+ "IGKC",
85
+ "IGLC2",
86
+ "IGLC3",
87
+ "IGLL5",
88
+ "JAM2",
89
+ "JCHAIN",
90
+ "KANSL1",
91
+ "KCNG4",
92
+ "KCNH2",
93
+ "KHNYN",
94
+ "KLHL33",
95
+ "KLK2",
96
+ "KLK3",
97
+ "KRBA1",
98
+ "KRT13",
99
+ "KRT15",
100
+ "KRT17",
101
+ "KRT19",
102
+ "KRT5",
103
+ "LACTB",
104
+ "LAIR1",
105
+ "LCN2",
106
+ "LEPR",
107
+ "LMO7DN",
108
+ "LOX",
109
+ "LRRC23",
110
+ "LTF",
111
+ "LYZ",
112
+ "MCUB",
113
+ "MFSD11",
114
+ "MGP",
115
+ "MHENCR",
116
+ "MMP7",
117
+ "MSMB",
118
+ "MSRB3",
119
+ "MT1G",
120
+ "MT1H",
121
+ "MYH11",
122
+ "MYOM1",
123
+ "NECAB1",
124
+ "NEFH",
125
+ "NPR3",
126
+ "NPY",
127
+ "NSUN2",
128
+ "NTRK2",
129
+ "OLFM4",
130
+ "OR6S1",
131
+ "P3H3",
132
+ "PARP12",
133
+ "PCSK7",
134
+ "PDCD7",
135
+ "PDK1",
136
+ "PIGR",
137
+ "PLA2G2A",
138
+ "PLCD3",
139
+ "POU2F2",
140
+ "PRDM5",
141
+ "PRKRIP1",
142
+ "PRMT9",
143
+ "PRPF18",
144
+ "PRPF4",
145
+ "PSCA",
146
+ "PTGDS",
147
+ "PTGER3",
148
+ "PTRH1",
149
+ "RAB30",
150
+ "RASL11B",
151
+ "RDH11",
152
+ "RGS5",
153
+ "RIC3",
154
+ "RNASE1",
155
+ "RND2",
156
+ "RNF144A",
157
+ "RNFT2",
158
+ "RPAP3",
159
+ "RPGRIP1L",
160
+ "RUBCNL",
161
+ "S100P",
162
+ "SAA1",
163
+ "SCGB1A1",
164
+ "SCGB3A1",
165
+ "SCUBE3",
166
+ "SIX3",
167
+ "SLC14A1",
168
+ "SLC16A1-AS1",
169
+ "SLC19A2",
170
+ "SLC25A13",
171
+ "SLC26A4",
172
+ "SNAP47",
173
+ "SORD",
174
+ "SPAG16",
175
+ "SPC24",
176
+ "SPP1",
177
+ "SSTR2",
178
+ "ST3GAL2",
179
+ "SULF2",
180
+ "SYK",
181
+ "TFRC",
182
+ "TGM4",
183
+ "THAP6",
184
+ "THBD",
185
+ "TMEFF2",
186
+ "TMEM260",
187
+ "TPSAB1",
188
+ "TPSB2",
189
+ "TSPYL4",
190
+ "TTC27",
191
+ "UTP25",
192
+ "VHL",
193
+ "VIPR2",
194
+ "VTI1A",
195
+ "ZKSCAN5",
196
+ "ZNF2",
197
+ "ZNF266",
198
+ "ZNF385A",
199
+ "ZNF557",
200
+ "ZNF620",
201
+ "ZNF654"
202
+ ]
models/single-patch/prad/hvg/model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4f297f40eab72aa2e7706892106ee4428584e7604d0ef91a12272acde8aa60cf
3
+ size 183903592
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ torch==2.10.0
2
+ safetensors==0.8.0
3
+ huggingface-hub==0.36.0
src/__init__.py ADDED
@@ -0,0 +1 @@
 
 
1
+ """SimpleP2G pretrained prediction heads."""
src/pretrained.py ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Load released SimpleP2G prediction heads without an image encoder."""
2
+ from __future__ import annotations
3
+
4
+ import json
5
+ from pathlib import Path
6
+ from types import SimpleNamespace
7
+
8
+ import torch
9
+ from safetensors.torch import load_file
10
+
11
+ from src.simpleP2G import SimpleP2G
12
+
13
+
14
+ DATASETS = ("brain", "prad", "her2st", "lung", "ccrcc")
15
+ PANELS = ("hmhvg", "hvg")
16
+ SETTINGS = ("single-patch", "cross-patch")
17
+
18
+
19
+ def load_pretrained(
20
+ repo_id_or_path="king159/SimpleP2G",
21
+ *,
22
+ dataset="brain",
23
+ panel="hmhvg",
24
+ setting="single-patch",
25
+ device="cpu",
26
+ revision=None,
27
+ cache_dir=None,
28
+ local_files_only=False,
29
+ ):
30
+ """Return an eval-mode model, ordered gene names and checkpoint metadata.
31
+
32
+ ``repo_id_or_path`` is a Hub model ID or a downloaded repository directory.
33
+ Inputs are precomputed image embeddings; no image-encoder weights are loaded.
34
+ Predictions follow the order in ``genes`` and use log2(count + 1) units.
35
+ """
36
+ dataset, panel = dataset.lower(), panel.lower()
37
+ if dataset not in DATASETS or panel not in PANELS or setting not in SETTINGS:
38
+ raise ValueError(f"Unsupported model selection: {dataset}/{panel}/{setting}")
39
+ folder = f"models/{setting}/{dataset}/{panel}"
40
+ local = Path(repo_id_or_path).expanduser()
41
+
42
+ def resolve(filename):
43
+ if local.is_dir():
44
+ path = local / folder / filename
45
+ if not path.is_file():
46
+ raise FileNotFoundError(path)
47
+ return path
48
+ from huggingface_hub import hf_hub_download
49
+
50
+ return Path(hf_hub_download(
51
+ repo_id=str(repo_id_or_path), filename=f"{folder}/{filename}",
52
+ revision=revision, cache_dir=cache_dir, local_files_only=local_files_only,
53
+ ))
54
+
55
+ metadata = json.loads(resolve("config.json").read_text())
56
+ if metadata.get("format_version") != 1:
57
+ raise ValueError("Unsupported checkpoint metadata version")
58
+ expected = {"dataset": dataset, "panel": panel, "setting": setting}
59
+ if any(metadata.get(key) != value for key, value in expected.items()):
60
+ raise ValueError("Checkpoint metadata does not match the requested model")
61
+ genes = json.loads(resolve("genes.json").read_text())
62
+ config = SimpleNamespace(**metadata["model_config"])
63
+ if len(genes) != config.num_genes or len(set(genes)) != len(genes):
64
+ raise ValueError("The ordered gene list must contain one unique name per output")
65
+ if setting == "single-patch":
66
+ model = SimpleP2G(config)
67
+ else:
68
+ from src.simpleP2G_neigh import SimpleP2GNeigh
69
+
70
+ model = SimpleP2GNeigh(config)
71
+ state = load_file(str(resolve("model.safetensors")), device="cpu")
72
+ model.load_state_dict(state, strict=True)
73
+ model.to(device=device).eval().requires_grad_(False)
74
+ return model, genes, metadata
src/simpleP2G.py ADDED
@@ -0,0 +1,350 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Optional
2
+
3
+ import torch
4
+ import torch.nn as nn
5
+ import torch.nn.functional as F
6
+
7
+
8
+ class SimpleP2GRMSNorm(nn.Module):
9
+ def __init__(self, hidden_size, eps=1e-6):
10
+ super().__init__()
11
+ self.weight = nn.Parameter(torch.ones(hidden_size))
12
+ self.variance_epsilon = eps
13
+
14
+ def forward(self, hidden_states):
15
+ input_dtype = hidden_states.dtype
16
+ hidden_states = hidden_states.to(torch.float32)
17
+ variance = hidden_states.pow(2).mean(-1, keepdim=True)
18
+ hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon)
19
+ return self.weight * hidden_states.to(input_dtype)
20
+
21
+
22
+ class SimpleP2GMLP(nn.Module):
23
+ def __init__(self, config):
24
+ super().__init__()
25
+ self.config = config
26
+ self.hidden_size = config.hidden_size
27
+ self.intermediate_size = getattr(
28
+ config,
29
+ "intermediate_size",
30
+ int(config.hidden_size * getattr(config, "mlp_ratio", 4.0)),
31
+ )
32
+ self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
33
+ self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
34
+ self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False)
35
+ self.act_fn = nn.GELU(approximate="tanh")
36
+ self.dropout = nn.Dropout(getattr(config, "dropout", 0.0))
37
+
38
+ def forward(self, x):
39
+ down_proj = self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x))
40
+ return self.dropout(down_proj)
41
+
42
+
43
+ class SimpleP2GAttention(nn.Module):
44
+ """
45
+ multi-head self-attention module using F.scaled_dot_product_attention.
46
+ """
47
+
48
+ def __init__(self, config):
49
+ super().__init__()
50
+ self.config = config
51
+ self.hidden_size = config.hidden_size
52
+ self.num_heads = config.num_heads
53
+ self.head_dim = self.hidden_size // self.num_heads
54
+
55
+ if self.hidden_size % self.num_heads != 0:
56
+ raise ValueError(f"hidden_size {self.hidden_size} must be divisible by num_heads {self.num_heads}")
57
+
58
+ self.attention_dropout = getattr(config, "attention_dropout", 0.0)
59
+
60
+ self.q_proj = nn.Linear(self.hidden_size, self.num_heads * self.head_dim, bias=False)
61
+ self.k_proj = nn.Linear(self.hidden_size, self.num_heads * self.head_dim, bias=False)
62
+ self.v_proj = nn.Linear(self.hidden_size, self.num_heads * self.head_dim, bias=False)
63
+ self.o_proj = nn.Linear(self.num_heads * self.head_dim, self.hidden_size, bias=False)
64
+
65
+ def forward(self, hidden_states: torch.Tensor, attention_mask: Optional[torch.Tensor] = None) -> torch.Tensor:
66
+ batch_size, seq_len, _ = hidden_states.size()
67
+
68
+ query_states = self.q_proj(hidden_states)
69
+ key_states = self.k_proj(hidden_states)
70
+ value_states = self.v_proj(hidden_states)
71
+
72
+ query_states = query_states.view(batch_size, seq_len, self.num_heads, self.head_dim).transpose(1, 2)
73
+ key_states = key_states.view(batch_size, seq_len, self.num_heads, self.head_dim).transpose(1, 2)
74
+ value_states = value_states.view(batch_size, seq_len, self.num_heads, self.head_dim).transpose(1, 2)
75
+
76
+ # Prepare attention mask for F.scaled_dot_product_attention
77
+ # F.sdpa expects mask to be True for positions that should attend
78
+ if attention_mask is not None:
79
+ if attention_mask.dim() == 2: # (B, N)
80
+ # Convert to (B, 1, 1, N) and invert (0 -> False, 1 -> True)
81
+ attention_mask = attention_mask.bool()
82
+ attention_mask = attention_mask.unsqueeze(1).unsqueeze(1)
83
+ elif attention_mask.dim() == 3: # (B, 1, N)
84
+ attention_mask = attention_mask.bool()
85
+ attention_mask = attention_mask.unsqueeze(1)
86
+ elif attention_mask.dim() == 4: # (B, 1, 1, N) or (B, H, N, N)
87
+ attention_mask = attention_mask.bool()
88
+
89
+ # Use F.scaled_dot_product_attention
90
+ attn_output = F.scaled_dot_product_attention(
91
+ query_states,
92
+ key_states,
93
+ value_states,
94
+ attn_mask=attention_mask,
95
+ dropout_p=self.attention_dropout if self.training else 0.0,
96
+ is_causal=False,
97
+ )
98
+
99
+ attn_output = attn_output.transpose(1, 2).contiguous()
100
+ attn_output = attn_output.reshape(batch_size, seq_len, self.hidden_size)
101
+ attn_output = self.o_proj(attn_output)
102
+
103
+ return attn_output
104
+
105
+
106
+ class SimpleP2GCrossAttention(nn.Module):
107
+ """
108
+ Multi-head cross-attention module.
109
+ """
110
+
111
+ def __init__(self, config):
112
+ super().__init__()
113
+ self.config = config
114
+ self.hidden_size = config.hidden_size
115
+ self.num_heads = config.num_heads
116
+ self.head_dim = self.hidden_size // self.num_heads
117
+
118
+ if self.hidden_size % self.num_heads != 0:
119
+ raise ValueError(f"hidden_size {self.hidden_size} must be divisible by num_heads {self.num_heads}")
120
+
121
+ self.attention_dropout = getattr(config, "attention_dropout", 0.0)
122
+
123
+ self.q_proj = nn.Linear(self.hidden_size, self.num_heads * self.head_dim, bias=False)
124
+ self.k_proj = nn.Linear(self.hidden_size, self.num_heads * self.head_dim, bias=False)
125
+ self.v_proj = nn.Linear(self.hidden_size, self.num_heads * self.head_dim, bias=False)
126
+ self.o_proj = nn.Linear(self.num_heads * self.head_dim, self.hidden_size, bias=False)
127
+
128
+ def forward(
129
+ self,
130
+ hidden_states: torch.Tensor, # Query
131
+ encoder_hidden_states: torch.Tensor, # Key, Value
132
+ attention_mask: Optional[torch.Tensor] = None,
133
+ ) -> torch.Tensor:
134
+ batch_size, seq_len, _ = hidden_states.size()
135
+ encoder_seq_len = encoder_hidden_states.size(1)
136
+
137
+ query_states = self.q_proj(hidden_states)
138
+ key_states = self.k_proj(encoder_hidden_states)
139
+ value_states = self.v_proj(encoder_hidden_states)
140
+
141
+ query_states = query_states.view(batch_size, seq_len, self.num_heads, self.head_dim).transpose(1, 2)
142
+ key_states = key_states.view(batch_size, encoder_seq_len, self.num_heads, self.head_dim).transpose(1, 2)
143
+ value_states = value_states.view(batch_size, encoder_seq_len, self.num_heads, self.head_dim).transpose(1, 2)
144
+
145
+ if attention_mask is not None and not (
146
+ attention_mask.is_floating_point() or attention_mask.dtype == torch.bool
147
+ ):
148
+ attention_mask = attention_mask.bool()
149
+
150
+ attn_output = F.scaled_dot_product_attention(
151
+ query_states,
152
+ key_states,
153
+ value_states,
154
+ attn_mask=attention_mask,
155
+ dropout_p=self.attention_dropout if self.training else 0.0,
156
+ is_causal=False,
157
+ )
158
+
159
+ attn_output = attn_output.transpose(1, 2).contiguous()
160
+ attn_output = attn_output.reshape(batch_size, seq_len, self.hidden_size)
161
+ attn_output = self.o_proj(attn_output)
162
+
163
+ return attn_output
164
+
165
+
166
+ class SimpleP2GDecoderLayer(nn.Module):
167
+ def __init__(self, config):
168
+ super().__init__()
169
+ self.hidden_size = config.hidden_size
170
+ eps = getattr(config, "rms_norm_eps", 1e-6)
171
+
172
+ # Layers
173
+ self.self_attn = SimpleP2GAttention(config=config)
174
+ self.cross_attn = SimpleP2GCrossAttention(config=config)
175
+ self.mlp = SimpleP2GMLP(config)
176
+
177
+ # Pre-Norms (Normalization happens BEFORE the sub-layer)
178
+ self.norm1 = SimpleP2GRMSNorm(self.hidden_size, eps=eps)
179
+ self.norm2 = SimpleP2GRMSNorm(self.hidden_size, eps=eps)
180
+ self.norm3 = SimpleP2GRMSNorm(self.hidden_size, eps=eps)
181
+ self.resid_dropout = nn.Dropout(getattr(config, "dropout", 0.0))
182
+
183
+ def forward(self, x, encoder_hidden_states, attention_mask=None, cross_attention_mask=None):
184
+ # 1. Self-Attention (Genes interacting with each other)
185
+ x = x + self.resid_dropout(self.self_attn(self.norm1(x), attention_mask=attention_mask))
186
+
187
+ # 2. Cross-Attention (Genes looking at the image context)
188
+ x = x + self.resid_dropout(
189
+ self.cross_attn(self.norm2(x), encoder_hidden_states, attention_mask=cross_attention_mask)
190
+ )
191
+
192
+ # 3. Feed-Forward
193
+ x = x + self.mlp(self.norm3(x))
194
+
195
+ return x
196
+
197
+
198
+ class SimpleP2G(nn.Module):
199
+ def __init__(
200
+ self,
201
+ config,
202
+ ) -> None:
203
+ super().__init__()
204
+ self.config = config
205
+ self.decoder_depth = config.decoder_depth
206
+ self.num_genes = config.num_genes
207
+ self.hidden_size = config.hidden_size
208
+ self.gene_queries = nn.Embedding(self.num_genes, self.hidden_size)
209
+ self.cond_size = config.cond_size
210
+ self.num_cond_tokens = getattr(config, "num_cond_tokens", 1)
211
+ self.decoder_blocks = nn.ModuleList([SimpleP2GDecoderLayer(config) for _ in range(self.decoder_depth)])
212
+ self.final_norm = SimpleP2GRMSNorm(self.hidden_size)
213
+ self.mean_head = nn.Linear(self.hidden_size, 1)
214
+ if config.loss_name in ["gaussian_nll", "beta_nll"]:
215
+ self.log_var_head = nn.Linear(self.hidden_size, 1)
216
+ # if config.loss_name == "zinb":
217
+ # self.pi_head = nn.Linear(self.hidden_size, 1)
218
+ self.gradient_checkpointing = False
219
+ self.emb_dropout = nn.Dropout(getattr(config, "dropout", 0.0))
220
+
221
+ # ── Additional regularization ──
222
+ self.gene_drop_rate = float(getattr(config, "gene_drop_rate", 0.0))
223
+ self.emb_noise_std = float(getattr(config, "emb_noise_std", 0.0))
224
+ self.stochastic_depth_rate = float(getattr(config, "stochastic_depth_rate", 0.0))
225
+
226
+ self.label_embed = nn.Sequential(
227
+ nn.Linear(self.cond_size, self.cond_size, bias=True),
228
+ nn.SiLU(),
229
+ nn.Linear(self.cond_size, self.hidden_size * self.num_cond_tokens, bias=True),
230
+ )
231
+
232
+ def forward(self, c: torch.Tensor) -> tuple[torch.Tensor, ...]:
233
+ """Forward pass."""
234
+ output = self.gene_queries.weight.unsqueeze(0).expand(c.size(0), -1, -1) # (B, num_genes, hidden_size)
235
+ output = self.emb_dropout(output)
236
+
237
+ # Gene dropout: randomly zero out gene query positions during training
238
+ if self.training and self.gene_drop_rate > 0:
239
+ gene_mask = torch.rand(c.size(0), self.num_genes, 1, device=c.device) > self.gene_drop_rate
240
+ output = output * gene_mask # zero out dropped genes
241
+
242
+ condition = self.label_embed(c).view(c.size(0), self.num_cond_tokens, self.hidden_size) # (B, T, hidden_size)
243
+
244
+ # Embedding noise: add Gaussian noise to conditioning tokens during training
245
+ if self.training and self.emb_noise_std > 0:
246
+ condition = condition + torch.randn_like(condition) * self.emb_noise_std
247
+ for i, block in enumerate(self.decoder_blocks):
248
+ # Stochastic depth: randomly skip layers during training
249
+ if self.training and self.stochastic_depth_rate > 0:
250
+ # Linear scaling: deeper layers have higher drop probability
251
+ drop_prob = self.stochastic_depth_rate * i / max(len(self.decoder_blocks) - 1, 1)
252
+ if torch.rand(1).item() < drop_prob:
253
+ continue
254
+
255
+ if self.gradient_checkpointing and self.training:
256
+ output = torch.utils.checkpoint.checkpoint(
257
+ block,
258
+ output,
259
+ encoder_hidden_states=condition,
260
+ use_reentrant=False,
261
+ )
262
+ else:
263
+ output = block(
264
+ output,
265
+ encoder_hidden_states=condition,
266
+ )
267
+ output = self.final_norm(output)
268
+ raw_mean = self.mean_head(output).squeeze(-1)
269
+ mean = F.softplus(raw_mean) # Ensures predicted G >= 0
270
+ if self.config.loss_name in ["gaussian_nll", "beta_nll"]:
271
+ log_var = self.log_var_head(output).squeeze(-1)
272
+ # if self.config.loss_name == "zinb":
273
+ # pi_logits = self.pi_head(output).squeeze(-1)
274
+ # return mean, log_var, pi_logits
275
+ elif self.config.loss_name in ["mse", "l1"]:
276
+ log_var = torch.zeros_like(mean)
277
+ return mean, log_var
278
+
279
+
280
+ def get_loss_fn(loss_type: str) -> nn.Module:
281
+ if loss_type == "gaussian_nll":
282
+ return GaussianNLLLoss()
283
+ elif loss_type == "beta_nll":
284
+ return BetaNLLLoss(beta=1.0)
285
+ elif loss_type == "mse":
286
+ return nn.MSELoss()
287
+ elif loss_type == "l1":
288
+ return nn.L1Loss()
289
+ else:
290
+ raise ValueError(f"Unsupported loss type: {loss_type}")
291
+
292
+
293
+ class GaussianNLLLoss(nn.Module):
294
+ def __init__(self, logvar_clipping=(-10, 10)):
295
+ super().__init__()
296
+ self.min_logvar, self.max_logvar = logvar_clipping
297
+
298
+ def forward(self, pred_mean, pred_logvar, target):
299
+ # 1. Clamp logvar to prevent NaN gradients or Inf precision
300
+ pred_logvar = torch.clamp(pred_logvar, self.min_logvar, self.max_logvar)
301
+
302
+ # 2. Precision = exp(-logvar) is 1/sigma^2
303
+ precision = torch.exp(-pred_logvar)
304
+
305
+ # 3. Standard NLL formula components
306
+ # (target - mean)^2 / variance + log(variance)
307
+ diff = (target - pred_mean) ** 2
308
+ loss = 0.5 * (precision * diff + pred_logvar)
309
+
310
+ return loss.mean()
311
+
312
+
313
+ class BetaNLLLoss(nn.Module):
314
+ """
315
+ Beta-Negative Log-Likelihood Loss.
316
+ Reference: Seitzer et al., "Properties and Benefits of Training with
317
+ Beta-Negative Log-Likelihood", ICLR 2022.
318
+ """
319
+
320
+ def __init__(self, beta=1.0, logvar_clipping=(-10, 10)):
321
+ super().__init__()
322
+ self.beta = beta
323
+ self.min_logvar, self.max_logvar = logvar_clipping
324
+
325
+ def forward(self, pred_mean, pred_logvar, target):
326
+ """
327
+ pred_mean: (B, num_genes)
328
+ pred_logvar: (B, num_genes)
329
+ target: (B, num_genes)
330
+ """
331
+ # 1. Clamp for stability
332
+ pred_logvar = torch.clamp(pred_logvar, self.min_logvar, self.max_logvar)
333
+
334
+ # 2. Calculate variance (sigma^2)
335
+ variance = torch.exp(pred_logvar)
336
+
337
+ # 3. Standard Gaussian NLL components
338
+ # (y - mu)^2 / sigma^2 + log(sigma^2)
339
+ squared_error = (target - pred_mean) ** 2
340
+ nll = (squared_error / variance) + pred_logvar
341
+
342
+ # 4. Apply Beta Weighting
343
+ # The 'stop_gradient' (detach) on the multiplier is optional
344
+ # but often used to stabilize the variance head.
345
+ # The paper version uses the variance gradient as well.
346
+ weight = variance.detach() ** self.beta
347
+
348
+ loss = 0.5 * weight * nll
349
+
350
+ return loss.mean()
src/simpleP2G_neigh.py ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """SimpleP2G-cross: target tokens and spatially positioned neighbor tokens."""
2
+
3
+ import torch
4
+ from torch import nn
5
+ from torch.nn import functional as F
6
+ from torch.utils.checkpoint import checkpoint
7
+
8
+ from src.simpleP2G import SimpleP2GDecoderLayer, SimpleP2GRMSNorm
9
+
10
+
11
+ class SimpleP2GNeigh(nn.Module):
12
+ """The target-plus-neighbors model used in the main comparison."""
13
+
14
+ def __init__(self, config):
15
+ super().__init__()
16
+ self.config = config
17
+ self.decoder_depth = config.decoder_depth
18
+ self.num_genes = config.num_genes
19
+ self.hidden_size = config.hidden_size
20
+ self.cond_size = config.cond_size
21
+ self.num_cond_tokens = getattr(config, "num_cond_tokens", 4)
22
+ self.num_neighbor_tokens = int(getattr(config, "num_neighbor_tokens", 24))
23
+ if str(getattr(config, "neighbor_position_mode", "relative")) != "relative":
24
+ raise ValueError("SimpleP2G-cross requires relative neighbor positions")
25
+ for key in ("neighbor_cond_size", "global_cond_size"):
26
+ if int(getattr(config, key, self.cond_size)) != self.cond_size:
27
+ raise ValueError("All image embeddings must use the same encoder dimension")
28
+ if (
29
+ not getattr(config, "use_target_context", True)
30
+ or not getattr(config, "use_neighbor_context", True)
31
+ or getattr(config, "use_slide_context", False)
32
+ or getattr(config, "use_local_summary", False)
33
+ or getattr(config, "context_source_balance", 0.0) != 0
34
+ ):
35
+ raise ValueError(
36
+ "This model requires target + neighbor context; use the separate experiment entry point for other variants"
37
+ )
38
+ self.gene_queries = nn.Embedding(self.num_genes, self.hidden_size)
39
+ self.label_embed = nn.Sequential(
40
+ nn.Linear(self.cond_size, self.cond_size),
41
+ nn.SiLU(),
42
+ nn.Linear(self.cond_size, self.hidden_size * self.num_cond_tokens),
43
+ )
44
+ self.neighbor_proj = nn.Sequential(
45
+ nn.Linear(self.cond_size, self.hidden_size),
46
+ nn.SiLU(),
47
+ nn.Linear(self.hidden_size, self.hidden_size),
48
+ )
49
+ self.neighbor_pos_proj = nn.Sequential(
50
+ nn.Linear(2, self.hidden_size),
51
+ nn.SiLU(),
52
+ nn.Linear(self.hidden_size, self.hidden_size),
53
+ )
54
+ self.decoder_blocks = nn.ModuleList([SimpleP2GDecoderLayer(config) for _ in range(self.decoder_depth)])
55
+ self.final_norm = SimpleP2GRMSNorm(self.hidden_size)
56
+ self.mean_head = nn.Linear(self.hidden_size, 1)
57
+ if config.loss_name in ("gaussian_nll", "beta_nll"):
58
+ self.log_var_head = nn.Linear(self.hidden_size, 1)
59
+ self.gradient_checkpointing = False
60
+ self.emb_dropout = nn.Dropout(getattr(config, "dropout", 0.0))
61
+
62
+ def forward(self, c, neighbor_emb=None, neighbor_mask=None, neighbor_pos=None, global_emb=None):
63
+ """Predict from target (B,D), neighbors (B,K,D) and relative positions.
64
+
65
+ global_emb is accepted for the shared slide-dataset interface; the
66
+ main-comparison model does not consume a slide token.
67
+ """
68
+ if neighbor_emb is None or neighbor_pos is None:
69
+ raise ValueError("neighbor_emb and neighbor_pos are required")
70
+ batch_size = c.shape[0]
71
+ output = self.emb_dropout(self.gene_queries.weight.unsqueeze(0).expand(batch_size, -1, -1))
72
+ target = self.label_embed(c).view(batch_size, self.num_cond_tokens, self.hidden_size)
73
+ neighbors = self.neighbor_proj(neighbor_emb)
74
+ neighbors = neighbors + self.neighbor_pos_proj(neighbor_pos.to(dtype=neighbors.dtype))
75
+ condition = torch.cat((target, neighbors), dim=1)
76
+ if neighbor_mask is None:
77
+ neighbor_mask = torch.ones(neighbor_emb.shape[:2], device=c.device, dtype=torch.bool)
78
+ target_mask = torch.ones(batch_size, self.num_cond_tokens, device=c.device, dtype=torch.bool)
79
+ mask = torch.cat((target_mask, neighbor_mask.bool()), dim=1).unsqueeze(1).unsqueeze(1)
80
+ for block in self.decoder_blocks:
81
+ if self.gradient_checkpointing and self.training:
82
+ output = checkpoint(block, output, condition, None, mask, use_reentrant=False)
83
+ else:
84
+ output = block(output, encoder_hidden_states=condition, cross_attention_mask=mask)
85
+ output = self.final_norm(output)
86
+ mean = F.softplus(self.mean_head(output).squeeze(-1))
87
+ log_var = (
88
+ self.log_var_head(output).squeeze(-1)
89
+ if self.config.loss_name in ("gaussian_nll", "beta_nll")
90
+ else torch.zeros_like(mean)
91
+ )
92
+ return mean, log_var