trenden commited on
Commit
aa53b1a
·
verified ·
1 Parent(s): 03d9cd8

Upload sgmse/sampling/predictors.py

Browse files
Files changed (1) hide show
  1. sgmse/sampling/predictors.py +76 -0
sgmse/sampling/predictors.py ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import abc
2
+
3
+ import torch
4
+ import numpy as np
5
+
6
+ from sgmse.util.registry import Registry
7
+
8
+
9
+ PredictorRegistry = Registry("Predictor")
10
+
11
+
12
+ class Predictor(abc.ABC):
13
+ """The abstract class for a predictor algorithm."""
14
+
15
+ def __init__(self, sde, score_fn, probability_flow=False):
16
+ super().__init__()
17
+ self.sde = sde
18
+ self.rsde = sde.reverse(score_fn)
19
+ self.score_fn = score_fn
20
+ self.probability_flow = probability_flow
21
+
22
+ @abc.abstractmethod
23
+ def update_fn(self, x, t, *args):
24
+ """One update of the predictor.
25
+
26
+ Args:
27
+ x: A PyTorch tensor representing the current state
28
+ t: A Pytorch tensor representing the current time step.
29
+ *args: Possibly additional arguments, in particular `y` for OU processes
30
+
31
+ Returns:
32
+ x: A PyTorch tensor of the next state.
33
+ x_mean: A PyTorch tensor. The next state without random noise. Useful for denoising.
34
+ """
35
+ pass
36
+
37
+ def debug_update_fn(self, x, t, *args):
38
+ raise NotImplementedError(f"Debug update function not implemented for predictor {self}.")
39
+
40
+
41
+ @PredictorRegistry.register('euler_maruyama')
42
+ class EulerMaruyamaPredictor(Predictor):
43
+ def __init__(self, sde, score_fn, probability_flow=False):
44
+ super().__init__(sde, score_fn, probability_flow=probability_flow)
45
+
46
+ def update_fn(self, x, y, t, *args):
47
+ dt = -1. / self.rsde.N
48
+ z = torch.randn_like(x)
49
+ f, g = self.rsde.sde(x, y, t, *args)
50
+ x_mean = x + f * dt
51
+ x = x_mean + g[:, None, None, None] * np.sqrt(-dt) * z
52
+ return x, x_mean
53
+
54
+
55
+ @PredictorRegistry.register('reverse_diffusion')
56
+ class ReverseDiffusionPredictor(Predictor):
57
+ def __init__(self, sde, score_fn, probability_flow=False):
58
+ super().__init__(sde, score_fn, probability_flow=probability_flow)
59
+
60
+ def update_fn(self, x, y, t, stepsize):
61
+ f, g = self.rsde.discretize(x, y, t, stepsize)
62
+ z = torch.randn_like(x)
63
+ x_mean = x - f
64
+ x = x_mean + g[:, None, None, None] * z
65
+ return x, x_mean
66
+
67
+
68
+ @PredictorRegistry.register('none')
69
+ class NonePredictor(Predictor):
70
+ """An empty predictor that does nothing."""
71
+
72
+ def __init__(self, *args, **kwargs):
73
+ pass
74
+
75
+ def update_fn(self, x, y, t, *args):
76
+ return x, x