relbench 2.1.0__tar.gz → 2.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {relbench-2.1.0 → relbench-2.1.2}/PKG-INFO +48 -23
- {relbench-2.1.0 → relbench-2.1.2}/README.md +46 -22
- {relbench-2.1.0 → relbench-2.1.2}/pyproject.toml +2 -1
- {relbench-2.1.0 → relbench-2.1.2}/relbench/base/table.py +5 -0
- {relbench-2.1.0 → relbench-2.1.2}/relbench/base/task_autocomplete.py +2 -4
- {relbench-2.1.0 → relbench-2.1.2}/relbench/base/task_recommendation.py +3 -0
- {relbench-2.1.0 → relbench-2.1.2}/relbench/datasets/__init__.py +23 -8
- {relbench-2.1.0 → relbench-2.1.2}/relbench/datasets/dbinfer.py +12 -1
- relbench-2.1.2/relbench/datasets/hashes.json +38 -0
- {relbench-2.1.0 → relbench-2.1.2}/relbench/datasets/mimic.py +16 -1
- relbench-2.1.2/relbench/datasets/tgb.py +75 -0
- {relbench-2.1.0 → relbench-2.1.2}/relbench/modeling/loader.py +5 -2
- {relbench-2.1.0 → relbench-2.1.2}/relbench/modeling/nn.py +68 -1
- {relbench-2.1.0 → relbench-2.1.2}/relbench/modeling/utils.py +16 -6
- {relbench-2.1.0 → relbench-2.1.2}/relbench/tasks/__init__.py +94 -47
- {relbench-2.1.0 → relbench-2.1.2}/relbench/tasks/amazon.py +14 -28
- {relbench-2.1.0 → relbench-2.1.2}/relbench/tasks/arxiv.py +8 -16
- {relbench-2.1.0 → relbench-2.1.2}/relbench/tasks/avito.py +8 -16
- {relbench-2.1.0 → relbench-2.1.2}/relbench/tasks/dbinfer.py +38 -3
- {relbench-2.1.0 → relbench-2.1.2}/relbench/tasks/event.py +6 -12
- {relbench-2.1.0 → relbench-2.1.2}/relbench/tasks/f1.py +8 -16
- {relbench-2.1.0 → relbench-2.1.2}/relbench/tasks/hashes.json +47 -3
- {relbench-2.1.0 → relbench-2.1.2}/relbench/tasks/hm.py +6 -12
- {relbench-2.1.0 → relbench-2.1.2}/relbench/tasks/mimic.py +8 -4
- {relbench-2.1.0 → relbench-2.1.2}/relbench/tasks/ratebeer.py +14 -28
- {relbench-2.1.0 → relbench-2.1.2}/relbench/tasks/stack.py +10 -20
- relbench-2.1.2/relbench/tasks/tgb.py +627 -0
- {relbench-2.1.0 → relbench-2.1.2}/relbench/tasks/trial.py +10 -20
- relbench-2.1.0/relbench/datasets/hashes.json +0 -20
- {relbench-2.1.0 → relbench-2.1.2}/LICENSE +0 -0
- {relbench-2.1.0 → relbench-2.1.2}/relbench/__init__.py +0 -0
- {relbench-2.1.0 → relbench-2.1.2}/relbench/base/__init__.py +0 -0
- {relbench-2.1.0 → relbench-2.1.2}/relbench/base/database.py +0 -0
- {relbench-2.1.0 → relbench-2.1.2}/relbench/base/dataset.py +0 -0
- {relbench-2.1.0 → relbench-2.1.2}/relbench/base/task_base.py +0 -0
- {relbench-2.1.0 → relbench-2.1.2}/relbench/base/task_entity.py +0 -0
- {relbench-2.1.0 → relbench-2.1.2}/relbench/datasets/amazon.py +0 -0
- {relbench-2.1.0 → relbench-2.1.2}/relbench/datasets/arxiv.py +0 -0
- {relbench-2.1.0 → relbench-2.1.2}/relbench/datasets/avito.py +0 -0
- {relbench-2.1.0 → relbench-2.1.2}/relbench/datasets/event.py +0 -0
- {relbench-2.1.0 → relbench-2.1.2}/relbench/datasets/f1.py +0 -0
- {relbench-2.1.0 → relbench-2.1.2}/relbench/datasets/fake.py +0 -0
- {relbench-2.1.0 → relbench-2.1.2}/relbench/datasets/hm.py +0 -0
- {relbench-2.1.0 → relbench-2.1.2}/relbench/datasets/ratebeer.py +0 -0
- {relbench-2.1.0 → relbench-2.1.2}/relbench/datasets/salt.py +0 -0
- {relbench-2.1.0 → relbench-2.1.2}/relbench/datasets/stack.py +0 -0
- {relbench-2.1.0 → relbench-2.1.2}/relbench/datasets/trial.py +0 -0
- {relbench-2.1.0 → relbench-2.1.2}/relbench/metrics.py +0 -0
- {relbench-2.1.0 → relbench-2.1.2}/relbench/modeling/__init__.py +0 -0
- {relbench-2.1.0 → relbench-2.1.2}/relbench/modeling/graph.py +0 -0
- {relbench-2.1.0 → relbench-2.1.2}/relbench/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: relbench
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.2
|
|
4
4
|
Summary: RelBench: Relational Deep Learning Benchmark
|
|
5
5
|
Keywords:
|
|
6
6
|
Author-email: RelBench Team <relbench@cs.stanford.edu>
|
|
@@ -18,6 +18,7 @@ Requires-Dist: typing-extensions
|
|
|
18
18
|
Requires-Dist: datasets
|
|
19
19
|
Requires-Dist: redelex ; extra == "ctu"
|
|
20
20
|
Requires-Dist: dbinfer-relbench-adapter ; extra == "dbinfer"
|
|
21
|
+
Requires-Dist: db-dtypes ; extra == "dbinfer"
|
|
21
22
|
Requires-Dist: pre-commit ; extra == "dev"
|
|
22
23
|
Requires-Dist: sentence-transformers ; extra == "example"
|
|
23
24
|
Requires-Dist: pytorch_frame[full] ; extra == "example"
|
|
@@ -48,7 +49,7 @@ Provides-Extra: test
|
|
|
48
49
|
|
|
49
50
|
|
|
50
51
|
<!-- [<img align="center" src="https://relbench.stanford.edu/img/favicon.png" width="20px" /> -->
|
|
51
|
-
[**Website**](https://relbench.stanford.edu) | [**Position Paper**](https://proceedings.mlr.press/v235/fey24a.html) | [**
|
|
52
|
+
[**Website**](https://relbench.stanford.edu) | [**Position Paper**](https://proceedings.mlr.press/v235/fey24a.html) | [**RelBench v1 Paper**](https://arxiv.org/abs/2407.20060) | [**RelBench v2 Paper**](https://arxiv.org/abs/2602.12606) | [**Mailing List**](https://groups.google.com/forum/#!forum/relbench/join)
|
|
52
53
|
|
|
53
54
|
# News
|
|
54
55
|
|
|
@@ -124,7 +125,30 @@ pip install relbench
|
|
|
124
125
|
|
|
125
126
|
This will allow usage of the core RelBench data and task loading functionality.
|
|
126
127
|
|
|
127
|
-
|
|
128
|
+
|
|
129
|
+
To additionally use `relbench.modeling`, which requires [PyTorch](https://pytorch.org/), [PyTorch Geometric](https://github.com/pyg-team/pytorch_geometric) and [PyTorch Frame](https://github.com/pyg-team/pytorch-frame), install these dependencies manually or do:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
pip install relbench[full]
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
For the scripts in the `examples` directory, use:
|
|
137
|
+
```bash
|
|
138
|
+
pip install relbench[example]
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Then, to run a script:
|
|
142
|
+
```bash
|
|
143
|
+
git clone https://github.com/snap-stanford/relbench
|
|
144
|
+
cd relbench/examples
|
|
145
|
+
python gnn_entity.py --dataset rel-f1 --task driver-position
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
## Using External Integrations
|
|
150
|
+
|
|
151
|
+
**Using CTU datasets**
|
|
128
152
|
|
|
129
153
|
To use datasets from the CTU repository, use:
|
|
130
154
|
```bash
|
|
@@ -133,7 +157,7 @@ pip install relbench[ctu]
|
|
|
133
157
|
|
|
134
158
|
If you use the CTU datasets in your work, please cite [ReDeLEx](https://github.com/jakubpeleska/redelex) as below:
|
|
135
159
|
|
|
136
|
-
```
|
|
160
|
+
```bibtex
|
|
137
161
|
@misc{peleska2025redelex,
|
|
138
162
|
title={REDELEX: A Framework for Relational Deep Learning Exploration},
|
|
139
163
|
author={Jakub Peleška and Gustav Šír},
|
|
@@ -145,9 +169,9 @@ If you use the CTU datasets in your work, please cite [ReDeLEx](https://github.c
|
|
|
145
169
|
}
|
|
146
170
|
```
|
|
147
171
|
|
|
148
|
-
</details>
|
|
149
172
|
|
|
150
|
-
|
|
173
|
+
|
|
174
|
+
**Using 4DBInfer datasets**
|
|
151
175
|
|
|
152
176
|
To use datasets from the 4DBInfer repository, use:
|
|
153
177
|
```bash
|
|
@@ -155,7 +179,7 @@ pip install relbench[dbinfer]
|
|
|
155
179
|
```
|
|
156
180
|
|
|
157
181
|
If you use the 4DBInfer datasets in your work, please cite [4DBInfer](https://github.com/awslabs/multi-table-benchmark) as below:
|
|
158
|
-
```
|
|
182
|
+
```bibtex
|
|
159
183
|
@article{dbinfer,
|
|
160
184
|
title={4DBInfer: A 4D Benchmarking Toolbox for Graph-Centric Predictive Modeling on Relational DBs},
|
|
161
185
|
author={Wang, Minjie and Gan, Quan and Wipf, David and Cai, Zhenkun and Li, Ning and Tang, Jianheng and Zhang, Yanlin and Zhang, Zizhao and Mao, Zunyao and Song, Yakun and Wang, Yanbo and Li, Jiahang and Zhang, Han and Yang, Guang and Qin, Xiao and Lei, Chuan and Zhang, Muhan and Zhang, Weinan and Faloutsos, Christos and Zhang, Zheng},
|
|
@@ -164,28 +188,29 @@ If you use the 4DBInfer datasets in your work, please cite [4DBInfer](https://gi
|
|
|
164
188
|
}
|
|
165
189
|
```
|
|
166
190
|
|
|
167
|
-
|
|
168
|
-
<br>
|
|
169
|
-
|
|
191
|
+
**Using TGB datasets**
|
|
170
192
|
|
|
171
|
-
|
|
193
|
+
[TGB](https://tgb.complexdatalab.com/) datasets and tasks can be loaded in the RelBench format, and they cover bipartite link prediction (`tgbl-*`), heterogeneous link prediction (`thgl-*`), and node property prediction (`tgbn-*`). See `relbench/tasks/tgb.py` for the official TGB evaluation protocols (one-vs-many MRR / Hits@10 for link prediction, NDCG@10 for node property prediction). Standard RelBench style evaluation works as it is.
|
|
172
194
|
|
|
173
|
-
|
|
174
|
-
|
|
195
|
+
If you use the TGB datasets in your work, please cite [TGB](https://tgb.complexdatalab.com/) as below:
|
|
196
|
+
```bibtex
|
|
197
|
+
@article{huang2023temporal,
|
|
198
|
+
title={Temporal graph benchmark for machine learning on temporal graphs},
|
|
199
|
+
author={Huang, Shenyang and Poursafaei, Farimah and Danovitch, Jacob and Fey, Matthias and Hu, Weihua and Rossi, Emanuele and Leskovec, Jure and Bronstein, Michael and Rabusseau, Guillaume and Rabbany, Reihaneh},
|
|
200
|
+
journal={Advances in Neural Information Processing Systems},
|
|
201
|
+
year={2023}
|
|
202
|
+
}
|
|
175
203
|
```
|
|
176
204
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
205
|
+
```bibtex
|
|
206
|
+
@article{huang2024tgb2,
|
|
207
|
+
title={TGB 2.0: A Benchmark for Learning on Temporal Knowledge Graphs and Heterogeneous Graphs},
|
|
208
|
+
author={Gastinger, Julia and Huang, Shenyang and Galkin, Mikhail and Loghmani, Erfan and Parviz, Ali and Poursafaei, Farimah and Danovitch, Jacob and Rossi, Emanuele and Koutis, Ioannis and Stuckenschmidt, Heiner and Rabbany, Reihaneh and Rabusseau, Guillaume},
|
|
209
|
+
journal={Advances in Neural Information Processing Systems},
|
|
210
|
+
year={2024}
|
|
211
|
+
}
|
|
181
212
|
```
|
|
182
213
|
|
|
183
|
-
Then, to run a script:
|
|
184
|
-
```bash
|
|
185
|
-
git clone https://github.com/snap-stanford/relbench
|
|
186
|
-
cd relbench/examples
|
|
187
|
-
python gnn_entity.py --dataset rel-f1 --task driver-position
|
|
188
|
-
```
|
|
189
214
|
|
|
190
215
|
|
|
191
216
|
# Package Usage
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
<!-- [<img align="center" src="https://relbench.stanford.edu/img/favicon.png" width="20px" /> -->
|
|
15
|
-
[**Website**](https://relbench.stanford.edu) | [**Position Paper**](https://proceedings.mlr.press/v235/fey24a.html) | [**
|
|
15
|
+
[**Website**](https://relbench.stanford.edu) | [**Position Paper**](https://proceedings.mlr.press/v235/fey24a.html) | [**RelBench v1 Paper**](https://arxiv.org/abs/2407.20060) | [**RelBench v2 Paper**](https://arxiv.org/abs/2602.12606) | [**Mailing List**](https://groups.google.com/forum/#!forum/relbench/join)
|
|
16
16
|
|
|
17
17
|
# News
|
|
18
18
|
|
|
@@ -88,7 +88,30 @@ pip install relbench
|
|
|
88
88
|
|
|
89
89
|
This will allow usage of the core RelBench data and task loading functionality.
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
|
|
92
|
+
To additionally use `relbench.modeling`, which requires [PyTorch](https://pytorch.org/), [PyTorch Geometric](https://github.com/pyg-team/pytorch_geometric) and [PyTorch Frame](https://github.com/pyg-team/pytorch-frame), install these dependencies manually or do:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
pip install relbench[full]
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
For the scripts in the `examples` directory, use:
|
|
100
|
+
```bash
|
|
101
|
+
pip install relbench[example]
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Then, to run a script:
|
|
105
|
+
```bash
|
|
106
|
+
git clone https://github.com/snap-stanford/relbench
|
|
107
|
+
cd relbench/examples
|
|
108
|
+
python gnn_entity.py --dataset rel-f1 --task driver-position
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
## Using External Integrations
|
|
113
|
+
|
|
114
|
+
**Using CTU datasets**
|
|
92
115
|
|
|
93
116
|
To use datasets from the CTU repository, use:
|
|
94
117
|
```bash
|
|
@@ -97,7 +120,7 @@ pip install relbench[ctu]
|
|
|
97
120
|
|
|
98
121
|
If you use the CTU datasets in your work, please cite [ReDeLEx](https://github.com/jakubpeleska/redelex) as below:
|
|
99
122
|
|
|
100
|
-
```
|
|
123
|
+
```bibtex
|
|
101
124
|
@misc{peleska2025redelex,
|
|
102
125
|
title={REDELEX: A Framework for Relational Deep Learning Exploration},
|
|
103
126
|
author={Jakub Peleška and Gustav Šír},
|
|
@@ -109,9 +132,9 @@ If you use the CTU datasets in your work, please cite [ReDeLEx](https://github.c
|
|
|
109
132
|
}
|
|
110
133
|
```
|
|
111
134
|
|
|
112
|
-
</details>
|
|
113
135
|
|
|
114
|
-
|
|
136
|
+
|
|
137
|
+
**Using 4DBInfer datasets**
|
|
115
138
|
|
|
116
139
|
To use datasets from the 4DBInfer repository, use:
|
|
117
140
|
```bash
|
|
@@ -119,7 +142,7 @@ pip install relbench[dbinfer]
|
|
|
119
142
|
```
|
|
120
143
|
|
|
121
144
|
If you use the 4DBInfer datasets in your work, please cite [4DBInfer](https://github.com/awslabs/multi-table-benchmark) as below:
|
|
122
|
-
```
|
|
145
|
+
```bibtex
|
|
123
146
|
@article{dbinfer,
|
|
124
147
|
title={4DBInfer: A 4D Benchmarking Toolbox for Graph-Centric Predictive Modeling on Relational DBs},
|
|
125
148
|
author={Wang, Minjie and Gan, Quan and Wipf, David and Cai, Zhenkun and Li, Ning and Tang, Jianheng and Zhang, Yanlin and Zhang, Zizhao and Mao, Zunyao and Song, Yakun and Wang, Yanbo and Li, Jiahang and Zhang, Han and Yang, Guang and Qin, Xiao and Lei, Chuan and Zhang, Muhan and Zhang, Weinan and Faloutsos, Christos and Zhang, Zheng},
|
|
@@ -128,28 +151,29 @@ If you use the 4DBInfer datasets in your work, please cite [4DBInfer](https://gi
|
|
|
128
151
|
}
|
|
129
152
|
```
|
|
130
153
|
|
|
131
|
-
|
|
132
|
-
<br>
|
|
133
|
-
|
|
154
|
+
**Using TGB datasets**
|
|
134
155
|
|
|
135
|
-
|
|
156
|
+
[TGB](https://tgb.complexdatalab.com/) datasets and tasks can be loaded in the RelBench format, and they cover bipartite link prediction (`tgbl-*`), heterogeneous link prediction (`thgl-*`), and node property prediction (`tgbn-*`). See `relbench/tasks/tgb.py` for the official TGB evaluation protocols (one-vs-many MRR / Hits@10 for link prediction, NDCG@10 for node property prediction). Standard RelBench style evaluation works as it is.
|
|
136
157
|
|
|
137
|
-
|
|
138
|
-
|
|
158
|
+
If you use the TGB datasets in your work, please cite [TGB](https://tgb.complexdatalab.com/) as below:
|
|
159
|
+
```bibtex
|
|
160
|
+
@article{huang2023temporal,
|
|
161
|
+
title={Temporal graph benchmark for machine learning on temporal graphs},
|
|
162
|
+
author={Huang, Shenyang and Poursafaei, Farimah and Danovitch, Jacob and Fey, Matthias and Hu, Weihua and Rossi, Emanuele and Leskovec, Jure and Bronstein, Michael and Rabusseau, Guillaume and Rabbany, Reihaneh},
|
|
163
|
+
journal={Advances in Neural Information Processing Systems},
|
|
164
|
+
year={2023}
|
|
165
|
+
}
|
|
139
166
|
```
|
|
140
167
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
168
|
+
```bibtex
|
|
169
|
+
@article{huang2024tgb2,
|
|
170
|
+
title={TGB 2.0: A Benchmark for Learning on Temporal Knowledge Graphs and Heterogeneous Graphs},
|
|
171
|
+
author={Gastinger, Julia and Huang, Shenyang and Galkin, Mikhail and Loghmani, Erfan and Parviz, Ali and Poursafaei, Farimah and Danovitch, Jacob and Rossi, Emanuele and Koutis, Ioannis and Stuckenschmidt, Heiner and Rabbany, Reihaneh and Rabusseau, Guillaume},
|
|
172
|
+
journal={Advances in Neural Information Processing Systems},
|
|
173
|
+
year={2024}
|
|
174
|
+
}
|
|
145
175
|
```
|
|
146
176
|
|
|
147
|
-
Then, to run a script:
|
|
148
|
-
```bash
|
|
149
|
-
git clone https://github.com/snap-stanford/relbench
|
|
150
|
-
cd relbench/examples
|
|
151
|
-
python gnn_entity.py --dataset rel-f1 --task driver-position
|
|
152
|
-
```
|
|
153
177
|
|
|
154
178
|
|
|
155
179
|
# Package Usage
|
|
@@ -4,7 +4,7 @@ build-backend = "flit_core.buildapi"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "relbench"
|
|
7
|
-
version = "2.1.
|
|
7
|
+
version = "2.1.2"
|
|
8
8
|
description = "RelBench: Relational Deep Learning Benchmark"
|
|
9
9
|
authors = [{name = "RelBench Team", email = "relbench@cs.stanford.edu"}]
|
|
10
10
|
readme = "README.md"
|
|
@@ -44,6 +44,7 @@ dev=[
|
|
|
44
44
|
]
|
|
45
45
|
dbinfer=[
|
|
46
46
|
"dbinfer-relbench-adapter",
|
|
47
|
+
"db-dtypes",
|
|
47
48
|
]
|
|
48
49
|
ctu=[
|
|
49
50
|
"redelex",
|
|
@@ -84,6 +84,11 @@ class Table:
|
|
|
84
84
|
# Read the Parquet file using pyarrow
|
|
85
85
|
table = pa.parquet.read_table(path)
|
|
86
86
|
df = table.to_pandas()
|
|
87
|
+
# DuckDB currently cannot ingest pandas StringDtype columns reliably.
|
|
88
|
+
# Convert them to plain object dtype on load.
|
|
89
|
+
for col in df.columns:
|
|
90
|
+
if isinstance(df[col].dtype, pd.StringDtype):
|
|
91
|
+
df[col] = df[col].astype(object)
|
|
87
92
|
|
|
88
93
|
# Extract metadata
|
|
89
94
|
metadata_bytes = table.schema.metadata
|
|
@@ -173,8 +173,7 @@ class AutoCompleteTask(EntityTask):
|
|
|
173
173
|
min_timestamp = timestamp_df["timestamp"].min()
|
|
174
174
|
max_timestamp = timestamp_df["timestamp"].max()
|
|
175
175
|
|
|
176
|
-
df = duckdb.sql(
|
|
177
|
-
f"""
|
|
176
|
+
df = duckdb.sql(f"""
|
|
178
177
|
SELECT
|
|
179
178
|
entity_table.{self.time_col},
|
|
180
179
|
entity_table.{entity_col},
|
|
@@ -188,8 +187,7 @@ class AutoCompleteTask(EntityTask):
|
|
|
188
187
|
WHERE
|
|
189
188
|
entity_table.{self.time_col} > '{min_timestamp}' AND
|
|
190
189
|
entity_table.{self.time_col} <= '{max_timestamp}'
|
|
191
|
-
"""
|
|
192
|
-
).df()
|
|
190
|
+
""").df()
|
|
193
191
|
|
|
194
192
|
if self.task_type == TaskType.MULTICLASS_CLASSIFICATION:
|
|
195
193
|
df[self.target_col] = self.transform_target(df[self.target_col])
|
|
@@ -18,6 +18,7 @@ from relbench.datasets import (
|
|
|
18
18
|
ratebeer,
|
|
19
19
|
salt,
|
|
20
20
|
stack,
|
|
21
|
+
tgb,
|
|
21
22
|
trial,
|
|
22
23
|
)
|
|
23
24
|
from relbench.utils import get_relbench_cache_dir
|
|
@@ -70,15 +71,8 @@ def download_dataset(name: str) -> None:
|
|
|
70
71
|
The downloaded database will be automatically picked up by the dataset object, when
|
|
71
72
|
`dataset.get_db()` is called.
|
|
72
73
|
"""
|
|
73
|
-
if name.startswith("dbinfer-"):
|
|
74
|
-
print(
|
|
75
|
-
f"Dataset '{name}' is derived from 4DBInfer and must be generated "
|
|
76
|
-
"locally; skipping download."
|
|
77
|
-
)
|
|
78
|
-
return
|
|
79
74
|
|
|
80
75
|
if name == "rel-mimic":
|
|
81
|
-
print("Downloading Mimic dataset...")
|
|
82
76
|
from relbench.datasets.mimic import verify_mimic_access
|
|
83
77
|
|
|
84
78
|
verify_mimic_access()
|
|
@@ -126,6 +120,8 @@ def get_dataset(name: str, download=True) -> Dataset:
|
|
|
126
120
|
if name == "rel-mimic":
|
|
127
121
|
from relbench.datasets import mimic
|
|
128
122
|
|
|
123
|
+
mimic.verify_mimic_access()
|
|
124
|
+
|
|
129
125
|
cls, args, kwargs = (
|
|
130
126
|
mimic.MimicDataset,
|
|
131
127
|
(),
|
|
@@ -150,10 +146,29 @@ register_dataset("rel-arxiv", arxiv.ArxivDataset)
|
|
|
150
146
|
register_dataset("rel-salt", salt.SALTDataset)
|
|
151
147
|
register_dataset("rel-ratebeer", ratebeer.RateBeerDataset)
|
|
152
148
|
register_dataset("dbinfer-avs", dbinfer.DBInferAVSDataset)
|
|
153
|
-
register_dataset("dbinfer-mag", dbinfer.DBInferMAGDataset)
|
|
149
|
+
# register_dataset("dbinfer-mag", dbinfer.DBInferMAGDataset) # Experimental dataset: dbinfer-mag
|
|
154
150
|
register_dataset("dbinfer-diginetica", dbinfer.DBInferDigineticaDataset)
|
|
155
151
|
register_dataset("dbinfer-retailrocket", dbinfer.DBInferRetailRocketDataset)
|
|
156
152
|
register_dataset("dbinfer-seznam", dbinfer.DBInferSeznamDataset)
|
|
157
153
|
register_dataset("dbinfer-amazon", dbinfer.DBInferAmazonDataset)
|
|
158
154
|
register_dataset("dbinfer-stackexchange", dbinfer.DBInferStackExchangeDataset)
|
|
159
155
|
register_dataset("dbinfer-outbrain-small", dbinfer.DBInferOutbrainSmallDataset)
|
|
156
|
+
|
|
157
|
+
# Temporal Graph Benchmark (TGB)
|
|
158
|
+
register_dataset("tgbl-wiki", tgb.TGBDataset, tgb_name="tgbl-wiki")
|
|
159
|
+
register_dataset("tgbl-wiki-v2", tgb.TGBDataset, tgb_name="tgbl-wiki-v2")
|
|
160
|
+
register_dataset("tgbl-review", tgb.TGBDataset, tgb_name="tgbl-review")
|
|
161
|
+
register_dataset("tgbl-review-v2", tgb.TGBDataset, tgb_name="tgbl-review-v2")
|
|
162
|
+
register_dataset("tgbl-coin", tgb.TGBDataset, tgb_name="tgbl-coin")
|
|
163
|
+
register_dataset("tgbl-comment", tgb.TGBDataset, tgb_name="tgbl-comment")
|
|
164
|
+
register_dataset("tgbl-flight", tgb.TGBDataset, tgb_name="tgbl-flight")
|
|
165
|
+
|
|
166
|
+
register_dataset("thgl-software", tgb.TGBDataset, tgb_name="thgl-software")
|
|
167
|
+
register_dataset("thgl-forum", tgb.TGBDataset, tgb_name="thgl-forum")
|
|
168
|
+
register_dataset("thgl-github", tgb.TGBDataset, tgb_name="thgl-github")
|
|
169
|
+
register_dataset("thgl-myket", tgb.TGBDataset, tgb_name="thgl-myket")
|
|
170
|
+
|
|
171
|
+
register_dataset("tgbn-trade", tgb.TGBDataset, tgb_name="tgbn-trade")
|
|
172
|
+
register_dataset("tgbn-genre", tgb.TGBDataset, tgb_name="tgbn-genre")
|
|
173
|
+
register_dataset("tgbn-reddit", tgb.TGBDataset, tgb_name="tgbn-reddit")
|
|
174
|
+
register_dataset("tgbn-token", tgb.TGBDataset, tgb_name="tgbn-token")
|
|
@@ -38,7 +38,18 @@ class DBInferDatasetBase(Dataset):
|
|
|
38
38
|
self._adapter_cache_dir = adapter_cache_dir
|
|
39
39
|
|
|
40
40
|
def _load_dataset_adapter(self):
|
|
41
|
-
|
|
41
|
+
try:
|
|
42
|
+
from dbinfer_relbench_adapter.loader import load_dbinfer_data
|
|
43
|
+
except ImportError:
|
|
44
|
+
raise ImportError(
|
|
45
|
+
"dbinfer-relbench-adapter is not installed. "
|
|
46
|
+
"Please install it with:\n"
|
|
47
|
+
" pip install dbinfer-relbench-adapter\n"
|
|
48
|
+
" pip install dgl --force-reinstall -f https://data.dgl.ai/wheels/torch-2.3/cu121/repo.html\n"
|
|
49
|
+
"Note: dgl may conflict with other dependencies. We recommend building "
|
|
50
|
+
"dbinfer datasets in a separate virtual environment and using the cached "
|
|
51
|
+
"datasets in your main working environment."
|
|
52
|
+
) from None
|
|
42
53
|
|
|
43
54
|
dataset_adapter, _ = load_dbinfer_data(
|
|
44
55
|
dataset_name=self.dbinfer_name,
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"rel-trial/db.zip": "9fb5ba14f7cbca8115f3dfe0800415f98d6ddc15561e56c35ee614da6b89552a",
|
|
3
|
+
"rel-avito/db.zip": "274e692295027a753063b9201815a9d2dea94d4cda968be81be936f546d77058",
|
|
4
|
+
"rel-stack/db.zip": "5a97bf65a926529143e96f6413b2b0550ca55c01247f85156bfb999ee903e94e",
|
|
5
|
+
"rel-f1/db.zip": "ec31a4e1bc2b2f9c36c05fcd3dfe2a40a506f335dc51ce79c3ec8bb40feb1482",
|
|
6
|
+
"rel-hm/db.zip": "3fb2aa3c978cc388aa81f43f9404fed329b502104ff58f3ee435959ab95e7029",
|
|
7
|
+
"rel-event/db.zip": "2593477065e1090af0258c07769ec22f40dad01f035613ccf35258b924d8b066",
|
|
8
|
+
"rel-amazon/db.zip": "db71c7701b892a4eb7481ff04d14d25465795501dba3a5931aabee9930805efe",
|
|
9
|
+
"rel-salt/db.zip": "fca91ab7d9e37646dcf1cb0007cc4229e9b23ef3c85f3c9e578d0f3fcb167001",
|
|
10
|
+
"rel-mimic/db.zip": "b41c6fa39e9d37b8e1e66f8311eb44622c79ea1644ee2cce280fc731d8366bbb",
|
|
11
|
+
"rel-arxiv/db.zip": "b7db1bc1aa17a6d79e0cf102fe3f258920a610f58ad8f8891169676fc120bc5c",
|
|
12
|
+
"rel-ratebeer/db.zip": "49afdf23a8b464dc0e54731a3782b51e53f3acee93dae0aa6d968cfbd9caa4be",
|
|
13
|
+
"dbinfer-amazon/db.zip": "0d9291bf880b5afa232b711a462ed7522a94a0ef5c141699ee8a2687dbbf0d08",
|
|
14
|
+
"dbinfer-avs/db.zip": "84295768a283c3c9ee0dbb25eb1c47d6d3f2c1956b523e7361f086fcf6664a93",
|
|
15
|
+
"dbinfer-diginetica/db.zip": "396e2aeb88cc616672b3b0d88a02dc13829c81b855edc3e668f7f2dbad3b96f0",
|
|
16
|
+
"dbinfer-outbrain-small/db.zip": "d186a71fc534bcac4299c616110805a997fa56fd16c15110d02e1c8eb3975210",
|
|
17
|
+
"dbinfer-retailrocket/db.zip": "6dbe83488e11c0d159b4592aa4cff57f6fa22b9f4bbf4ae38d0388d536897d75",
|
|
18
|
+
"dbinfer-seznam/db.zip": "77314bf874dc495e8a4a61f2dc5f12982bbec3c5b6b7af5555e9a2bb587154d9",
|
|
19
|
+
"dbinfer-stackexchange/db.zip": "4c8b8ac38b56d57bc2ead3c12be1237b69cae76062ed3f176fc02ad327a84d19",
|
|
20
|
+
|
|
21
|
+
"tgbl-coin/db.zip": "6de3b62bcfc59bb18ff8de0614ce5cbcf21179ad56cb58920d25ade32ec43e00",
|
|
22
|
+
"tgbl-comment/db.zip": "4eb41776954efa2cb06cdb64e093b182335b8683e60236a6645cf4bcd83597be",
|
|
23
|
+
"tgbl-flight/db.zip": "e82646893a45be6c5312e5dc1a774c08d929ecb9eb309c0ad9fdec6dae3b156a",
|
|
24
|
+
"tgbl-review/db.zip": "63b405aafd8092cbda297694e649329ca806ccc3c49c8e6f53eb4a3c19075091",
|
|
25
|
+
"tgbl-review-v2/db.zip": "a5f1a7a9661a700ebb1a3b43df74037853ad3bd6ed54c74342045d2dc8448bc2",
|
|
26
|
+
"tgbl-wiki/db.zip": "ad7b55d1d7b7125c06588db0b8cbebe87c629a95a6c9a911369f89aca9dffdc9",
|
|
27
|
+
"tgbl-wiki-v2/db.zip": "5eb56f8e459405e3b554ce56585903c80038d84a99ca4333b00ce32c8c7a38f1",
|
|
28
|
+
|
|
29
|
+
"tgbn-genre/db.zip": "e46aecc28315ca9872117817ce65bc1f4d00ed261ab6d35038a84bcf0ebab7bf",
|
|
30
|
+
"tgbn-reddit/db.zip": "bc444f5cbaf7004ef7c6c8f98ae12ae72e8427ccc9710e96e46b0fc156cc952e",
|
|
31
|
+
"tgbn-token/db.zip": "44a0f90a62642b8054ef1fbee35c862a67e5d0cec92f08b8fd44c503e0986be8",
|
|
32
|
+
"tgbn-trade/db.zip": "8a983ae6281ea058dc8d84f6ce339d2dacf0ae9bb98bb82cca3fed54ec3fe370",
|
|
33
|
+
|
|
34
|
+
"thgl-forum/db.zip": "fdb20c1afc542e8026b85df850b5e8a539694c182eb4530924fad65964461256",
|
|
35
|
+
"thgl-github/db.zip": "f69c1d49779a4dbead101e7325447854c8890982d254efb2b722117819ba8304",
|
|
36
|
+
"thgl-myket/db.zip": "67a3af25553ceabe8a7eff8906c2213bd82e932cdaeb48ffa326b39d30e0f0cf",
|
|
37
|
+
"thgl-software/db.zip": "35816ef6a07be2291349f081814e18b498a2e46e006ed21be36fdb1a8a0eb90d"
|
|
38
|
+
}
|
|
@@ -26,6 +26,15 @@ def verify_mimic_access() -> None:
|
|
|
26
26
|
except Exception as e:
|
|
27
27
|
raise RuntimeError(
|
|
28
28
|
f"\nACCESS FAILED - BigQuery credential check encountered an error: {e}"
|
|
29
|
+
"\n\nTo gain access to MIMIC-IV via RelBench:"
|
|
30
|
+
"\n 1. Request access at https://physionet.org/content/mimiciv/"
|
|
31
|
+
"\n and complete the 'Request access using Google BigQuery' step."
|
|
32
|
+
"\n 2. Install the Google Cloud SDK: https://cloud.google.com/sdk/docs/install"
|
|
33
|
+
"\n 3. Authenticate: gcloud auth application-default login"
|
|
34
|
+
"\n 4. Set quota project: gcloud auth application-default set-quota-project YOUR_PROJECT_ID"
|
|
35
|
+
"\n 5. Export your project ID: export PROJECT_ID=YOUR_PROJECT_ID"
|
|
36
|
+
"\n 6. If credentials are not at the default path, set:"
|
|
37
|
+
"\n export GOOGLE_APPLICATION_CREDENTIALS=/path/to/application_default_credentials.json"
|
|
29
38
|
)
|
|
30
39
|
|
|
31
40
|
|
|
@@ -74,7 +83,9 @@ def convert_dtypes(df: pd.DataFrame) -> pd.DataFrame:
|
|
|
74
83
|
or "time" in col.lower()
|
|
75
84
|
):
|
|
76
85
|
try:
|
|
77
|
-
df[col] = pd.to_datetime(df[col], errors="coerce")
|
|
86
|
+
df[col] = pd.to_datetime(df[col], errors="coerce").astype(
|
|
87
|
+
"datetime64[ns]"
|
|
88
|
+
)
|
|
78
89
|
except Exception:
|
|
79
90
|
print("WARNING ")
|
|
80
91
|
pass
|
|
@@ -111,6 +122,10 @@ class MimicDataset(Dataset):
|
|
|
111
122
|
The dataset is anchored around ICU stays (`icustays`) and patients (`patients`) and constructs all other
|
|
112
123
|
tables with respect to these entities.
|
|
113
124
|
|
|
125
|
+
Note: MIMIC-IV applies date shifting for patient privacy. Timestamps are offset by a
|
|
126
|
+
random amount (typically decades) while preserving relative ordering. Expect dates
|
|
127
|
+
in the 2110-2200 range rather than the original 2008-2012 collection period.
|
|
128
|
+
|
|
114
129
|
If certain parameters are not provided, default values will be used.
|
|
115
130
|
|
|
116
131
|
Parameters:
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
import pandas as pd
|
|
8
|
+
|
|
9
|
+
from relbench.base import Database, Dataset
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass(frozen=True)
|
|
13
|
+
class TGBCutoffs:
|
|
14
|
+
val_timestamp_s: int
|
|
15
|
+
test_timestamp_s: int
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
_TGB_CUTOFFS: dict[str, TGBCutoffs] = {
|
|
19
|
+
"tgbl-wiki": TGBCutoffs(val_timestamp_s=1862653, test_timestamp_s=2218300),
|
|
20
|
+
"tgbl-wiki-v2": TGBCutoffs(val_timestamp_s=1862653, test_timestamp_s=2218300),
|
|
21
|
+
"tgbl-review": TGBCutoffs(val_timestamp_s=1464912000, test_timestamp_s=1488844800),
|
|
22
|
+
"tgbl-review-v2": TGBCutoffs(
|
|
23
|
+
val_timestamp_s=1464912000, test_timestamp_s=1488844800
|
|
24
|
+
),
|
|
25
|
+
"tgbl-coin": TGBCutoffs(val_timestamp_s=1662096249, test_timestamp_s=1664482319),
|
|
26
|
+
"tgbl-comment": TGBCutoffs(val_timestamp_s=1282869285, test_timestamp_s=1288838725),
|
|
27
|
+
"tgbl-flight": TGBCutoffs(val_timestamp_s=1638162000, test_timestamp_s=1653796800),
|
|
28
|
+
"thgl-software": TGBCutoffs(
|
|
29
|
+
val_timestamp_s=1706003880, test_timestamp_s=1706315669
|
|
30
|
+
),
|
|
31
|
+
"thgl-forum": TGBCutoffs(val_timestamp_s=1390426563, test_timestamp_s=1390838358),
|
|
32
|
+
"thgl-github": TGBCutoffs(val_timestamp_s=1711075987, test_timestamp_s=1711482874),
|
|
33
|
+
"thgl-myket": TGBCutoffs(val_timestamp_s=1603724860, test_timestamp_s=1606341312),
|
|
34
|
+
"tgbn-trade": TGBCutoffs(val_timestamp_s=1262304000, test_timestamp_s=1388534400),
|
|
35
|
+
"tgbn-genre": TGBCutoffs(val_timestamp_s=1216427762, test_timestamp_s=1230448684),
|
|
36
|
+
"tgbn-reddit": TGBCutoffs(val_timestamp_s=1279485233, test_timestamp_s=1286653871),
|
|
37
|
+
"tgbn-token": TGBCutoffs(val_timestamp_s=1522889022, test_timestamp_s=1525386888),
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class TGBDataset(Dataset):
|
|
42
|
+
r"""Temporal Graph Benchmark (TGB) datasets exported to RelBench format."""
|
|
43
|
+
|
|
44
|
+
url = "https://tgb.complexdatalab.com/"
|
|
45
|
+
|
|
46
|
+
def __init__(self, *, tgb_name: str, cache_dir: Optional[str] = None) -> None:
|
|
47
|
+
if tgb_name not in _TGB_CUTOFFS:
|
|
48
|
+
raise ValueError(
|
|
49
|
+
f"Unknown tgb_name='{tgb_name}'. Known keys: {sorted(_TGB_CUTOFFS.keys())}"
|
|
50
|
+
)
|
|
51
|
+
self.tgb_name = str(tgb_name)
|
|
52
|
+
|
|
53
|
+
cutoffs = _TGB_CUTOFFS[self.tgb_name]
|
|
54
|
+
self.val_timestamp = pd.to_datetime(
|
|
55
|
+
int(cutoffs.val_timestamp_s), unit="s", utc=True
|
|
56
|
+
)
|
|
57
|
+
self.test_timestamp = pd.to_datetime(
|
|
58
|
+
int(cutoffs.test_timestamp_s), unit="s", utc=True
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
super().__init__(cache_dir=cache_dir)
|
|
62
|
+
|
|
63
|
+
def make_db(self) -> Database:
|
|
64
|
+
if self.cache_dir is None:
|
|
65
|
+
raise RuntimeError("TGBDataset requires cache_dir to locate the cached db.")
|
|
66
|
+
|
|
67
|
+
db_dir = Path(self.cache_dir) / "db"
|
|
68
|
+
if db_dir.exists() and any(db_dir.glob("*.parquet")):
|
|
69
|
+
return Database.load(db_dir)
|
|
70
|
+
|
|
71
|
+
raise RuntimeError(
|
|
72
|
+
f"TGB dataset '{self.tgb_name}' not found at {db_dir}. "
|
|
73
|
+
"This dataset is distributed as a pre-built RelBench database (db.zip). "
|
|
74
|
+
"Please run `download_dataset(...)` or place `db/*.parquet` in the cache directory."
|
|
75
|
+
)
|
|
@@ -8,7 +8,7 @@ from torch_geometric.data import Data, FeatureStore, GraphStore, HeteroData
|
|
|
8
8
|
from torch_geometric.loader import NodeLoader
|
|
9
9
|
from torch_geometric.sampler import NeighborSampler, NodeSamplerInput
|
|
10
10
|
from torch_geometric.sampler.base import SubgraphType
|
|
11
|
-
from torch_geometric.typing import EdgeType, NodeType, OptTensor
|
|
11
|
+
from torch_geometric.typing import WITH_PYG_LIB, EdgeType, NodeType, OptTensor
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
def batched_arange(count: Tensor) -> Tuple[Tensor, Tensor]:
|
|
@@ -201,7 +201,10 @@ class LinkNeighborLoader(DataLoader):
|
|
|
201
201
|
data,
|
|
202
202
|
num_neighbors=num_neighbors,
|
|
203
203
|
subgraph_type=subgraph_type,
|
|
204
|
-
disjoint=True
|
|
204
|
+
# PyG only supports `disjoint=True` sampling with `pyg-lib`
|
|
205
|
+
# (as of torch_geometric==2.7.*). Fall back to `disjoint=False` to
|
|
206
|
+
# keep RelBench functional in environments without `pyg-lib`.
|
|
207
|
+
disjoint=WITH_PYG_LIB,
|
|
205
208
|
temporal_strategy=temporal_strategy,
|
|
206
209
|
time_attr=time_attr,
|
|
207
210
|
share_memory=kwargs.get("num_workers", 0) > 0,
|
|
@@ -5,7 +5,13 @@ import torch_frame
|
|
|
5
5
|
from torch import Tensor
|
|
6
6
|
from torch_frame.data.stats import StatType
|
|
7
7
|
from torch_frame.nn.models import ResNet
|
|
8
|
-
from torch_geometric.nn import
|
|
8
|
+
from torch_geometric.nn import (
|
|
9
|
+
GATv2Conv,
|
|
10
|
+
HeteroConv,
|
|
11
|
+
LayerNorm,
|
|
12
|
+
PositionalEncoding,
|
|
13
|
+
SAGEConv,
|
|
14
|
+
)
|
|
9
15
|
from torch_geometric.typing import EdgeType, NodeType
|
|
10
16
|
|
|
11
17
|
|
|
@@ -171,3 +177,64 @@ class HeteroGraphSAGE(torch.nn.Module):
|
|
|
171
177
|
x_dict = {key: x.relu() for key, x in x_dict.items()}
|
|
172
178
|
|
|
173
179
|
return x_dict
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
class HeteroGAT(torch.nn.Module):
|
|
183
|
+
def __init__(
|
|
184
|
+
self,
|
|
185
|
+
node_types: List[NodeType],
|
|
186
|
+
edge_types: List[EdgeType],
|
|
187
|
+
channels: int,
|
|
188
|
+
heads: int = 4,
|
|
189
|
+
num_layers: int = 2,
|
|
190
|
+
dropout: float = 0.0,
|
|
191
|
+
):
|
|
192
|
+
super().__init__()
|
|
193
|
+
self.channels = int(channels)
|
|
194
|
+
self.heads = int(heads)
|
|
195
|
+
self.dropout = float(dropout)
|
|
196
|
+
|
|
197
|
+
self.convs = torch.nn.ModuleList()
|
|
198
|
+
for _ in range(num_layers):
|
|
199
|
+
conv = HeteroConv(
|
|
200
|
+
{
|
|
201
|
+
edge_type: GATv2Conv(
|
|
202
|
+
(channels, channels),
|
|
203
|
+
channels,
|
|
204
|
+
heads=heads,
|
|
205
|
+
concat=False,
|
|
206
|
+
dropout=dropout,
|
|
207
|
+
add_self_loops=False,
|
|
208
|
+
)
|
|
209
|
+
for edge_type in edge_types
|
|
210
|
+
},
|
|
211
|
+
aggr="sum",
|
|
212
|
+
)
|
|
213
|
+
self.convs.append(conv)
|
|
214
|
+
|
|
215
|
+
self.norms = torch.nn.ModuleList()
|
|
216
|
+
for _ in range(num_layers):
|
|
217
|
+
norm_dict = torch.nn.ModuleDict()
|
|
218
|
+
for node_type in node_types:
|
|
219
|
+
norm_dict[node_type] = LayerNorm(channels, mode="node")
|
|
220
|
+
self.norms.append(norm_dict)
|
|
221
|
+
|
|
222
|
+
def reset_parameters(self):
|
|
223
|
+
for conv in self.convs:
|
|
224
|
+
conv.reset_parameters()
|
|
225
|
+
for norm_dict in self.norms:
|
|
226
|
+
for norm in norm_dict.values():
|
|
227
|
+
norm.reset_parameters()
|
|
228
|
+
|
|
229
|
+
def forward(
|
|
230
|
+
self,
|
|
231
|
+
x_dict: Dict[NodeType, Tensor],
|
|
232
|
+
edge_index_dict: Dict[NodeType, Tensor],
|
|
233
|
+
num_sampled_nodes_dict: Optional[Dict[NodeType, List[int]]] = None,
|
|
234
|
+
num_sampled_edges_dict: Optional[Dict[EdgeType, List[int]]] = None,
|
|
235
|
+
) -> Dict[NodeType, Tensor]:
|
|
236
|
+
for _, (conv, norm_dict) in enumerate(zip(self.convs, self.norms)):
|
|
237
|
+
x_dict = conv(x_dict, edge_index_dict)
|
|
238
|
+
x_dict = {key: norm_dict[key](x) for key, x in x_dict.items()}
|
|
239
|
+
x_dict = {key: x.relu() for key, x in x_dict.items()}
|
|
240
|
+
return x_dict
|