torch-molecule 0.1.0.dev2__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.
Files changed (148) hide show
  1. torch_molecule/__init__.py +70 -0
  2. torch_molecule/base/__init__.py +8 -0
  3. torch_molecule/base/base.py +396 -0
  4. torch_molecule/base/encoder.py +44 -0
  5. torch_molecule/base/generator.py +24 -0
  6. torch_molecule/base/old_encoder.py +322 -0
  7. torch_molecule/base/old_predictor.py +904 -0
  8. torch_molecule/base/old_predictor2.py +436 -0
  9. torch_molecule/base/predictor.py +112 -0
  10. torch_molecule/encoder/attrmask/__init__.py +3 -0
  11. torch_molecule/encoder/attrmask/model.py +113 -0
  12. torch_molecule/encoder/attrmask/modeling_attrmask.py +304 -0
  13. torch_molecule/encoder/constant.py +13 -0
  14. torch_molecule/encoder/contextpred/__init__.py +3 -0
  15. torch_molecule/encoder/contextpred/model.py +207 -0
  16. torch_molecule/encoder/contextpred/modeling_contextpred.py +299 -0
  17. torch_molecule/encoder/contextpred/utils.py +206 -0
  18. torch_molecule/encoder/edgepred/__init__.py +3 -0
  19. torch_molecule/encoder/edgepred/model.py +104 -0
  20. torch_molecule/encoder/edgepred/modeling_edgepred.py +285 -0
  21. torch_molecule/encoder/graphmae/__init__.py +3 -0
  22. torch_molecule/encoder/graphmae/dataloader.py +206 -0
  23. torch_molecule/encoder/graphmae/model.py +137 -0
  24. torch_molecule/encoder/graphmae/modeling_graphmae.py +323 -0
  25. torch_molecule/encoder/infograph/__init__.py +3 -0
  26. torch_molecule/encoder/infograph/loss_function.py +128 -0
  27. torch_molecule/encoder/infograph/model.py +92 -0
  28. torch_molecule/encoder/infograph/modeling_infograph.py +301 -0
  29. torch_molecule/encoder/infograph/module.py +31 -0
  30. torch_molecule/encoder/moama/__init__.py +3 -0
  31. torch_molecule/encoder/moama/model.py +131 -0
  32. torch_molecule/encoder/moama/modeling_moama.py +307 -0
  33. torch_molecule/encoder/moama/utils.py +143 -0
  34. torch_molecule/encoder/pretrained/__init__.py +3 -0
  35. torch_molecule/encoder/pretrained/modeling_pretrained.py +274 -0
  36. torch_molecule/encoder/supervised/__init__.py +3 -0
  37. torch_molecule/encoder/supervised/model.py +97 -0
  38. torch_molecule/encoder/supervised/modeling_supervised.py +354 -0
  39. torch_molecule/generator/digress/__init__.py +3 -0
  40. torch_molecule/generator/digress/diffusion.py +194 -0
  41. torch_molecule/generator/digress/modeling_digress.py +503 -0
  42. torch_molecule/generator/digress/transformer.py +360 -0
  43. torch_molecule/generator/digress/utils.py +196 -0
  44. torch_molecule/generator/gdss/__init__.py +3 -0
  45. torch_molecule/generator/gdss/layers.py +257 -0
  46. torch_molecule/generator/gdss/model.py +204 -0
  47. torch_molecule/generator/gdss/modeling_gdss.py +474 -0
  48. torch_molecule/generator/gdss/sde.py +334 -0
  49. torch_molecule/generator/gdss/solver.py +227 -0
  50. torch_molecule/generator/gdss/toremove/ScoreNetworkA.py +167 -0
  51. torch_molecule/generator/gdss/toremove/ScoreNetworkX.py +85 -0
  52. torch_molecule/generator/gdss/utils.py +240 -0
  53. torch_molecule/generator/graph_dit/__init__.py +3 -0
  54. torch_molecule/generator/graph_dit/diffusion.py +188 -0
  55. torch_molecule/generator/graph_dit/modeling_graph_dit.py +581 -0
  56. torch_molecule/generator/graph_dit/transformer.py +207 -0
  57. torch_molecule/generator/graph_dit/utils.py +220 -0
  58. torch_molecule/generator/graph_ga/__init__.py +3 -0
  59. torch_molecule/generator/graph_ga/crossover.py +182 -0
  60. torch_molecule/generator/graph_ga/modeling_graph_ga.py +310 -0
  61. torch_molecule/generator/graph_ga/mutate.py +136 -0
  62. torch_molecule/generator/graph_ga/oracle.py +95 -0
  63. torch_molecule/generator/jtvae/__init__.py +3 -0
  64. torch_molecule/generator/jtvae/jtnn/chemutils.py +450 -0
  65. torch_molecule/generator/jtvae/jtnn/datautils.py +127 -0
  66. torch_molecule/generator/jtvae/jtnn/jtmpn.py +140 -0
  67. torch_molecule/generator/jtvae/jtnn/jtnn_dec.py +350 -0
  68. torch_molecule/generator/jtvae/jtnn/jtnn_enc.py +131 -0
  69. torch_molecule/generator/jtvae/jtnn/mol_tree.py +111 -0
  70. torch_molecule/generator/jtvae/jtnn/mpn.py +129 -0
  71. torch_molecule/generator/jtvae/jtnn/nnutils.py +66 -0
  72. torch_molecule/generator/jtvae/jtnn/vocab.py +31 -0
  73. torch_molecule/generator/jtvae/jtnn_vae.py +246 -0
  74. torch_molecule/generator/jtvae/modeling_jtvae.py +247 -0
  75. torch_molecule/generator/lstm/__init__.py +3 -0
  76. torch_molecule/generator/lstm/action_sampler.py +91 -0
  77. torch_molecule/generator/lstm/lstm.py +59 -0
  78. torch_molecule/generator/lstm/modeling_lstm.py +263 -0
  79. torch_molecule/generator/lstm/smiles_char_dict.py +123 -0
  80. torch_molecule/generator/lstm/utils.py +62 -0
  81. torch_molecule/generator/molgpt/__init__.py +3 -0
  82. torch_molecule/generator/molgpt/dataset.py +87 -0
  83. torch_molecule/generator/molgpt/gpt.py +251 -0
  84. torch_molecule/generator/molgpt/modeling_molgpt.py +427 -0
  85. torch_molecule/generator/pretrained/modeling_pretrained.py +1 -0
  86. torch_molecule/nn/__init__.py +16 -0
  87. torch_molecule/nn/attention.py +63 -0
  88. torch_molecule/nn/embedder.py +183 -0
  89. torch_molecule/nn/gnn.py +631 -0
  90. torch_molecule/nn/mlp.py +34 -0
  91. torch_molecule/predictor/bfgnn/__init__.py +3 -0
  92. torch_molecule/predictor/bfgnn/model.py +116 -0
  93. torch_molecule/predictor/bfgnn/modeling_bfgnn.py +81 -0
  94. torch_molecule/predictor/dir/__init__.py +3 -0
  95. torch_molecule/predictor/dir/model.py +235 -0
  96. torch_molecule/predictor/dir/modeling_dir.py +161 -0
  97. torch_molecule/predictor/dir/utils.py +40 -0
  98. torch_molecule/predictor/gnn/__init__.py +3 -0
  99. torch_molecule/predictor/gnn/model.py +114 -0
  100. torch_molecule/predictor/gnn/modeling_gnn.py +706 -0
  101. torch_molecule/predictor/gnn/old_modeling_gnn.py +707 -0
  102. torch_molecule/predictor/grea/__init__.py +3 -0
  103. torch_molecule/predictor/grea/model.py +190 -0
  104. torch_molecule/predictor/grea/modeling_grea.py +107 -0
  105. torch_molecule/predictor/grea/old1_features.py +229 -0
  106. torch_molecule/predictor/grea/old1_modeling_grea.py +493 -0
  107. torch_molecule/predictor/grea/utils.py +97 -0
  108. torch_molecule/predictor/grin/__init__.py +3 -0
  109. torch_molecule/predictor/grin/model.py +116 -0
  110. torch_molecule/predictor/grin/modeling_grin.py +91 -0
  111. torch_molecule/predictor/irm/__init__.py +3 -0
  112. torch_molecule/predictor/irm/model.py +127 -0
  113. torch_molecule/predictor/irm/modeling_irm.py +179 -0
  114. torch_molecule/predictor/lstm/__init__.py +3 -0
  115. torch_molecule/predictor/lstm/model.py +145 -0
  116. torch_molecule/predictor/lstm/modeling_lstm.py +627 -0
  117. torch_molecule/predictor/lstm/token_from_smiles.py +85 -0
  118. torch_molecule/predictor/old_modeling_graph.py +650 -0
  119. torch_molecule/predictor/rpgnn/__init__.py +3 -0
  120. torch_molecule/predictor/rpgnn/model.py +185 -0
  121. torch_molecule/predictor/rpgnn/modeling_rpgnn.py +76 -0
  122. torch_molecule/predictor/sgir/__init__.py +3 -0
  123. torch_molecule/predictor/sgir/modeling_sgir.py +260 -0
  124. torch_molecule/predictor/sgir/strategy.py +266 -0
  125. torch_molecule/predictor/smiles_transformer/__init__.py +3 -0
  126. torch_molecule/predictor/smiles_transformer/model.py +424 -0
  127. torch_molecule/predictor/smiles_transformer/modeling_transformer.py +252 -0
  128. torch_molecule/predictor/ssr/__init__.py +3 -0
  129. torch_molecule/predictor/ssr/model.py +283 -0
  130. torch_molecule/predictor/ssr/modeling_ssr.py +267 -0
  131. torch_molecule/predictor/ssr/utils.py +185 -0
  132. torch_molecule/utils/__init__.py +31 -0
  133. torch_molecule/utils/checker.py +158 -0
  134. torch_molecule/utils/checkpoint.py +294 -0
  135. torch_molecule/utils/format.py +140 -0
  136. torch_molecule/utils/generic/metrics.py +530 -0
  137. torch_molecule/utils/generic/pseudo_tasks.py +11 -0
  138. torch_molecule/utils/generic/weights.py +30 -0
  139. torch_molecule/utils/graph/features.py +178 -0
  140. torch_molecule/utils/graph/graph_from_smiles.py +134 -0
  141. torch_molecule/utils/graph/graph_to_smiles.py +312 -0
  142. torch_molecule/utils/hf.py +232 -0
  143. torch_molecule/utils/search.py +64 -0
  144. torch_molecule-0.1.0.dev2.dist-info/METADATA +243 -0
  145. torch_molecule-0.1.0.dev2.dist-info/RECORD +148 -0
  146. torch_molecule-0.1.0.dev2.dist-info/WHEEL +5 -0
  147. torch_molecule-0.1.0.dev2.dist-info/licenses/LICENSE +21 -0
  148. torch_molecule-0.1.0.dev2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,334 @@
