Roadmap / Diffusion & Multimodal Models

✓

DDPM Sampling Step

mediumdiffusionsampling

The problem

To generate an image, a diffusion model runs the noising process backwards: it starts from pure noise xTx_T and, at each step tt from TT down to 1, asks the network for a prediction of the noise in xtx_t and removes a bit of it, getting xt−1x_{t-1}. You will write one reverse step, the clean-image estimate, and the whole loop (Ho et al., 2020, Algorithm 2).

One reverse step

Given the current sample xtx_t and the network's noise prediction ϵ^\hat\epsilon:

xt−1=1αt(xt−βt1−αˉt ϵ^)+σtzx_{t-1} = \frac{1}{\sqrt{\alpha_t}}\left(x_t - \frac{\beta_t}{\sqrt{1 - \bar\alpha_t}}\,\hat\epsilon\right) + \sigma_t z

where:

  • αt=1−βt\alpha_t = 1 - \beta_t and αˉt\bar\alpha_t come from the schedule of the previous exercise;
  • the first part removes the predicted noise from xtx_t;
  • σt=βt\sigma_t = \sqrt{\beta_t}, and zz is fresh standard Gaussian noise for t>1t > 1, but z=0z = 0 at the last step, t=1t = 1: the final image has no noise added.

Example. Schedule β=(0.1,0.2,0.3,0.4)\beta = (0.1, 0.2, 0.3, 0.4), so αˉ=(0.9,0.72,0.504,0.3024)\bar\alpha = (0.9, 0.72, 0.504, 0.3024). Step t=2t = 2 with x2=1.0x_2 = 1.0, prediction ϵ^=0.5\hat\epsilon = 0.5 and fresh noise z=0.7z = 0.7:

  • first part: 10.8(1.0−0.20.28⋅0.5)=0.907\frac{1}{\sqrt{0.8}}\left(1.0 - \frac{0.2}{\sqrt{0.28}} \cdot 0.5\right) = 0.907;
  • noise: 0.2⋅0.7=0.313\sqrt{0.2} \cdot 0.7 = 0.313;
  • x1=1.220x_1 = 1.220.

Step t=1t = 1 with the same xx and ϵ^\hat\epsilon: no noise term, and x0=0.887x_0 = 0.887 (with β1=0.1\beta_1 = 0.1).

The clean-image estimate

From the noise prediction one can estimate the clean image directly, inverting the forward formula:

x^0=xt−1−αˉt ϵ^αˉt\hat x_0 = \frac{x_t - \sqrt{1 - \bar\alpha_t}\,\hat\epsilon}{\sqrt{\bar\alpha_t}}

Example. The forward example: x0=2x_0 = 2 and noise 1 gave x2=2.226x_2 = 2.226. If the network predicts the noise exactly (ϵ^=1\hat\epsilon = 1): x^0=(2.226−0.529⋅1)/0.72=2\hat x_0 = (2.226 - 0.529 \cdot 1) / \sqrt{0.72} = 2. A wrong prediction gives a wrong estimate.

What to implement

With betas and abar indexed from 0 as in the previous exercise (step tt is index t−1t - 1):

  • predict_x0(x_t, eps_hat, t, abar): the clean-image estimate.
  • reverse_step(x_t, eps_hat, t, betas, abar, z): xt−1x_{t-1}. z is given (an array shaped like x_t), so the step is deterministic; ignore it when t=1t = 1.
  • sample(eps_model, x_T, betas, abar, rng): the full loop from t=Tt = T down to 1, calling eps_model(x, t) for the prediction and drawing z = rng.standard_normal(x.shape) at every step with t>1t > 1 (and none at t=1t = 1).

Requirements

  • αt=1−βt\alpha_t = 1 - \beta_t.
  • Draw the random numbers exactly as described so that the tests can reproduce the samples.
solution.py
Python idle

Press Run (⌘/Ctrl + Enter) to test your code.