Diffusion: from noise to image
How is an image created by removing noise step by step?
Lesson complete
If you like:
This is static: sixty-four random pixels. Watch closely: in a few seconds, a tiny network turns it into a seven that never existed.
No voice: the lesson advances on its own with subtitles.
The voice for this lesson is being recorded: for now it advances on its own with subtitles.
Review modeComment on this stepI finished the lesson
What you will achieve
- Explain the forward process (mixing an image with noise, step by step, until only static is left) and why undoing it in one jump is impossible but in many small steps is not.
- Describe, piece by piece, what the network in a diffusion model takes in and returns (noisy image and step → estimated noise) and how generation starts from pure static.
- Recognize what classifier-free guidance does (exaggerating the hint, at the cost of variety) and what latent diffusion does (diffusing in a space of codes, which is far cheaper).
Key ideas
- The forward process mixes an image with noise, step by step, on a fixed schedule, until only static is left. It learns nothing, and in the end every image ends up as the same kind of static, which is easy to make.
- Undoing the noise in one jump is impossible: the same static could have come from any image, and the best possible guess is a blurry average. A small step, by contrast, can be estimated.
- The network takes the noisy image and the step number, and estimates the noise. It is trained on examples that never run out: we make the noise ourselves, so we know the answer.
- Generating means starting from pure static and removing a little of the estimated noise, many times. Different static gives a different result: nothing was stored.
- Classifier-free guidance exaggerates the difference between the estimate with the hint and without it: more fidelity, less variety. Latent diffusion does all of this in a much smaller space of codes and decodes at the end; that is how Stable Diffusion works.
What many people believe
Common belief The network “cleans up” an image that was already hidden in the static: it just uncovers it.
What is true There is no image in the static. Step by step, the network decides what drawing is plausible given what it learned from the data; with different static, or a different hint, a different drawing comes out.
Check yourself
Four questions. No grade, no account: they just show whether the idea stuck.
Under the hoodFor those who want the math and the code. You do not need it to follow the course.
The forward process
With a noise schedule , let and . Each step is , and chaining them gives a closed form for any step:
The lesson’s bar shows (the share of the mix’s “energy” that is still image) and (the share that is noise). The lesson uses and the cosine schedule of Nichol and Dhariwal (2021), with , clipping each to at most 0.35 (with so few steps, the last cosine values approach 1). So is 0.899 at step 10, 0.494 at 25, 0.094 at 40, and 0.003 at 50. Pixels are first mapped to the range ; on screen they are clipped to .
Why not in one jump
The network is trained with squared error, and what minimizes squared error is the conditional mean . At the static keeps almost no information, so : the average of all the digits, the lesson’s smudge. By contrast, if each is small, the reverse step is nearly Gaussian, with the same form as the forward step (Sohl-Dickstein et al., 2015, citing Feller, 1949): estimating its mean is enough.
What the network learns and how it is trained
The network estimates the noise. The simplified loss of Ho et al. (2020) is
Thanks to the closed form, training does not need to walk through the steps: it jumps straight to a random . The lesson’s pixel network has 53,056 parameters (three layers of 128 neurons with residual connections and SiLU; inputs: the 64 pixels, 16 numbers encoding the step, and the label in 11 slots, the last one meaning “no hint”) and was trained for 30,000 rounds with batches of 256 images: 7,680,000 noisy versions of lesson 15’s 1,500 training digits. With the seven at step 20, its noise estimate has a mean squared error of 0.135 per pixel; if it said “there is no noise,” the error would be 0.864.
Sampling
DDPM’s original sampler starts from and, for , computes
with a little fresh noise at each step (except the last). The scene uses the deterministic variant of Song et al. (2021), DDIM with , with the same network trained as in DDPM:
That is: the noise estimate gives the clean image it implies, which is then mixed again with the share of noise that belongs to the previous step. With no fresh noise, each point on the plane follows its arrow exactly and the same static always gives the same result; different static gives a different one.
Classifier-free guidance
A single network is trained with the label and, with probability 0.15, without it (). When sampling, they are combined:
With it is the estimate without the hint (the hint is ignored); with , the conditional, which follows the hint as is; with the hint’s direction is exaggerated. It is the same convention as in lesson 18. Ho and Salimans (2022) write the same with : . Each guided step costs two network evaluations. On the lesson’s plane, with the hint “seven” and two hundred points (reader: lesson 15’s logistic regression), 26 are read as sevens with , 199 with , and 200 with . At the same time, the real sevens left with no new point within 0.3 number 4 of 154 with , 48 with , 95 with , and 144 with : the points crowd onto the edge of the group farthest from the other digits. The pixel network generates its sevens with .
Latent diffusion
An autoencoder compresses the image into a code ; diffusion happens in and at the end is decoded (Rombach et al., 2022). In the lesson, is the two numbers of lesson 15’s VAE, multiplied by 1.6 before diffusing (Stable Diffusion also rescales its codes by a fixed factor), and the plane network has 10,370 parameters. In Stable Diffusion v1, the autoencoder shrinks each side 8 times and outputs 4 channels: a -number image becomes a -number code, 48 times fewer.
In code
import numpy as np
T, s = 50, 0.008
f = lambda t: np.cos((t / T + s) / (1 + s) * np.pi / 2) ** 2
a_full = f(np.arange(T + 1)) / f(0)
betas = np.clip(1 - a_full[1:] / a_full[:-1], 1e-4, 0.35) # noise schedule
alphas = 1 - betas
abar = np.cumprod(alphas)
print('image share of the mix (%):', [round(float(100 * abar[t - 1]), 1) for t in (10, 25, 40, 50)])
# Toy data: a single number that is -1 or +1. For it, the best possible
# noise estimator can be written by hand (in the lesson a network learns it).
def estimated_noise(x, i):
a, b = np.sqrt(abar[i]), np.sqrt(1 - abar[i])
x0 = np.tanh(a * x / b**2) # mean of x0 given x_t
return (x - a * x0) / b
rng = np.random.default_rng(0)
x = rng.standard_normal(10_000) # pure static
for i in reversed(range(T)): # fifty steps back (DDPM)
e = estimated_noise(x, i)
x = (x - betas[i] / np.sqrt(1 - abar[i]) * e) / np.sqrt(alphas[i])
if i > 0:
x += np.sqrt(betas[i]) * rng.standard_normal(x.size)
print('within 0.1 of -1 or +1:', round(float(np.mean(np.abs(np.abs(x) - 1) < 0.1)), 3))
print('share at +1:', round(float(np.mean(x > 0)), 3))
# image share of the mix (%): [89.9, 49.4, 9.4, 0.3]
# within 0.1 of -1 or +1: 1.0
# share at +1: 0.499
What comes next
Lesson 18 shows how a sentence becomes the hint that guides diffusion (CLIP and text conditioning). Later on, the transformer (lessons 21 and 22) replaces the convolutional network in many modern diffusion models.
Decision lens
What this idea means if your job is to decide, not to code.
- The cost of generating is steps × network evaluations × images. Classifier-free guidance doubles the evaluations per step: for large campaigns, estimate the volume and compare setups with fewer steps or lower resolution.
- The guidance scale is a business dial: higher gives results more faithful to the request, but more alike. Try several scales on your own cases before settling on one.
- Apparent quality is deceiving: check details (text inside the image, hands, logos) and keep human review before publishing.
- These models learn from large collections of real images: ask the vendor where the data comes from, what licenses cover it, and what usage and synthetic-image labeling policy it offers.
Terms in this lesson
- Generative model A model that learns the distribution of its data (what is common, what is rare) and can therefore produce new, similar data. A model that classifies, by contrast, only learns the boundary between groups.
- Distribution The way the data is spread out: which values (or combinations of values) are common, which are rare, and which never appear. With two measures it looks like a cloud of points.
- Sampling Drawing a new data point that follows a distribution: common things come out often and rare things seldom. It is how a generative model generates. (Not to be confused with the audio samples of lesson 2.)
- Autoencoder A two-piece network: an encoder, which sums up each data point in a few numbers (the code), and a decoder, which tries to rebuild it from the code. It is trained to bring the reconstruction error down.
- Latent space The space of a model’s codes (“latent” means hidden): each data point is a point, and nearby points tend to be similar data. Any point can be decoded.
- Variational autoencoder (VAE) An autoencoder that sums up each data point as a cloud (center and size) instead of a point, and penalizes clouds that stray from a standard zone. That way the latent space has no holes and you can sample from it.
- Pixel The smallest dot of a digital image. In grayscale it is a number from 0 (black) to 255 (white); in color it is three numbers (red, green, and blue).
- Loss function A single number that summarizes how wrong a model is on its data. Training is the search for the parameters that make it as small as possible.
- Mean squared error (MSE) A loss that averages the squared errors. It punishes big errors far more than small ones and is measured in the units of the output, squared.
- Gradient descent A method that adjusts the weights step by step, always against the slope of the error (the gradient), until it reaches a bottom.
- Training data Examples, each with its correct answer, from which a model adjusts its parameters.
- Diffusion model A generative model that learns to undo a fixed process that mixes data with noise step by step (the forward process). It generates by starting from pure static and removing a little estimated noise, many times.
- Denoising The task of the network in a diffusion model: it takes a noisy image and the step number, and estimates the noise so it can be subtracted.
- Noise schedule The fixed recipe for how much noise is mixed in at each step of the forward process; it determines how much of the mix is still image at each step.
- Latent diffusion Doing diffusion in the code space of an autoencoder, much smaller than the image, and decoding at the end. It is cheaper; that is how Stable Diffusion works.
- Classifier-free guidance When generating, the noise estimate is computed with the hint (a label or a text) and without it, and their difference is exaggerated by the guidance scale: more fidelity to the hint, less variety.
Full transcript
Sources
- Alpaydin, E., Kaynak, C. (1998). Optical Recognition of Handwritten Digits (UCI Machine Learning Repository, CC BY 4.0; datos de los dígitos de 8 × 8)
- Sohl-Dickstein, J., Weiss, E. A., Maheswaranathan, N., Ganguli, S. (2015). Deep Unsupervised Learning using Nonequilibrium Thermodynamics (ICML 2015)
- Ho, J., Jain, A., Abbeel, P. (2020). Denoising Diffusion Probabilistic Models (NeurIPS 2020)
- Nichol, A., Dhariwal, P. (2021). Improved Denoising Diffusion Probabilistic Models (ICML 2021)
- Song, J., Meng, C., Ermon, S. (2021). Denoising Diffusion Implicit Models (ICLR 2021)
- Ho, J., Salimans, T. (2022). Classifier-Free Diffusion Guidance
- Rombach, R., Blattmann, A., Lorenz, D., Esser, P., Ommer, B. (2022). High-Resolution Image Synthesis with Latent Diffusion Models (CVPR 2022)
- Stability AI (2022). Stable Diffusion Public Release (anuncio, 22 de agosto de 2022)
- CompVis (2022). Stable Diffusion v1-4 Model Card
- Alpaydin, E., Kaynak, C. (1998). Optical Recognition of Handwritten Digits (UCI Machine Learning Repository)
CommentsThis lesson’s public conversation: questions, facts to check, ideas.
Comments live in GitHub Discussions, in the course’s public repository; writing one requires a GitHub account. They load from giscus.app when you open this section. The course reviewers read them, and if a change is accepted, it is applied in both languages. Open the thread on GitHub