pyg-nightly 2.7.0.dev20250402__py3-none-any.whl → 2.7.0.dev20250404__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.dev20250402.dist-info → pyg_nightly-2.7.0.dev20250404.dist-info}/METADATA +1 -1
- {pyg_nightly-2.7.0.dev20250402.dist-info → pyg_nightly-2.7.0.dev20250404.dist-info}/RECORD +7 -6
- torch_geometric/__init__.py +1 -1
- torch_geometric/nn/models/__init__.py +2 -0
- torch_geometric/nn/models/attract_repel.py +148 -0
- {pyg_nightly-2.7.0.dev20250402.dist-info → pyg_nightly-2.7.0.dev20250404.dist-info}/WHEEL +0 -0
- {pyg_nightly-2.7.0.dev20250402.dist-info → pyg_nightly-2.7.0.dev20250404.dist-info}/licenses/LICENSE +0 -0
{pyg_nightly-2.7.0.dev20250402.dist-info → pyg_nightly-2.7.0.dev20250404.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.dev20250404
|
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=FXQ6WZdtxVAyouslhtsPt0xXJ33VOV4_aeSKmDUWYrU,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=dwKH_fLrAMV9nda0nQHLyCzIOPezHCZa01pmTCdaJxU,2263
|
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
|
@@ -633,7 +634,7 @@ torch_geometric/utils/undirected.py,sha256=H_nfpI0_WluOG6VfjPyldvcjL4w5USAKWu2x5
|
|
633
634
|
torch_geometric/visualization/__init__.py,sha256=PyR_4K5SafsJrBr6qWrkjKr6GBL1b7FtZybyXCDEVwY,154
|
634
635
|
torch_geometric/visualization/graph.py,sha256=ZuLPL92yGRi7lxlqsUPwL_EVVXF7P2kMcveTtW79vpA,4784
|
635
636
|
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.
|
637
|
+
pyg_nightly-2.7.0.dev20250404.dist-info/licenses/LICENSE,sha256=ic-27cMJc1kWoMEYncz3Ya3Ur2Bi3bNLWib2DT763-o,1067
|
638
|
+
pyg_nightly-2.7.0.dev20250404.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
639
|
+
pyg_nightly-2.7.0.dev20250404.dist-info/METADATA,sha256=AO-euV7W-eeQ5YKe9jRqjlvrpn4qZGiLmiYV_VNxKyI,63021
|
640
|
+
pyg_nightly-2.7.0.dev20250404.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.dev20250404'
|
35
35
|
|
36
36
|
__all__ = [
|
37
37
|
'Index',
|
@@ -36,6 +36,7 @@ from .sgformer import SGFormer
|
|
36
36
|
# Deprecated:
|
37
37
|
from torch_geometric.explain.algorithm.captum import (to_captum_input,
|
38
38
|
captum_output_to_dicts)
|
39
|
+
from .attract_repel import ARLinkPredictor
|
39
40
|
|
40
41
|
__all__ = classes = [
|
41
42
|
'MLP',
|
@@ -84,4 +85,5 @@ __all__ = classes = [
|
|
84
85
|
'MoleculeGPT',
|
85
86
|
'GLEM',
|
86
87
|
'SGFormer',
|
88
|
+
'ARLinkPredictor',
|
87
89
|
]
|
@@ -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()
|
File without changes
|
{pyg_nightly-2.7.0.dev20250402.dist-info → pyg_nightly-2.7.0.dev20250404.dist-info}/licenses/LICENSE
RENAMED
File without changes
|