Spaces:
Paused
Paused
File size: 2,889 Bytes
e9d1f07 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | """
This file contains implementations of the forward diffusion process
Current Models:
1) Gaussian Diffusion
"""
import torch
from torch import nn
from .beta_schedules import *
class ForwardModel(nn.Module):
"""
(Forward Model Template)
"""
def __init__(self,
num_timesteps=1000,
schedule='linear'
):
super().__init__()
self.schedule=schedule
self.num_timesteps=num_timesteps
@torch.no_grad()
def forward(self, x_0, t):
"""
Get noisy sample at t given x_0
"""
raise NotImplemented
@torch.no_grad()
def step(self, x_t, t):
"""
Get next sample in the process
"""
raise NotImplemented
class GaussianForwardProcess(ForwardModel):
"""
Gassian Forward Model
"""
def __init__(self,
num_timesteps=1000,
schedule='linear'
):
super().__init__(num_timesteps=num_timesteps,
schedule=schedule
)
# get process parameters
self.register_buffer('betas',get_beta_schedule(self.schedule,self.num_timesteps))
self.register_buffer('betas_sqrt',self.betas.sqrt())
self.register_buffer('alphas',1-self.betas)
self.register_buffer('alphas_cumprod',torch.cumprod(self.alphas,0))
self.register_buffer('alphas_cumprod_sqrt',self.alphas_cumprod.sqrt())
self.register_buffer('alphas_one_minus_cumprod_sqrt',(1-self.alphas_cumprod).sqrt())
self.register_buffer('alphas_sqrt',self.alphas.sqrt())
@torch.no_grad()
def forward(self, x_0, t, return_noise=False):
"""
Get noisy sample at t given x_0
q(x_t | x_0)=N(x_t; alphas_cumprod_sqrt(t)*x_0, 1-alpha_cumprod(t)*I)
"""
assert (t<self.num_timesteps).all()
b=x_0.shape[0]
mean=x_0*self.alphas_cumprod_sqrt[t].view(b,1,1,1)
std=self.alphas_one_minus_cumprod_sqrt[t].view(b,1,1,1)
noise=torch.randn_like(x_0)
output=mean+std*noise
if not return_noise:
return output
else:
return output, noise
@torch.no_grad()
def step(self, x_t, t, return_noise=False):
"""
Get next sample in the process
q(x_t | x_t-1)=N(x_t; alphas_sqrt(t)*x_0,betas(t)*I)
"""
assert (t<self.num_timesteps).all()
mean=self.alphas_sqrt[t]*x_t
std=self.betas_sqrt[t]
noise=torch.randn_like(x_0)
output=mean+std*noise
if not return_noise:
return output
else:
return output, noise |