1
+ import abc
2
+ import torch
3
+ import numpy as np
4
+
5
+ def get_score_fn(sde, model, train=True, continuous=True):
6
+ if not train:
7
+ model.eval()
8
+ model_fn = model
9
+ if isinstance(sde, VPSDE) or isinstance(sde, subVPSDE):
10
+ def score_fn(x, adj, flags, t):
11
+ # Scale neural network output by standard deviation and flip sign
12
+ if continuous:
13
+ score = model_fn(x, adj, flags)
14
+ std = sde.marginal_prob(torch.zeros_like(adj), t)[1]
15
+ else:
16
+ raise NotImplementedError(f"Discrete not supported")
17
+ score = -score / std[:, None, None]
18
+ return score
19
+
20
+ elif isinstance(sde, VESDE):
21
+ def score_fn(x, adj, flags, t):
22
+ if continuous:
23
+ score = model_fn(x, adj, flags)
24
+ else:
25
+ raise NotImplementedError(f"Discrete not supported")
26
+ return score
27
+ else:
28
+ raise NotImplementedError(f"SDE class {sde.__class__.__name__} not supported.")
29
+ return score_fn
30
+
31
+ def load_sde(sde_type, beta_min, beta_max, num_scales):
32
+ if sde_type == "VP":
33
+ sde = VPSDE(beta_min=beta_min, beta_max=beta_max, N=num_scales)
34
+ elif sde_type == "VE":
35
+ sde = VESDE(sigma_min=beta_min, sigma_max=beta_max, N=num_scales)
36
+ elif sde_type == "subVP":
37
+ sde = subVPSDE(beta_min=beta_min, beta_max=beta_max, N=num_scales)
38
+ else:
39
+ raise NotImplementedError(f"SDE class {sde_type} not yet supported.")
40
+ return sde
41
+
42
+ class SDE(abc.ABC):
43
+ """SDE abstract class. Functions are designed for a mini-batch of inputs."""
44
+
45
+ def __init__(self, N):
46
+ """Construct an SDE.
47
+ Args:
48
+ N: number of discretization time steps.
49
+ """
50
+ super().__init__()
51
+ self.N = N
52
+
53
+ @property
54
+ @abc.abstractmethod
55
+ def T(self):
56
+ """End time of the SDE."""
57
+ pass
58
+
59
+ @abc.abstractmethod
60
+ def sde(self, x, t):
61
+ pass
62
+
63
+ @abc.abstractmethod
64
+ def marginal_prob(self, x, t):
65
+ """Parameters to determine the marginal distribution of the SDE, $p_t(x)$."""
66
+ pass
67
+
68
+ @abc.abstractmethod
69
+ def prior_sampling(self, shape):
70
+ """Generate one sample from the prior distribution, $p_T(x)$."""
71
+ pass
72
+
73
+ @abc.abstractmethod
74
+ def prior_logp(self, z):
75
+ """Compute log-density of the prior distribution.
76
+ Useful for computing the log-likelihood via probability flow ODE.
77
+ Args:
78
+ z: latent code
79
+ Returns:
80
+ log probability density
81
+ """
82
+ pass
83
+
84
+ def discretize(self, x, t):
85
+ """Discretize the SDE in the form: x_{i+1} = x_i + f_i(x_i) + G_i z_i.
86
+ Useful for reverse diffusion sampling and probabiliy flow sampling.
87
+ Defaults to Euler-Maruyama discretization.
88
+ Args:
89
+ x: a torch tensor
90
+ t: a torch float representing the time step (from 0 to `self.T`)
91
+ Returns:
92
+ f, G
93
+ """
94
+ dt = 1 / self.N
95
+ drift, diffusion = self.sde(x, t)
96
+ f = drift * dt
97
+ G = diffusion * torch.sqrt(torch.tensor(dt, device=t.device))
98
+ return f, G
99
+
100
+ def reverse(self, score_fn, probability_flow=False):
101
+ """Create the reverse-time SDE/ODE.
102
+ Args:
103
+ score_fn: A time-dependent score-based model that takes x and t and returns the score.
104
+ probability_flow: If `True`, create the reverse-time ODE used for probability flow sampling.
105
+ """
106
+ N = self.N
107
+ T = self.T
108
+ sde_fn = self.sde
109
+ discretize_fn = self.discretize
110
+
111
+ # -------- Build the class for reverse-time SDE --------
112
+ class RSDE(self.__class__):
113
+ def __init__(self):
114
+ self.N = N
115
+ self.probability_flow = probability_flow
116
+
117
+ @property
118
+ def T(self):
119
+ return T
120
+
121
+ def sde(self, feature, x, flags, t, is_adj=True):
122
+ """Create the drift and diffusion functions for the reverse SDE/ODE."""
123
+ drift, diffusion = sde_fn(x, t) if is_adj else sde_fn(feature, t)
124
+ score = score_fn(feature, x, flags, t)
125
+ drift = drift - diffusion[:, None, None] ** 2 * score * (
126
+ 0.5 if self.probability_flow else 1.0
127
+ )
128
+ # -------- Set the diffusion function to zero for ODEs. --------
129
+ diffusion = 0.0 if self.probability_flow else diffusion
130
+ return drift, diffusion
131
+
132
+ def discretize(self, feature, x, flags, t, is_adj=True):
133
+ """Create discretized iteration rules for the reverse diffusion sampler."""
134
+ f, G = discretize_fn(x, t) if is_adj else discretize_fn(feature, t)
135
+ score = score_fn(feature, x, flags, t)
136
+ rev_f = f - G[:, None, None] ** 2 * score * (
137
+ 0.5 if self.probability_flow else 1.0
138
+ )
139
+ rev_G = torch.zeros_like(G) if self.probability_flow else G
140
+ return rev_f, rev_G
141
+
142
+ return RSDE()
143
+
144
+ class VPSDE(SDE):
145
+ def __init__(self, beta_min=0.1, beta_max=20, N=1000):
146
+ """Construct a Variance Preserving SDE.
147
+ Args:
148
+ beta_min: value of beta(0)
149
+ beta_max: value of beta(1)
150
+ N: number of discretization steps
151
+ """
152
+ super().__init__(N)
153
+ self.beta_0 = beta_min
154
+ self.beta_1 = beta_max
155
+ self.N = N
156
+ self.discrete_betas = torch.linspace(beta_min / N, beta_max / N, N)
157
+ self.alphas = 1.0 - self.discrete_betas
158
+ self.alphas_cumprod = torch.cumprod(self.alphas, dim=0)
159
+ self.sqrt_alphas_cumprod = torch.sqrt(self.alphas_cumprod)
160
+ self.sqrt_1m_alphas_cumprod = torch.sqrt(1.0 - self.alphas_cumprod)
161
+
162
+ @property
163
+ def T(self):
164
+ return 1
165
+
166
+ def sde(self, x, t):
167
+ beta_t = self.beta_0 + t * (self.beta_1 - self.beta_0)
168
+ drift = -0.5 * beta_t[:, None, None] * x
169
+ diffusion = torch.sqrt(beta_t)
170
+ return drift, diffusion
171
+
172
+ # -------- mean, std of the perturbation kernel --------
173
+ def marginal_prob(self, x, t):
174
+ log_mean_coeff = (
175
+ -0.25 * t**2 * (self.beta_1 - self.beta_0) - 0.5 * t * self.beta_0
176
+ )
177
+ mean = torch.exp(log_mean_coeff[:, None, None]) * x
178
+ std = torch.sqrt(1.0 - torch.exp(2.0 * log_mean_coeff))
179
+ return mean, std
180
+
181
+ def prior_sampling(self, shape):
182
+ return torch.randn(*shape)
183
+
184
+ def prior_sampling_sym(self, shape):
185
+ x = torch.randn(*shape).triu(1)
186
+ return x + x.transpose(-1, -2)
187
+
188
+ def prior_logp(self, z):
189
+ shape = z.shape
190
+ N = np.prod(shape[1:])
191
+ logps = -N / 2.0 * np.log(2 * np.pi) - torch.sum(z**2, dim=(1, 2)) / 2.0
192
+ return logps
193
+
194
+ def discretize(self, x, t):
195
+ """DDPM discretization."""
196
+ timestep = (t * (self.N - 1) / self.T).long()
197
+ beta = self.discrete_betas.to(x.device)[timestep]
198
+ alpha = self.alphas.to(x.device)[timestep]
199
+ sqrt_beta = torch.sqrt(beta)
200
+ f = torch.sqrt(alpha)[:, None, None] * x - x
201
+ G = sqrt_beta
202
+ return f, G
203
+
204
+ def transition(self, x, t, dt):
205
+ # -------- negative timestep dt --------
206
+ log_mean_coeff = (
207
+ 0.25 * dt * (2 * self.beta_0 + (2 * t + dt) * (self.beta_1 - self.beta_0))
208
+ )
209
+ mean = torch.exp(-log_mean_coeff[:, None, None]) * x
210
+ std = torch.sqrt(1.0 - torch.exp(2.0 * log_mean_coeff))
211
+ return mean, std
212
+
213
+
214
+ class VESDE(SDE):
215
+ def __init__(self, sigma_min=0.01, sigma_max=50, N=1000):
216
+ """Construct a Variance Exploding SDE.
217
+ Args:
218
+ sigma_min: smallest sigma.
219
+ sigma_max: largest sigma.
220
+ N: number of discretization steps
221
+ """
222
+ super().__init__(N)
223
+ self.sigma_min = sigma_min
224
+ self.sigma_max = sigma_max
225
+ self.discrete_sigmas = torch.exp(
226
+ torch.linspace(np.log(self.sigma_min), np.log(self.sigma_max), N)
227
+ )
228
+ self.N = N
229
+
230
+ @property
231
+ def T(self):
232
+ return 1
233
+
234
+ def sde(self, x, t):
235
+ sigma = self.sigma_min * (self.sigma_max / self.sigma_min) ** t
236
+ drift = torch.zeros_like(x)
237
+ diffusion = sigma * torch.sqrt(
238
+ torch.tensor(
239
+ 2 * (np.log(self.sigma_max) - np.log(self.sigma_min)), device=t.device
240
+ )
241
+ )
242
+ return drift, diffusion
243
+
244
+ def marginal_prob(self, x, t):
245
+ std = self.sigma_min * (self.sigma_max / self.sigma_min) ** t
246
+ mean = x
247
+ return mean, std
248
+
249
+ def prior_sampling(self, shape):
250
+ return torch.randn(*shape)
251
+
252
+ def prior_sampling_sym(self, shape):
253
+ x = torch.randn(*shape).triu(1)
254
+ x = x + x.transpose(-1, -2)
255
+ return x
256
+
257
+ def prior_logp(self, z):
258
+ shape = z.shape
259
+ N = np.prod(shape[1:])
260
+ return -N / 2.0 * np.log(2 * np.pi * self.sigma_max**2) - torch.sum(
261
+ z**2, dim=(1, 2, 3)
262
+ ) / (2 * self.sigma_max**2)
263
+
264
+ def discretize(self, x, t):
265
+ """SMLD(NCSN) discretization."""
266
+ timestep = (t * (self.N - 1) / self.T).long()
267
+ self.discrete_sigmas = self.discrete_sigmas.to(t.device)
268
+ sigma = self.discrete_sigmas.to(t.device)[timestep]
269
+ adjacent_sigma = torch.where(
270
+ timestep == 0,
271
+ torch.zeros_like(t),
272
+ self.discrete_sigmas[timestep - 1].to(t.device),
273
+ )
274
+ f = torch.zeros_like(x)
275
+ G = torch.sqrt(sigma**2 - adjacent_sigma**2)
276
+ return f, G
277
+
278
+ def transition(self, x, t, dt):
279
+ # -------- negative timestep dt --------
280
+ std = torch.square(
281
+ self.sigma_min * (self.sigma_max / self.sigma_min) ** t
282
+ ) - torch.square(self.sigma_min * (self.sigma_max / self.sigma_min) ** (t + dt))
283
+ std = torch.sqrt(std)
284
+ mean = x
285
+ return mean, std
286
+
287
+
288
+ class subVPSDE(SDE):
289
+ def __init__(self, beta_min=0.1, beta_max=20, N=1000):
290
+ """Construct the sub-VP SDE that excels at likelihoods.
291
+ Args:
292
+ beta_min: value of beta(0)
293
+ beta_max: value of beta(1)
294
+ N: number of discretization steps
295
+ """
296
+ super().__init__(N)
297
+ self.beta_0 = beta_min
298
+ self.beta_1 = beta_max
299
+ self.N = N
300
+ self.discrete_betas = torch.linspace(beta_min / N, beta_max / N, N)
301
+ self.alphas = 1.0 - self.discrete_betas
302
+
303
+ @property
304
+ def T(self):
305
+ return 1
306
+
307
+ def sde(self, x, t):
308
+ beta_t = self.beta_0 + t * (self.beta_1 - self.beta_0)
309
+ drift = -0.5 * beta_t[:, None, None] * x
310
+ discount = 1.0 - torch.exp(
311
+ -2 * self.beta_0 * t - (self.beta_1 - self.beta_0) * t**2
312
+ )
313
+ diffusion = torch.sqrt(beta_t * discount)
314
+ return drift, diffusion
315
+
316
+ def marginal_prob(self, x, t):
317
+ log_mean_coeff = (
318
+ -0.25 * t**2 * (self.beta_1 - self.beta_0) - 0.5 * t * self.beta_0
319
+ )
320
+ mean = torch.exp(log_mean_coeff)[:, None, None] * x
321
+ std = 1 - torch.exp(2.0 * log_mean_coeff)
322
+ return mean, std
323
+
324
+ def prior_sampling(self, shape):
325
+ return torch.randn(*shape)
326
+
327
+ def prior_sampling_sym(self, shape):
328
+ x = torch.randn(*shape).triu(1)
329
+ return x + x.transpose(-1, -2)
330
+
331
+ def prior_logp(self, z):
332
+ shape = z.shape
333
+ N = np.prod(shape[1:])
334
+ return -N / 2.0 * np.log(2 * np.pi) - torch.sum(z**2, dim=(1, 2, 3)) / 2.0
@@ -0,0 +1,227 @@
1
+ import torch
2
+ import numpy as np
3
+ import abc
4
+
5
+ from .utils import mask_adjs, mask_x, gen_noise
6
+ from .sde import VPSDE, subVPSDE, get_score_fn
7
+
8
+ ### sampling
9
+ # -------- PC sampler --------
10
+ def get_pc_sampler(
11
+ sde_x,
12
+ sde_adj,
13
+ predictor="Euler",
14
+ corrector="None",
15
+ snr=0.1,
16
+ scale_eps=1.0,
17
+ n_steps=1,
18
+ probability_flow=False,
19
+ continuous=False,
20
+ denoise=True,
21
+ eps=1e-3,
22
+ device="cuda",
23
+ ):
24
+ def pc_sampler(model_x, model_adj, shape_x, shape_adj, init_flags):
25
+ score_fn_x = get_score_fn(sde_x, model_x, train=False, continuous=continuous)
26
+ score_fn_adj = get_score_fn(
27
+ sde_adj, model_adj, train=False, continuous=continuous
28
+ )
29
+
30
+ predictor_fn = (
31
+ ReverseDiffusionPredictor
32
+ if predictor == "Reverse"
33
+ else EulerMaruyamaPredictor
34
+ )
35
+ corrector_fn = LangevinCorrector if corrector == "Langevin" else NoneCorrector
36
+
37
+ predictor_obj_x = predictor_fn("x", sde_x, score_fn_x, probability_flow)
38
+ corrector_obj_x = corrector_fn(
39
+ "x", sde_x, score_fn_x, snr, scale_eps, n_steps
40
+ )
41
+
42
+ predictor_obj_adj = predictor_fn(
43
+ "adj", sde_adj, score_fn_adj, probability_flow
44
+ )
45
+ corrector_obj_adj = corrector_fn(
46
+ "adj", sde_adj, score_fn_adj, snr, scale_eps, n_steps
47
+ )
48
+
49
+ with torch.no_grad():
50
+ # -------- Initial sample --------
51
+ x = sde_x.prior_sampling(shape_x).to(device)
52
+ adj = sde_adj.prior_sampling_sym(shape_adj).to(device)
53
+ flags = init_flags
54
+ x = mask_x(x, flags)
55
+ adj = mask_adjs(adj, flags)
56
+ diff_steps = sde_adj.N
57
+ timesteps = torch.linspace(sde_adj.T, eps, diff_steps, device=device)
58
+
59
+ # -------- Reverse diffusion process --------
60
+ # for i in trange(
61
+ # 0, (diff_steps), desc="[Sampling]", position=1, leave=False
62
+ # ):
63
+ for i in range(0, diff_steps):
64
+ t = timesteps[i]
65
+ vec_t = torch.ones(shape_adj[0], device=t.device) * t
66
+
67
+ _x = x
68
+ x, x_mean = corrector_obj_x.update_fn(x, adj, flags, vec_t)
69
+ adj, adj_mean = corrector_obj_adj.update_fn(_x, adj, flags, vec_t)
70
+
71
+ _x = x
72
+ x, x_mean = predictor_obj_x.update_fn(x, adj, flags, vec_t)
73
+ adj, adj_mean = predictor_obj_adj.update_fn(_x, adj, flags, vec_t)
74
+ # print(" ")
75
+ return (
76
+ (x_mean if denoise else x),
77
+ (adj_mean if denoise else adj),
78
+ diff_steps * (n_steps + 1),
79
+ )
80
+
81
+ return pc_sampler
82
+
83
+
84
+ class Predictor(abc.ABC):
85
+ """The abstract class for a predictor algorithm."""
86
+
87
+ def __init__(self, sde, score_fn, probability_flow=False):
88
+ super().__init__()
89
+ self.sde = sde
90
+ # Compute the reverse SDE/ODE
91
+ self.rsde = sde.reverse(score_fn, probability_flow)
92
+ self.score_fn = score_fn
93
+
94
+ @abc.abstractmethod
95
+ def update_fn(self, x, t, flags):
96
+ pass
97
+
98
+
99
+ class Corrector(abc.ABC):
100
+ """The abstract class for a corrector algorithm."""
101
+
102
+ def __init__(self, sde, score_fn, snr, scale_eps, n_steps):
103
+ super().__init__()
104
+ self.sde = sde
105
+ self.score_fn = score_fn
106
+ self.snr = snr
107
+ self.scale_eps = scale_eps
108
+ self.n_steps = n_steps
109
+
110
+ @abc.abstractmethod
111
+ def update_fn(self, x, t, flags):
112
+ pass
113
+
114
+
115
+ class EulerMaruyamaPredictor(Predictor):
116
+ def __init__(self, obj, sde, score_fn, probability_flow=False):
117
+ super().__init__(sde, score_fn, probability_flow)
118
+ self.obj = obj
119
+
120
+ def update_fn(self, x, adj, flags, t):
121
+ dt = -1.0 / self.rsde.N
122
+
123
+ if self.obj == "x":
124
+ z = gen_noise(x, flags, sym=False)
125
+ drift, diffusion = self.rsde.sde(x, adj, flags, t, is_adj=False)
126
+ x_mean = x + drift * dt
127
+ x = x_mean + diffusion[:, None, None] * np.sqrt(-dt) * z
128
+ return x, x_mean
129
+
130
+ elif self.obj == "adj":
131
+ z = gen_noise(adj, flags)
132
+ drift, diffusion = self.rsde.sde(x, adj, flags, t, is_adj=True)
133
+ adj_mean = adj + drift * dt
134
+ adj = adj_mean + diffusion[:, None, None] * np.sqrt(-dt) * z
135
+
136
+ return adj, adj_mean
137
+
138
+ else:
139
+ raise NotImplementedError(f"obj {self.obj} not yet supported.")
140
+
141
+
142
+ class ReverseDiffusionPredictor(Predictor):
143
+ def __init__(self, obj, sde, score_fn, probability_flow=False):
144
+ super().__init__(sde, score_fn, probability_flow)
145
+ self.obj = obj
146
+
147
+ def update_fn(self, x, adj, flags, t):
148
+ if self.obj == "x":
149
+ f, G = self.rsde.discretize(x, adj, flags, t, is_adj=False)
150
+ z = gen_noise(x, flags, sym=False)
151
+ x_mean = x - f
152
+ x = x_mean + G[:, None, None] * z
153
+ return x, x_mean
154
+
155
+ elif self.obj == "adj":
156
+ f, G = self.rsde.discretize(x, adj, flags, t, is_adj=True)
157
+ z = gen_noise(adj, flags)
158
+ adj_mean = adj - f
159
+ adj = adj_mean + G[:, None, None] * z
160
+ return adj, adj_mean
161
+
162
+ else:
163
+ raise NotImplementedError(f"obj {self.obj} not yet supported.")
164
+
165
+
166
+ class NoneCorrector(Corrector):
167
+ """An empty corrector that does nothing."""
168
+
169
+ def __init__(self, obj, sde, score_fn, snr, scale_eps, n_steps):
170
+ self.obj = obj
171
+ pass
172
+
173
+ def update_fn(self, x, adj, flags, t):
174
+ if self.obj == "x":
175
+ return x, x
176
+ elif self.obj == "adj":
177
+ return adj, adj
178
+ else:
179
+ raise NotImplementedError(f"obj {self.obj} not yet supported.")
180
+
181
+
182
+ class LangevinCorrector(Corrector):
183
+ def __init__(self, obj, sde, score_fn, snr, scale_eps, n_steps):
184
+ super().__init__(sde, score_fn, snr, scale_eps, n_steps)
185
+ self.obj = obj
186
+
187
+ def update_fn(self, x, adj, flags, t):
188
+ sde = self.sde
189
+ score_fn = self.score_fn
190
+ n_steps = self.n_steps
191
+ target_snr = self.snr
192
+ seps = self.scale_eps
193
+
194
+ if isinstance(sde, VPSDE) or isinstance(sde, subVPSDE):
195
+ timestep = (t * (sde.N - 1) / sde.T).long()
196
+ alpha = sde.alphas.to(t.device)[timestep]
197
+ else:
198
+ alpha = torch.ones_like(t)
199
+
200
+ if self.obj == "x":
201
+ for i in range(n_steps):
202
+ grad = score_fn(x, adj, flags, t)
203
+ noise = gen_noise(x, flags, sym=False)
204
+ grad_norm = torch.norm(grad.reshape(grad.shape[0], -1), dim=-1).mean()
205
+ noise_norm = torch.norm(
206
+ noise.reshape(noise.shape[0], -1), dim=-1
207
+ ).mean()
208
+ step_size = (target_snr * noise_norm / grad_norm) ** 2 * 2 * alpha
209
+ x_mean = x + step_size[:, None, None] * grad
210
+ x = x_mean + torch.sqrt(step_size * 2)[:, None, None] * noise * seps
211
+ return x, x_mean
212
+
213
+ elif self.obj == "adj":
214
+ for i in range(n_steps):
215
+ grad = score_fn(x, adj, flags, t)
216
+ noise = gen_noise(adj, flags)
217
+ grad_norm = torch.norm(grad.reshape(grad.shape[0], -1), dim=-1).mean()
218
+ noise_norm = torch.norm(
219
+ noise.reshape(noise.shape[0], -1), dim=-1
220
+ ).mean()
221
+ step_size = (target_snr * noise_norm / grad_norm) ** 2 * 2 * alpha
222
+ adj_mean = adj + step_size[:, None, None] * grad
223
+ adj = adj_mean + torch.sqrt(step_size * 2)[:, None, None] * noise * seps
224
+ return adj, adj_mean
225
+
226
+ else:
227
+ raise NotImplementedError(f"obj {self.obj} not yet supported")