D4CMPP2 0.4.0__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.
- D4CMPP2/_Data/AGENTS.md +24 -0
- D4CMPP2/_Data/Aqsoldb.csv +9291 -0
- D4CMPP2/_Data/BradleyMP.csv +3042 -0
- D4CMPP2/_Data/Lipophilicity.csv +1131 -0
- D4CMPP2/_Data/README.md +8 -0
- D4CMPP2/_Data/__init__.py +26 -0
- D4CMPP2/_Data/optical.csv +20237 -0
- D4CMPP2/_Data/test.csv +190 -0
- D4CMPP2/__init__.py +16 -0
- D4CMPP2/__main__.py +5 -0
- D4CMPP2/_main.py +500 -0
- D4CMPP2/cli.py +7 -0
- D4CMPP2/exceptions.py +53 -0
- D4CMPP2/grid_search.py +259 -0
- D4CMPP2/network_refer.yaml +160 -0
- D4CMPP2/networks/AFP_model.py +72 -0
- D4CMPP2/networks/AFPwithSolv_model.py +72 -0
- D4CMPP2/networks/DMPNN_model.py +90 -0
- D4CMPP2/networks/DMPNNwithSolv_model.py +89 -0
- D4CMPP2/networks/GAT_model.py +48 -0
- D4CMPP2/networks/GATwithSolv_model.py +63 -0
- D4CMPP2/networks/GCN_model.py +113 -0
- D4CMPP2/networks/GCNwithSolv_model.py +103 -0
- D4CMPP2/networks/GC_model.py +122 -0
- D4CMPP2/networks/ISATPM_model.py +14 -0
- D4CMPP2/networks/ISATPN_model.py +199 -0
- D4CMPP2/networks/ISAT_model.py +90 -0
- D4CMPP2/networks/MPNN_model.py +56 -0
- D4CMPP2/networks/MPNNwithSolv_model.py +72 -0
- D4CMPP2/networks/__init__.py +25 -0
- D4CMPP2/networks/base.py +250 -0
- D4CMPP2/networks/registry.py +187 -0
- D4CMPP2/networks/src/AFP.py +118 -0
- D4CMPP2/networks/src/BiDropout.py +29 -0
- D4CMPP2/networks/src/DMPNN.py +35 -0
- D4CMPP2/networks/src/GAT.py +69 -0
- D4CMPP2/networks/src/GC.py +85 -0
- D4CMPP2/networks/src/GCN.py +71 -0
- D4CMPP2/networks/src/ISAT.py +153 -0
- D4CMPP2/networks/src/Linear.py +49 -0
- D4CMPP2/networks/src/MPNN.py +56 -0
- D4CMPP2/networks/src/SolventLayer.py +62 -0
- D4CMPP2/networks/src/__init__.py +0 -0
- D4CMPP2/networks/src/distGCN.py +21 -0
- D4CMPP2/networks/src/pyg_hetero.py +24 -0
- D4CMPP2/optimize.py +472 -0
- D4CMPP2/src/Analyzer/ISAAnalyzer.py +458 -0
- D4CMPP2/src/Analyzer/ISAPNAnalyzer.py +366 -0
- D4CMPP2/src/Analyzer/ISAwSAnalyzer.py +117 -0
- D4CMPP2/src/Analyzer/MolAnalyzer.py +319 -0
- D4CMPP2/src/Analyzer/__init__.py +54 -0
- D4CMPP2/src/Analyzer/core.py +480 -0
- D4CMPP2/src/Analyzer/factory.py +166 -0
- D4CMPP2/src/Analyzer/interpretation.py +232 -0
- D4CMPP2/src/Analyzer/results.py +101 -0
- D4CMPP2/src/DataManager/Dataset/GraphDataset.py +314 -0
- D4CMPP2/src/DataManager/Dataset/ISAGraphDataset.py +384 -0
- D4CMPP2/src/DataManager/Dataset/__init__.py +0 -0
- D4CMPP2/src/DataManager/GraphGenerator/ISAGraphGenerator.py +223 -0
- D4CMPP2/src/DataManager/GraphGenerator/MolGraphGenerator.py +73 -0
- D4CMPP2/src/DataManager/GraphGenerator/__init__.py +14 -0
- D4CMPP2/src/DataManager/ISADataManager.py +67 -0
- D4CMPP2/src/DataManager/MolDataManager.py +735 -0
- D4CMPP2/src/DataManager/__init__.py +14 -0
- D4CMPP2/src/DataManager/contracts.py +179 -0
- D4CMPP2/src/NetworkManager/ISANetworkManager.py +12 -0
- D4CMPP2/src/NetworkManager/NetworkManager.py +520 -0
- D4CMPP2/src/NetworkManager/__init__.py +14 -0
- D4CMPP2/src/PostProcessor.py +160 -0
- D4CMPP2/src/TrainManager/ISATrainManager.py +26 -0
- D4CMPP2/src/TrainManager/TrainManager.py +254 -0
- D4CMPP2/src/TrainManager/__init__.py +14 -0
- D4CMPP2/src/TrainManager/callbacks.py +119 -0
- D4CMPP2/src/__init__.py +0 -0
- D4CMPP2/src/utils/PATH.py +246 -0
- D4CMPP2/src/utils/__init__.py +0 -0
- D4CMPP2/src/utils/argparser.py +56 -0
- D4CMPP2/src/utils/checkpointing.py +90 -0
- D4CMPP2/src/utils/config_resolution.py +123 -0
- D4CMPP2/src/utils/config_validation.py +370 -0
- D4CMPP2/src/utils/csv_validation.py +105 -0
- D4CMPP2/src/utils/data_quality.py +181 -0
- D4CMPP2/src/utils/featureizer.py +202 -0
- D4CMPP2/src/utils/functional_group.csv +169 -0
- D4CMPP2/src/utils/graph_cache.py +213 -0
- D4CMPP2/src/utils/leaderboard.py +212 -0
- D4CMPP2/src/utils/metrics.py +31 -0
- D4CMPP2/src/utils/module_loader.py +147 -0
- D4CMPP2/src/utils/output.py +80 -0
- D4CMPP2/src/utils/reproducibility.py +70 -0
- D4CMPP2/src/utils/run_manifest.py +175 -0
- D4CMPP2/src/utils/scaler.py +40 -0
- D4CMPP2/src/utils/sculptor.py +713 -0
- D4CMPP2/src/utils/splitting.py +250 -0
- D4CMPP2/src/utils/supportfile_saver.py +94 -0
- D4CMPP2/src/utils/tools.py +156 -0
- D4CMPP2/src/utils/transfer_learning.py +111 -0
- d4cmpp2-0.4.0.dist-info/METADATA +420 -0
- d4cmpp2-0.4.0.dist-info/RECORD +103 -0
- d4cmpp2-0.4.0.dist-info/WHEEL +5 -0
- d4cmpp2-0.4.0.dist-info/entry_points.txt +2 -0
- d4cmpp2-0.4.0.dist-info/licenses/LICENSE +21 -0
- d4cmpp2-0.4.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import torch
|
|
2
|
+
import torch.nn as nn
|
|
3
|
+
import torch.nn.functional as F
|
|
4
|
+
import numpy as np
|
|
5
|
+
|
|
6
|
+
from .GCN import GCN_layer
|
|
7
|
+
from .MPNN import MPNN_layer
|
|
8
|
+
from .distGCN import distGCN_layer
|
|
9
|
+
from .pyg_hetero import relation_graph, relation_sum
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _unbiased_variance_or_zero(values):
|
|
13
|
+
"""Preserve unbiased variance except for its undefined one-value case."""
|
|
14
|
+
flattened = values.view(-1)
|
|
15
|
+
if flattened.numel() == 1:
|
|
16
|
+
return flattened.sum() * 0.0
|
|
17
|
+
return torch.var(flattened)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ISATconvolution(nn.Module):
|
|
21
|
+
def __init__(self, in_node_feats, in_edge_feats, out_feats, activation, n_layers, dropout=0.2, batch_norm=False, residual_sum = False, alpha=0.1, max_dist = 4):
|
|
22
|
+
super().__init__()
|
|
23
|
+
# Message Passing
|
|
24
|
+
self.r2r = nn.ModuleList([MPNN_layer(in_node_feats, in_edge_feats, out_feats, activation, dropout, batch_norm, residual_sum) for _ in range(n_layers)])
|
|
25
|
+
self.i2i = nn.ModuleList([GCN_layer(out_feats, out_feats, activation, dropout, batch_norm, residual_sum) for _ in range(n_layers)])
|
|
26
|
+
|
|
27
|
+
self.r2i = r2i_layer()
|
|
28
|
+
self.i2d = i2s_layer()
|
|
29
|
+
self.d2d = distGCN_layer(out_feats, max_dist, out_feats, activation, alpha)
|
|
30
|
+
|
|
31
|
+
self.d2score = nn.Sequential(nn.Linear(out_feats, out_feats//2),
|
|
32
|
+
nn.LeakyReLU(),
|
|
33
|
+
nn.Linear(out_feats//2, 1)
|
|
34
|
+
)
|
|
35
|
+
self.d2r = s2r_Layer()
|
|
36
|
+
self.batch_norm = nn.BatchNorm1d(1)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def forward(self, graph, r_node, r2r_edge, i_node, d2d_edge):
|
|
40
|
+
real_graph = relation_graph(graph, 'r_nd', 'r2r')
|
|
41
|
+
image_graph = relation_graph(graph, 'i_nd', 'i2i')
|
|
42
|
+
dot_graph = relation_graph(graph, 'd_nd', 'd2d')
|
|
43
|
+
|
|
44
|
+
for i in range(len(self.r2r)):
|
|
45
|
+
r_node = self.r2r[i](real_graph, r_node, r2r_edge)
|
|
46
|
+
i_node = self.r2i(graph, r_node, i_node)
|
|
47
|
+
i_node = self.i2i[i](image_graph, i_node)
|
|
48
|
+
d_node = self.i2d(graph, i_node)
|
|
49
|
+
d_node = self.d2d(dot_graph, d_node, d2d_edge)
|
|
50
|
+
score= self.d2r(graph, d_node)
|
|
51
|
+
score= self.d2score(score)
|
|
52
|
+
score= nn.Sigmoid()(self.batch_norm(score))
|
|
53
|
+
|
|
54
|
+
r_node=score*r_node
|
|
55
|
+
return r_node, score
|
|
56
|
+
|
|
57
|
+
class ISATconvolution_PM(nn.Module):
|
|
58
|
+
def __init__(self, in_node_feats, in_edge_feats, out_feats, activation, n_layers, dropout=0.2, batch_norm=False, residual_sum = False, alpha=0.1, max_dist = 4):
|
|
59
|
+
super().__init__()
|
|
60
|
+
# Message Passing
|
|
61
|
+
self.r2r = nn.ModuleList([MPNN_layer(in_node_feats, in_edge_feats, out_feats, activation, dropout, batch_norm, residual_sum) for _ in range(n_layers)])
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
self.i2i_P = nn.ModuleList([GCN_layer(out_feats, out_feats, activation, dropout, batch_norm, residual_sum) for _ in range(n_layers)])
|
|
65
|
+
self.d2d_P = distGCN_layer(out_feats, max_dist, out_feats, activation, alpha)
|
|
66
|
+
self.d2score_P = nn.Sequential(nn.Linear(out_feats, out_feats//2),
|
|
67
|
+
nn.LeakyReLU(),
|
|
68
|
+
nn.Linear(out_feats//2, 3),
|
|
69
|
+
nn.LeakyReLU()
|
|
70
|
+
)
|
|
71
|
+
self.d2score_pl = nn.Linear(3, 1)
|
|
72
|
+
|
|
73
|
+
self.i2i_M = nn.ModuleList([GCN_layer(out_feats, out_feats, activation, dropout, batch_norm, residual_sum) for _ in range(n_layers)])
|
|
74
|
+
self.d2d_M = distGCN_layer(out_feats, max_dist, out_feats, activation, alpha)
|
|
75
|
+
self.d2score_M = nn.Sequential(nn.Linear(out_feats, out_feats//2),
|
|
76
|
+
nn.LeakyReLU(),
|
|
77
|
+
nn.Linear(out_feats//2,3),
|
|
78
|
+
nn.LeakyReLU()
|
|
79
|
+
)
|
|
80
|
+
self.d2score_ml = nn.Linear(3, 1)
|
|
81
|
+
|
|
82
|
+
self.r2i = r2i_layer()
|
|
83
|
+
self.i2d = i2s_layer()
|
|
84
|
+
self.d2r = s2r_Layer()
|
|
85
|
+
|
|
86
|
+
self.batch_norm_P = nn.BatchNorm1d(1)
|
|
87
|
+
self.batch_norm_M = nn.BatchNorm1d(1)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def forward(self, graph, r_node, r2r_edge, i_node, d2d_edge, **kargs):
|
|
91
|
+
|
|
92
|
+
real_graph = relation_graph(graph, 'r_nd', 'r2r')
|
|
93
|
+
image_graph = relation_graph(graph, 'i_nd', 'i2i')
|
|
94
|
+
dot_graph = relation_graph(graph, 'd_nd', 'd2d')
|
|
95
|
+
|
|
96
|
+
i_node_P = i_node
|
|
97
|
+
i_node_M = i_node
|
|
98
|
+
for i in range(len(self.r2r)):
|
|
99
|
+
r_node = self.r2r[i](real_graph, r_node, r2r_edge)
|
|
100
|
+
|
|
101
|
+
i_node_P = self.r2i(graph, r_node, i_node_P)
|
|
102
|
+
i_node_P = self.i2i_P[i](image_graph, i_node_P)
|
|
103
|
+
|
|
104
|
+
i_node_M = self.r2i(graph, r_node, i_node_M)
|
|
105
|
+
i_node_M = self.i2i_M[i](image_graph, i_node_M)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
d_node_P = self.i2d(graph, i_node_P)
|
|
109
|
+
score_P = self.d2d_P(dot_graph, d_node_P, d2d_edge)
|
|
110
|
+
score_P_temp= score_P.clone()
|
|
111
|
+
score_P= self.d2score_P(score_P)
|
|
112
|
+
score_P= self.d2score_pl(score_P)
|
|
113
|
+
score_P= nn.Sigmoid()(self.batch_norm_P(score_P))
|
|
114
|
+
score_P_node= self.d2r(graph, score_P)
|
|
115
|
+
|
|
116
|
+
r_node_P=score_P_node*r_node
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
d_node_M = self.i2d(graph, i_node_M)
|
|
120
|
+
score_M = self.d2d_M(dot_graph, d_node_M, d2d_edge)
|
|
121
|
+
score_M_temp= score_M.clone()
|
|
122
|
+
score_M= self.d2score_M(score_M)
|
|
123
|
+
score_M= self.d2score_ml(score_M)
|
|
124
|
+
score_M= nn.Sigmoid()(self.batch_norm_M(score_M))
|
|
125
|
+
score_M_node= self.d2r(graph, score_M)
|
|
126
|
+
|
|
127
|
+
r_node_M=score_M_node*r_node
|
|
128
|
+
|
|
129
|
+
if kargs.get('get_feature',False):
|
|
130
|
+
return score_P_temp, score_M_temp, score_P, score_M # score by group, score by atom
|
|
131
|
+
|
|
132
|
+
self.p_score_var = _unbiased_variance_or_zero(score_P)
|
|
133
|
+
self.n_score_var = _unbiased_variance_or_zero(score_M)
|
|
134
|
+
self.p_score_mean = torch.mean(score_P.view(-1))
|
|
135
|
+
self.n_score_mean = torch.mean(score_M.view(-1))
|
|
136
|
+
self.p_score_ms = torch.mean(torch.square(0.5-score_P.view(-1)))
|
|
137
|
+
self.n_score_ms = torch.mean(torch.square(0.5-score_M.view(-1)))
|
|
138
|
+
return r_node_P, r_node_M, score_P, score_M
|
|
139
|
+
|
|
140
|
+
class r2i_layer(nn.Module):
|
|
141
|
+
def forward(self,graph, r_node, i_node):
|
|
142
|
+
return i_node+r_node
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
class i2s_layer(nn.Module):
|
|
146
|
+
def forward(self,graph, i_node):
|
|
147
|
+
return relation_sum(graph, 'i_nd', 'i2d', 'd_nd', i_node)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
class s2r_Layer(nn.Module):
|
|
151
|
+
def forward(self, graph, node):
|
|
152
|
+
return relation_sum(graph, 'd_nd', 'd2r', 'r_nd', node)
|
|
153
|
+
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import torch
|
|
2
|
+
import torch.nn as nn
|
|
3
|
+
|
|
4
|
+
class Linears(nn.Module):
|
|
5
|
+
def __init__(self, in_feats, out_feats, activation, n_layers, dropout=0.2, batch_norm=False, residual_sum = False, last= False):
|
|
6
|
+
super().__init__()
|
|
7
|
+
self.activation = activation
|
|
8
|
+
self.dropout = nn.Dropout(dropout)
|
|
9
|
+
self.batch_norm = batch_norm
|
|
10
|
+
self.linears = nn.ModuleList()
|
|
11
|
+
self.batch_norms = nn.ModuleList()
|
|
12
|
+
self.residual_sum = residual_sum
|
|
13
|
+
self.last = last
|
|
14
|
+
hidden_dim = (in_feats+out_feats)//2
|
|
15
|
+
for i in range(n_layers):
|
|
16
|
+
if i==0:
|
|
17
|
+
_in_feats = in_feats
|
|
18
|
+
else:
|
|
19
|
+
_in_feats = hidden_dim
|
|
20
|
+
if i==n_layers-1:
|
|
21
|
+
_out_feats = out_feats
|
|
22
|
+
else:
|
|
23
|
+
_out_feats = hidden_dim
|
|
24
|
+
self.linears.append(nn.Linear(_in_feats, _out_feats))
|
|
25
|
+
if self.batch_norm:
|
|
26
|
+
self.batch_norms.append(nn.BatchNorm1d(_out_feats))
|
|
27
|
+
if residual_sum:
|
|
28
|
+
if in_feats!=out_feats:
|
|
29
|
+
self.residual_layer = nn.Linear(_in_feats, _out_feats)
|
|
30
|
+
|
|
31
|
+
def forward(self, x):
|
|
32
|
+
count=0
|
|
33
|
+
for linear in self.linears:
|
|
34
|
+
count+=1
|
|
35
|
+
h = linear(x)
|
|
36
|
+
if count==len(self.linears) and self.last:
|
|
37
|
+
return h
|
|
38
|
+
else:
|
|
39
|
+
if self.batch_norm:
|
|
40
|
+
h = self.batch_norms[count-1](h)
|
|
41
|
+
h = self.activation(h)
|
|
42
|
+
h = self.dropout(h)
|
|
43
|
+
if self.residual_sum:
|
|
44
|
+
if x.shape[1]==h.shape[1]:
|
|
45
|
+
x = h + x
|
|
46
|
+
else:
|
|
47
|
+
x = h
|
|
48
|
+
return x
|
|
49
|
+
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import torch.nn as nn
|
|
2
|
+
import torch
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class MPNN_layer(nn.Module):
|
|
6
|
+
def __init__(self, in_node_feats, in_edge_feats, out_feats, activation, dropout=0.2, batch_norm=False, residual_sum = False):
|
|
7
|
+
super(MPNN_layer, self).__init__()
|
|
8
|
+
self.activation = activation
|
|
9
|
+
self.dropout = nn.Dropout(dropout)
|
|
10
|
+
self.batch_norm = batch_norm
|
|
11
|
+
self.linear = nn.Linear(in_node_feats*2+in_edge_feats, out_feats)
|
|
12
|
+
self.residual_sum = residual_sum
|
|
13
|
+
if self.batch_norm:
|
|
14
|
+
self.bn = nn.BatchNorm1d(out_feats)
|
|
15
|
+
if residual_sum:
|
|
16
|
+
if in_node_feats!=out_feats:
|
|
17
|
+
self.residual_layer = nn.Linear(in_node_feats, out_feats)
|
|
18
|
+
|
|
19
|
+
def forward(self, graph, node_feats, edge_feats):
|
|
20
|
+
src, dst = graph.edge_index
|
|
21
|
+
messages = self.linear(torch.cat([node_feats[src], node_feats[dst], edge_feats], dim=1))
|
|
22
|
+
h = messages.new_zeros((node_feats.shape[0], messages.shape[1]))
|
|
23
|
+
h.index_add_(0, dst, messages)
|
|
24
|
+
degree = messages.new_zeros((node_feats.shape[0], 1))
|
|
25
|
+
degree.index_add_(0, dst, messages.new_ones((messages.shape[0], 1)))
|
|
26
|
+
h = h / degree.clamp_min(1)
|
|
27
|
+
if self.batch_norm:
|
|
28
|
+
h = self.bn(h)
|
|
29
|
+
h = self.activation(h)
|
|
30
|
+
h = self.dropout(h)
|
|
31
|
+
if self.residual_sum:
|
|
32
|
+
if node_feats.shape[1]!=h.shape[1]:
|
|
33
|
+
node_feats = self.residual_layer(node_feats)
|
|
34
|
+
h = h + node_feats
|
|
35
|
+
return h
|
|
36
|
+
|
|
37
|
+
class MPNNs(nn.Module):
|
|
38
|
+
def __init__(self, in_node_feats, in_edge_feats, hidden_feats, out_feats, activation, n_layers, dropout=0.2, batch_norm=False, residual_sum = False):
|
|
39
|
+
super(MPNNs, self).__init__()
|
|
40
|
+
|
|
41
|
+
self.layers = nn.ModuleList()
|
|
42
|
+
for i in range(n_layers):
|
|
43
|
+
if i==0:
|
|
44
|
+
_in_feats = in_node_feats
|
|
45
|
+
else:
|
|
46
|
+
_in_feats = hidden_feats
|
|
47
|
+
if i==n_layers-1:
|
|
48
|
+
_out_feats = out_feats
|
|
49
|
+
else:
|
|
50
|
+
_out_feats = hidden_feats
|
|
51
|
+
self.layers.append(MPNN_layer(_in_feats, in_edge_feats, _out_feats, activation, dropout, batch_norm, residual_sum))
|
|
52
|
+
|
|
53
|
+
def forward(self, graph, node_feats, edge_feats):
|
|
54
|
+
for layer in self.layers:
|
|
55
|
+
node_feats = layer(graph, node_feats, edge_feats)
|
|
56
|
+
return node_feats
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
|
|
2
|
+
from D4CMPP2.networks.src.GCN import GCNs, graph_sum_pool
|
|
3
|
+
from D4CMPP2.networks.src.Linear import Linears
|
|
4
|
+
import torch.nn as nn
|
|
5
|
+
import torch
|
|
6
|
+
|
|
7
|
+
class SolventLayer(nn.Module):
|
|
8
|
+
def __init__(self, config):
|
|
9
|
+
super(SolventLayer, self).__init__()
|
|
10
|
+
|
|
11
|
+
hidden_dim = config["hidden_dim"]
|
|
12
|
+
linear_layers = config["linear_layers"]
|
|
13
|
+
solvent_hidden_dim = config.get("solvent_hidden_dim", 64)
|
|
14
|
+
solvent_conv_layers = config.get("solvent_conv_layers", 4)
|
|
15
|
+
solvent_linear_layers = config.get("solvent_linear_layers", 2)
|
|
16
|
+
solvent_dropout = config.get("solvent_dropout", 0.2)
|
|
17
|
+
self.node_embedding = nn.Linear(config['node_dim'], hidden_dim)
|
|
18
|
+
self.node_embedding_solv = nn.Linear(
|
|
19
|
+
config["node_dim"], solvent_hidden_dim
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
self.GCNs_solv = GCNs(
|
|
23
|
+
solvent_hidden_dim,
|
|
24
|
+
solvent_hidden_dim,
|
|
25
|
+
solvent_hidden_dim,
|
|
26
|
+
nn.ReLU(),
|
|
27
|
+
solvent_conv_layers,
|
|
28
|
+
solvent_dropout,
|
|
29
|
+
False,
|
|
30
|
+
True,
|
|
31
|
+
)
|
|
32
|
+
self.Linears2 = Linears(
|
|
33
|
+
solvent_hidden_dim,
|
|
34
|
+
solvent_hidden_dim,
|
|
35
|
+
nn.ReLU(),
|
|
36
|
+
solvent_linear_layers,
|
|
37
|
+
solvent_dropout,
|
|
38
|
+
False,
|
|
39
|
+
False,
|
|
40
|
+
)
|
|
41
|
+
self.Linears3 = Linears(
|
|
42
|
+
hidden_dim + solvent_hidden_dim,
|
|
43
|
+
config["target_dim"],
|
|
44
|
+
nn.ReLU(),
|
|
45
|
+
linear_layers,
|
|
46
|
+
config.get("dropout", 0.2),
|
|
47
|
+
False,
|
|
48
|
+
False,
|
|
49
|
+
True,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
def forward(self, hidden_feats,solv_graph,solv_node_feats,**kwargs):
|
|
53
|
+
h = hidden_feats
|
|
54
|
+
|
|
55
|
+
h_solv = self.node_embedding_solv(solv_node_feats)
|
|
56
|
+
h_solv = self.GCNs_solv(solv_graph, h_solv)
|
|
57
|
+
h_solv = graph_sum_pool(solv_graph, h_solv)
|
|
58
|
+
|
|
59
|
+
h_solv = self.Linears2(h_solv)
|
|
60
|
+
h = torch.cat([h,h_solv],axis=1)
|
|
61
|
+
h = self.Linears3(h)
|
|
62
|
+
return h
|
|
File without changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import torch.nn as nn
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class distGCN_layer(nn.Module):
|
|
5
|
+
def __init__(self, in_feats, edge_feats, out_feats, activation, alpha=0.1):
|
|
6
|
+
super().__init__()
|
|
7
|
+
self.activation = activation
|
|
8
|
+
self.linear = nn.Linear(in_feats, out_feats)
|
|
9
|
+
self.edge_linear = nn.Linear(edge_feats, out_feats)
|
|
10
|
+
self.alpha = alpha
|
|
11
|
+
|
|
12
|
+
def forward(self, graph, node_feats, edge_feats):
|
|
13
|
+
if len(edge_feats) == 0:
|
|
14
|
+
return node_feats
|
|
15
|
+
src, dst = graph.edge_index
|
|
16
|
+
transformed_nodes = self.linear(node_feats)
|
|
17
|
+
transformed_edges = self.edge_linear(edge_feats)
|
|
18
|
+
messages = transformed_nodes[src] * transformed_edges
|
|
19
|
+
aggregated = messages.new_zeros((node_feats.shape[0], messages.shape[1]))
|
|
20
|
+
aggregated.index_add_(0, dst, messages)
|
|
21
|
+
return node_feats + self.alpha * self.activation(aggregated)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from types import SimpleNamespace
|
|
2
|
+
|
|
3
|
+
import torch
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def relation_graph(graph, node_type, relation):
|
|
7
|
+
"""Expose one homogeneous HeteroData relation to the existing PyG layers."""
|
|
8
|
+
store = graph[node_type]
|
|
9
|
+
batch = getattr(store, 'batch', None)
|
|
10
|
+
if batch is None:
|
|
11
|
+
batch = torch.zeros(store.num_nodes, dtype=torch.long, device=store.x.device)
|
|
12
|
+
return SimpleNamespace(
|
|
13
|
+
edge_index=graph[node_type, relation, node_type].edge_index,
|
|
14
|
+
batch=batch,
|
|
15
|
+
num_graphs=int(getattr(graph, 'num_graphs', 1)),
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def relation_sum(graph, source_type, relation, destination_type, source_features):
|
|
20
|
+
"""Sum source features at each destination node for one typed relation."""
|
|
21
|
+
src, dst = graph[source_type, relation, destination_type].edge_index
|
|
22
|
+
output = source_features.new_zeros((graph[destination_type].num_nodes, source_features.shape[1]))
|
|
23
|
+
output.index_add_(0, dst, source_features[src])
|
|
24
|
+
return output
|