Utilities for training and sampling diffusion models. Original ported from this codebase: https://github.com/hojonathanho/diffusion/blob/1e0dceb3b3495bbe19116a5e1b3596cd0706c543/diffusion_tf/diffusion_utils_2.py#L42 :param betas: a 1-D numpy array of betas for each diffusion timeste
| 142 | |
| 143 | |
| 144 | class GaussianDiffusion: |
| 145 | """ |
| 146 | Utilities for training and sampling diffusion models. |
| 147 | Original ported from this codebase: |
| 148 | https://github.com/hojonathanho/diffusion/blob/1e0dceb3b3495bbe19116a5e1b3596cd0706c543/diffusion_tf/diffusion_utils_2.py#L42 |
| 149 | :param betas: a 1-D numpy array of betas for each diffusion timestep, |
| 150 | starting at T and going to 1. |
| 151 | """ |
| 152 | |
| 153 | def __init__( |
| 154 | self, |
| 155 | *, |
| 156 | betas, |
| 157 | model_mean_type, |
| 158 | model_var_type, |
| 159 | loss_type |
| 160 | ): |
| 161 | |
| 162 | self.model_mean_type = model_mean_type |
| 163 | self.model_var_type = model_var_type |
| 164 | self.loss_type = loss_type |
| 165 | |
| 166 | # Use float64 for accuracy. |
| 167 | betas = np.array(betas, dtype=np.float64) |
| 168 | self.betas = betas |
| 169 | assert len(betas.shape) == 1, "betas must be 1-D" |
| 170 | assert (betas > 0).all() and (betas <= 1).all() |
| 171 | |
| 172 | self.num_timesteps = int(betas.shape[0]) |
| 173 | |
| 174 | alphas = 1.0 - betas |
| 175 | self.alphas_cumprod = np.cumprod(alphas, axis=0) |
| 176 | self.alphas_cumprod_prev = np.append(1.0, self.alphas_cumprod[:-1]) |
| 177 | self.alphas_cumprod_next = np.append(self.alphas_cumprod[1:], 0.0) |
| 178 | assert self.alphas_cumprod_prev.shape == (self.num_timesteps,) |
| 179 | |
| 180 | # calculations for diffusion q(x_t | x_{t-1}) and others |
| 181 | self.sqrt_alphas_cumprod = np.sqrt(self.alphas_cumprod) |
| 182 | self.sqrt_one_minus_alphas_cumprod = np.sqrt(1.0 - self.alphas_cumprod) |
| 183 | self.log_one_minus_alphas_cumprod = np.log(1.0 - self.alphas_cumprod) |
| 184 | self.sqrt_recip_alphas_cumprod = np.sqrt(1.0 / self.alphas_cumprod) |
| 185 | self.sqrt_recipm1_alphas_cumprod = np.sqrt(1.0 / self.alphas_cumprod - 1) |
| 186 | |
| 187 | # calculations for posterior q(x_{t-1} | x_t, x_0) |
| 188 | self.posterior_variance = ( |
| 189 | betas * (1.0 - self.alphas_cumprod_prev) / (1.0 - self.alphas_cumprod) |
| 190 | ) |
| 191 | # below: log calculation clipped because the posterior variance is 0 at the beginning of the diffusion chain |
| 192 | self.posterior_log_variance_clipped = np.log( |
| 193 | np.append(self.posterior_variance[1], self.posterior_variance[1:]) |
| 194 | ) if len(self.posterior_variance) > 1 else np.array([]) |
| 195 | |
| 196 | self.posterior_mean_coef1 = ( |
| 197 | betas * np.sqrt(self.alphas_cumprod_prev) / (1.0 - self.alphas_cumprod) |
| 198 | ) |
| 199 | self.posterior_mean_coef2 = ( |
| 200 | (1.0 - self.alphas_cumprod_prev) * np.sqrt(alphas) / (1.0 - self.alphas_cumprod) |
| 201 | ) |