The problem
A diffusion model learns to make images by learning to undo noise. First we need the forward process: adding noise to an image, a little at a time, in steps. You will write the schedule of how much noise is added at each step, and the function that jumps straight to any step. This is the DDPM (Denoising Diffusion Probabilistic Models) schedule.
The schedule
At step a small amount of noise of variance is added. Two derived quantities:
where is the share of the signal that survives step , and ("alpha bar") is the product of the survivals up to step : the share of the original image still in the sample. DDPM's grows linearly from to .
Example. , .
- .
- : running product: , then , then , then .
Jumping to step
You do not need to add noise times: the sum of many small Gaussian noises is one Gaussian noise, so
where is the clean data, is standard Gaussian noise (given in the tests, shaped like ), and the two coefficients say how much of the signal and how much of the noise are in .
Example. Same schedule, , noise , step (): . In the code, is
abar[1]: the array is indexed from 0.
The training loss
The network predicts the noise that was added; the loss is the mean squared error between its prediction and the true noise.
Example. The true noise is and the prediction : squared errors , mean .
What to implement
linear_betas(T, beta_1=1e-4, beta_T=0.02): values increasing linearly frombeta_1tobeta_T. Elementt - 1is .alpha_bars(betas): for , same indexing.q_sample(x0, t, noise, abar): for an integer step , usingabar[t - 1].simple_loss(eps_pred, noise): the mean squared error between the predicted and the true noise, over all elements.
Requirements
- Steps are numbered from 1 as in the paper; arrays are indexed from 0. Mind the shift.
- No loops:
np.cumprodcomputes the running product.