| 13 | |
| 14 | |
| 15 | class Diffusion: |
| 16 | def __init__(self, noise_steps=1000, beta_start=1e-4, beta_end=0.02, img_size=256, device="cuda"): |
| 17 | self.noise_steps = noise_steps |
| 18 | self.beta_start = beta_start |
| 19 | self.beta_end = beta_end |
| 20 | self.img_size = img_size |
| 21 | self.device = device |
| 22 | |
| 23 | self.beta = self.prepare_noise_schedule().to(device) |
| 24 | self.alpha = 1. - self.beta |
| 25 | self.alpha_hat = torch.cumprod(self.alpha, dim=0) |
| 26 | |
| 27 | def prepare_noise_schedule(self): |
| 28 | return torch.linspace(self.beta_start, self.beta_end, self.noise_steps) |
| 29 | |
| 30 | def noise_images(self, x, t): |
| 31 | sqrt_alpha_hat = torch.sqrt(self.alpha_hat[t])[:, None, None, None] |
| 32 | sqrt_one_minus_alpha_hat = torch.sqrt(1 - self.alpha_hat[t])[:, None, None, None] |
| 33 | Ɛ = torch.randn_like(x) |
| 34 | return sqrt_alpha_hat * x + sqrt_one_minus_alpha_hat * Ɛ, Ɛ |
| 35 | |
| 36 | def sample_timesteps(self, n): |
| 37 | return torch.randint(low=1, high=self.noise_steps, size=(n,)) |
| 38 | |
| 39 | def sample(self, model, n): |
| 40 | logging.info(f"Sampling {n} new images....") |
| 41 | model.eval() |
| 42 | with torch.no_grad(): |
| 43 | x = torch.randn((n, 3, self.img_size, self.img_size)).to(self.device) |
| 44 | for i in tqdm(reversed(range(1, self.noise_steps)), position=0): |
| 45 | t = (torch.ones(n) * i).long().to(self.device) |
| 46 | predicted_noise = model(x, t) |
| 47 | alpha = self.alpha[t][:, None, None, None] |
| 48 | alpha_hat = self.alpha_hat[t][:, None, None, None] |
| 49 | beta = self.beta[t][:, None, None, None] |
| 50 | if i > 1: |
| 51 | noise = torch.randn_like(x) |
| 52 | else: |
| 53 | noise = torch.zeros_like(x) |
| 54 | x = 1 / torch.sqrt(alpha) * (x - ((1 - alpha) / (torch.sqrt(1 - alpha_hat))) * predicted_noise) + torch.sqrt(beta) * noise |
| 55 | model.train() |
| 56 | x = (x.clamp(-1, 1) + 1) / 2 |
| 57 | x = (x * 255).type(torch.uint8) |
| 58 | return x |
| 59 | |
| 60 | |
| 61 | def train(args): |
no outgoing calls
no test coverage detected