pyg-nightly 2.7.0.dev20250403__py3-none-any.whl → 2.7.0.dev20250405__py3-none-any.whl
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.
- {pyg_nightly-2.7.0.dev20250403.dist-info → pyg_nightly-2.7.0.dev20250405.dist-info}/METADATA +1 -1
- {pyg_nightly-2.7.0.dev20250403.dist-info → pyg_nightly-2.7.0.dev20250405.dist-info}/RECORD +10 -7
- torch_geometric/__init__.py +1 -1
- torch_geometric/nn/models/__init__.py +5 -0
- torch_geometric/nn/models/attract_repel.py +148 -0
- torch_geometric/nn/models/gpse.py +1079 -0
- torch_geometric/transforms/__init__.py +2 -0
- torch_geometric/transforms/add_gpse.py +39 -0
- {pyg_nightly-2.7.0.dev20250403.dist-info → pyg_nightly-2.7.0.dev20250405.dist-info}/WHEEL +0 -0
- {pyg_nightly-2.7.0.dev20250403.dist-info → pyg_nightly-2.7.0.dev20250405.dist-info}/licenses/LICENSE +0 -0
{pyg_nightly-2.7.0.dev20250403.dist-info → pyg_nightly-2.7.0.dev20250405.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: pyg-nightly
|
3
|
-
Version: 2.7.0.
|
3
|
+
Version: 2.7.0.dev20250405
|
4
4
|
Summary: Graph Neural Network Library for PyTorch
|
5
5
|
Keywords: deep-learning,pytorch,geometric-deep-learning,graph-neural-networks,graph-convolutional-networks
|
6
6
|
Author-email: Matthias Fey <matthias@pyg.org>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
torch_geometric/__init__.py,sha256=
|
1
|
+
torch_geometric/__init__.py,sha256=Gv9oWwU7Y-5CKcoO3SA059-jYYjsTMcsubgypKMaUcQ,1978
|
2
2
|
torch_geometric/_compile.py,sha256=f-WQeH4VLi5Hn9lrgztFUCSrN_FImjhQa6BxFzcYC38,1338
|
3
3
|
torch_geometric/_onnx.py,sha256=V9ffrIKSqhDw6xUZ12lkuSfNs48cQp2EeJ6Z19GfnVw,349
|
4
4
|
torch_geometric/backend.py,sha256=lVaf7aLoVaB3M-UcByUJ1G4T4FOK6LXAg0CF4W3E8jo,1575
|
@@ -426,8 +426,9 @@ torch_geometric/nn/kge/distmult.py,sha256=dGQ0bVzjreZgFN1lXE23_IIidsiOq7ehPrMb-N
|
|
426
426
|
torch_geometric/nn/kge/loader.py,sha256=5Uc1j3OUMQnBYSHDqL7pLCty1siFLzoPkztigYO2zP8,771
|
427
427
|
torch_geometric/nn/kge/rotate.py,sha256=XLuO1AbyTt5cJxr97ZzoyAyIEsHKesgW5TvDmnGJAao,3208
|
428
428
|
torch_geometric/nn/kge/transe.py,sha256=jlejq5BLMm-sb1wWcLDp7pZqCdelWBgjDIC8ctbjSdU,3088
|
429
|
-
torch_geometric/nn/models/__init__.py,sha256=
|
429
|
+
torch_geometric/nn/models/__init__.py,sha256=4mZ5dyiZ9aa1NaBth1qYV-hZdnG_Np1XWvRLB4Qv6RM,2338
|
430
430
|
torch_geometric/nn/models/attentive_fp.py,sha256=tkgvw28wg9-JqHIfBllfCwTHrZIUiv85yZJcDqjz3z0,6634
|
431
|
+
torch_geometric/nn/models/attract_repel.py,sha256=h9OyogT0NY0xiT0DkpJHMxH6ZUmo8R-CmwZdKEwq8Ek,5277
|
431
432
|
torch_geometric/nn/models/autoencoder.py,sha256=nGje-zty78Y3hxOJ9o0_6QziJjOvBlknk6z0_fDQwQU,10770
|
432
433
|
torch_geometric/nn/models/basic_gnn.py,sha256=PGa0RUMyvrNy_5yRI2jX_zwPsmZXwOQWfsWvxOiHsSk,31225
|
433
434
|
torch_geometric/nn/models/captum.py,sha256=kV3lsIM7QdP9MDXmBOTq0Sf1jTEcK-_9LnwLYm2aVzw,3971
|
@@ -440,6 +441,7 @@ torch_geometric/nn/models/g_retriever.py,sha256=CdSOasnPiMvq5AjduNTpz-LIZiNp3X0x
|
|
440
441
|
torch_geometric/nn/models/git_mol.py,sha256=Wc6Hx6RDDR7sDWRWHfA5eK9e9gFsrTZ9OLmpMfoj3pE,12676
|
441
442
|
torch_geometric/nn/models/glem.py,sha256=sT0XM4klVlci9wduvUoXupATUw9p25uXtaJBrmv3yvs,16431
|
442
443
|
torch_geometric/nn/models/gnnff.py,sha256=15dkiLgy0LmH1hnUrpeoHioIp4BPTfjpVATpnGRt9E0,7860
|
444
|
+
torch_geometric/nn/models/gpse.py,sha256=my-KIw_Ov8o0pXSCyh43NZRBAW95TFfmBgxzSimx8-A,42680
|
443
445
|
torch_geometric/nn/models/graph_mixer.py,sha256=mthMeCOikR8gseEsu4oJ3Cd9C35zHSv1p32ROwnG-6s,9246
|
444
446
|
torch_geometric/nn/models/graph_unet.py,sha256=N8TSmJo8AlbZjjcame0xW_jZvMOirL5ahw6qv5Yjpbs,5586
|
445
447
|
torch_geometric/nn/models/jumping_knowledge.py,sha256=9JR2EoViXKjcDSLb8tjJm-UHfv1mQCJvZAAEsYa0Ocw,5496
|
@@ -520,7 +522,8 @@ torch_geometric/testing/decorators.py,sha256=j45wlxMB1-Pn3wPKBgDziqg6KkWJUb_fcwf
|
|
520
522
|
torch_geometric/testing/distributed.py,sha256=ZZCCXqiQC4-m1ExSjDZhS_a1qPXnHEwhJGTmACxNnVI,2227
|
521
523
|
torch_geometric/testing/feature_store.py,sha256=J6JBIt2XK-t8yG8B4JzXp-aJcVl5jaCS1m2H7d6OUxs,2158
|
522
524
|
torch_geometric/testing/graph_store.py,sha256=00B7QToCIspYmgN7svQKp1iU-qAzEtrt3VQRFxkHfuk,1044
|
523
|
-
torch_geometric/transforms/__init__.py,sha256=
|
525
|
+
torch_geometric/transforms/__init__.py,sha256=P0R2CFg9pXxjTX4NnYfNPrifRPAw5lVXEOxO80q-1Ek,4296
|
526
|
+
torch_geometric/transforms/add_gpse.py,sha256=4o0UrSmTu3CKsL3UAREiul8O4lC02PUx_ajxP4sPsxU,1570
|
524
527
|
torch_geometric/transforms/add_metapaths.py,sha256=GabaPRvUnpFrZJsxLMUBY2Egzx94GTgsMxegL_qTtbk,14239
|
525
528
|
torch_geometric/transforms/add_positional_encoding.py,sha256=tuilyubAn3yeyz8mvFc5zxXTlNzh8okKzG9AE2lPG1Q,6049
|
526
529
|
torch_geometric/transforms/add_remaining_self_loops.py,sha256=ItU5FAcE-mkbp_wqTLkRhv0RShR5JVr8vr9d5xv3_Ak,2085
|
@@ -633,7 +636,7 @@ torch_geometric/utils/undirected.py,sha256=H_nfpI0_WluOG6VfjPyldvcjL4w5USAKWu2x5
|
|
633
636
|
torch_geometric/visualization/__init__.py,sha256=PyR_4K5SafsJrBr6qWrkjKr6GBL1b7FtZybyXCDEVwY,154
|
634
637
|
torch_geometric/visualization/graph.py,sha256=ZuLPL92yGRi7lxlqsUPwL_EVVXF7P2kMcveTtW79vpA,4784
|
635
638
|
torch_geometric/visualization/influence.py,sha256=CWMvuNA_Nf1sfbJmQgn58yS4OFpeKXeZPe7kEuvkUBw,477
|
636
|
-
pyg_nightly-2.7.0.
|
637
|
-
pyg_nightly-2.7.0.
|
638
|
-
pyg_nightly-2.7.0.
|
639
|
-
pyg_nightly-2.7.0.
|
639
|
+
pyg_nightly-2.7.0.dev20250405.dist-info/licenses/LICENSE,sha256=ic-27cMJc1kWoMEYncz3Ya3Ur2Bi3bNLWib2DT763-o,1067
|
640
|
+
pyg_nightly-2.7.0.dev20250405.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
641
|
+
pyg_nightly-2.7.0.dev20250405.dist-info/METADATA,sha256=9NrBoIq1lq6tX1hOXmse3Dvp7PZNQjcsoyGzucHSgp8,63021
|
642
|
+
pyg_nightly-2.7.0.dev20250405.dist-info/RECORD,,
|
torch_geometric/__init__.py
CHANGED
@@ -31,7 +31,7 @@ from .lazy_loader import LazyLoader
|
|
31
31
|
contrib = LazyLoader('contrib', globals(), 'torch_geometric.contrib')
|
32
32
|
graphgym = LazyLoader('graphgym', globals(), 'torch_geometric.graphgym')
|
33
33
|
|
34
|
-
__version__ = '2.7.0.
|
34
|
+
__version__ = '2.7.0.dev20250405'
|
35
35
|
|
36
36
|
__all__ = [
|
37
37
|
'Index',
|
@@ -12,6 +12,7 @@ from .re_net import RENet
|
|
12
12
|
from .graph_unet import GraphUNet
|
13
13
|
from .schnet import SchNet
|
14
14
|
from .dimenet import DimeNet, DimeNetPlusPlus
|
15
|
+
from .gpse import GPSE, GPSENodeEncoder
|
15
16
|
from .captum import to_captum_model
|
16
17
|
from .metapath2vec import MetaPath2Vec
|
17
18
|
from .deepgcn import DeepGCNLayer
|
@@ -36,6 +37,7 @@ from .sgformer import SGFormer
|
|
36
37
|
# Deprecated:
|
37
38
|
from torch_geometric.explain.algorithm.captum import (to_captum_input,
|
38
39
|
captum_output_to_dicts)
|
40
|
+
from .attract_repel import ARLinkPredictor
|
39
41
|
|
40
42
|
__all__ = classes = [
|
41
43
|
'MLP',
|
@@ -61,6 +63,8 @@ __all__ = classes = [
|
|
61
63
|
'SchNet',
|
62
64
|
'DimeNet',
|
63
65
|
'DimeNetPlusPlus',
|
66
|
+
'GPSE',
|
67
|
+
'GPSENodeEncoder',
|
64
68
|
'to_captum_model',
|
65
69
|
'to_captum_input',
|
66
70
|
'captum_output_to_dicts',
|
@@ -84,4 +88,5 @@ __all__ = classes = [
|
|
84
88
|
'MoleculeGPT',
|
85
89
|
'GLEM',
|
86
90
|
'SGFormer',
|
91
|
+
'ARLinkPredictor',
|
87
92
|
]
|
@@ -0,0 +1,148 @@
|
|
1
|
+
import torch
|
2
|
+
import torch.nn.functional as F
|
3
|
+
|
4
|
+
|
5
|
+
class ARLinkPredictor(torch.nn.Module):
|
6
|
+
r"""Link predictor using Attract-Repel embeddings from the paper
|
7
|
+
`"Pseudo-Euclidean Attract-Repel Embeddings for Undirected Graphs"
|
8
|
+
<https://arxiv.org/abs/2106.09671>`_.
|
9
|
+
|
10
|
+
This model splits node embeddings into: attract and
|
11
|
+
repel.
|
12
|
+
The edge prediction score is computed as the dot product of attract
|
13
|
+
components minus the dot product of repel components.
|
14
|
+
|
15
|
+
Args:
|
16
|
+
in_channels (int): Size of each input sample.
|
17
|
+
hidden_channels (int): Size of hidden embeddings.
|
18
|
+
out_channels (int, optional): Size of output embeddings.
|
19
|
+
If set to :obj:`None`, will default to :obj:`hidden_channels`.
|
20
|
+
(default: :obj:`None`)
|
21
|
+
num_layers (int): Number of message passing layers.
|
22
|
+
(default: :obj:`2`)
|
23
|
+
dropout (float): Dropout probability. (default: :obj:`0.0`)
|
24
|
+
attract_ratio (float): Ratio to use for attract component.
|
25
|
+
Must be between 0 and 1. (default: :obj:`0.5`)
|
26
|
+
"""
|
27
|
+
def __init__(self, in_channels, hidden_channels, out_channels=None,
|
28
|
+
num_layers=2, dropout=0.0, attract_ratio=0.5):
|
29
|
+
super().__init__()
|
30
|
+
|
31
|
+
if out_channels is None:
|
32
|
+
out_channels = hidden_channels
|
33
|
+
|
34
|
+
self.in_channels = in_channels
|
35
|
+
self.hidden_channels = hidden_channels
|
36
|
+
self.out_channels = out_channels
|
37
|
+
self.num_layers = num_layers
|
38
|
+
self.dropout = dropout
|
39
|
+
|
40
|
+
if not 0 <= attract_ratio <= 1:
|
41
|
+
raise ValueError(
|
42
|
+
f"attract_ratio must be between 0 and 1, got {attract_ratio}")
|
43
|
+
|
44
|
+
self.attract_ratio = attract_ratio
|
45
|
+
self.attract_dim = int(out_channels * attract_ratio)
|
46
|
+
self.repel_dim = out_channels - self.attract_dim
|
47
|
+
|
48
|
+
# Create model layers
|
49
|
+
self.lins = torch.nn.ModuleList()
|
50
|
+
self.lins.append(torch.nn.Linear(in_channels, hidden_channels))
|
51
|
+
|
52
|
+
for _ in range(num_layers - 2):
|
53
|
+
self.lins.append(torch.nn.Linear(hidden_channels, hidden_channels))
|
54
|
+
|
55
|
+
# Final layer splits into attract and repel components
|
56
|
+
self.lin_attract = torch.nn.Linear(hidden_channels, self.attract_dim)
|
57
|
+
self.lin_repel = torch.nn.Linear(hidden_channels, self.repel_dim)
|
58
|
+
|
59
|
+
self.reset_parameters()
|
60
|
+
|
61
|
+
def reset_parameters(self):
|
62
|
+
"""Reset all learnable parameters."""
|
63
|
+
for lin in self.lins:
|
64
|
+
lin.reset_parameters()
|
65
|
+
self.lin_attract.reset_parameters()
|
66
|
+
self.lin_repel.reset_parameters()
|
67
|
+
|
68
|
+
def encode(self, x, *args, **kwargs):
|
69
|
+
"""Encode node features into attract-repel embeddings.
|
70
|
+
|
71
|
+
Args:
|
72
|
+
x (torch.Tensor): Node feature matrix of shape
|
73
|
+
:obj:`[num_nodes, in_channels]`.
|
74
|
+
*args: Variable length argument list
|
75
|
+
**kwargs: Arbitrary keyword arguments
|
76
|
+
|
77
|
+
"""
|
78
|
+
for lin in self.lins:
|
79
|
+
x = lin(x)
|
80
|
+
x = F.relu(x)
|
81
|
+
x = F.dropout(x, p=self.dropout, training=self.training)
|
82
|
+
|
83
|
+
# Split into attract and repel components
|
84
|
+
attract_x = self.lin_attract(x)
|
85
|
+
repel_x = self.lin_repel(x)
|
86
|
+
|
87
|
+
return attract_x, repel_x
|
88
|
+
|
89
|
+
def decode(self, attract_z, repel_z, edge_index):
|
90
|
+
"""Decode edge scores from attract-repel embeddings.
|
91
|
+
|
92
|
+
Args:
|
93
|
+
attract_z (torch.Tensor): Attract embeddings of shape
|
94
|
+
:obj:`[num_nodes, attract_dim]`.
|
95
|
+
repel_z (torch.Tensor): Repel embeddings of shape
|
96
|
+
:obj:`[num_nodes, repel_dim]`.
|
97
|
+
edge_index (torch.Tensor): Edge indices of shape
|
98
|
+
:obj:`[2, num_edges]`.
|
99
|
+
|
100
|
+
Returns:
|
101
|
+
torch.Tensor: Edge prediction scores.
|
102
|
+
"""
|
103
|
+
# Get node embeddings for edges
|
104
|
+
row, col = edge_index
|
105
|
+
attract_z_row = attract_z[row]
|
106
|
+
attract_z_col = attract_z[col]
|
107
|
+
repel_z_row = repel_z[row]
|
108
|
+
repel_z_col = repel_z[col]
|
109
|
+
|
110
|
+
# Compute attract-repel scores
|
111
|
+
attract_score = torch.sum(attract_z_row * attract_z_col, dim=1)
|
112
|
+
repel_score = torch.sum(repel_z_row * repel_z_col, dim=1)
|
113
|
+
|
114
|
+
return attract_score - repel_score
|
115
|
+
|
116
|
+
def forward(self, x, edge_index):
|
117
|
+
"""Forward pass for link prediction.
|
118
|
+
|
119
|
+
Args:
|
120
|
+
x (torch.Tensor): Node feature matrix.
|
121
|
+
edge_index (torch.Tensor): Edge indices to predict.
|
122
|
+
|
123
|
+
Returns:
|
124
|
+
torch.Tensor: Predicted edge scores.
|
125
|
+
"""
|
126
|
+
# Encode nodes into attract-repel embeddings
|
127
|
+
attract_z, repel_z = self.encode(x)
|
128
|
+
|
129
|
+
# Decode target edges
|
130
|
+
return torch.sigmoid(self.decode(attract_z, repel_z, edge_index))
|
131
|
+
|
132
|
+
def calculate_r_fraction(self, attract_z, repel_z):
|
133
|
+
"""Calculate the R-fraction (proportion of energy in repel space).
|
134
|
+
|
135
|
+
Args:
|
136
|
+
attract_z (torch.Tensor): Attract embeddings.
|
137
|
+
repel_z (torch.Tensor): Repel embeddings.
|
138
|
+
|
139
|
+
Returns:
|
140
|
+
float: R-fraction value.
|
141
|
+
"""
|
142
|
+
attract_norm_squared = torch.sum(attract_z**2)
|
143
|
+
repel_norm_squared = torch.sum(repel_z**2)
|
144
|
+
|
145
|
+
r_fraction = repel_norm_squared / (attract_norm_squared +
|
146
|
+
repel_norm_squared + 1e-10)
|
147
|
+
|
148
|
+
return r_fraction.item()
|