Skip to main content
Open In Colab In the EM for MoG tutorial you saw the Expectation-Maximization algorithm fit a Mixture of Gaussians: given data, recover the three component means, covariances, and weights. Here you do the opposite. You generate new samples from the same MoG using Denoising Diffusion Probabilistic Models (DDPM, Ho et al. 2020), without ever telling the model that the target distribution has three components, or what their parameters are. The model only sees data points and must learn to produce more. The 2D MoG is the cleanest place to build intuition: every step of the forward and reverse processes can be plotted directly. The same recipe scales to images, audio, and trajectories by swapping the small MLP below for a U-Net and using more diffusion steps.

The target distribution

Same three-cluster MoG as the EM tutorial: 100 points each from three anisotropic Gaussians with random seed 42. To DDPM, this is just a tensor of 300 points in R2\mathbb{R}^2, it has no idea three Gaussians produced it.
Output from cell 2

The forward (noising) process

DDPM defines a fixed Markov chain that gradually adds Gaussian noise to a data point until, after TT steps, it is indistinguishable from pure noise: q(xtxt1)=N ⁣(xt;  1βtxt1,  βtI)q(x_t \mid x_{t-1}) = \mathcal{N}\!\left(x_t;\; \sqrt{1-\beta_t}\, x_{t-1},\; \beta_t I\right) β1,,βT\beta_1, \dots, \beta_T is the variance schedule. With αt=1βt\alpha_t = 1 - \beta_t and αˉt=s=1tαs\bar\alpha_t = \prod_{s=1}^t \alpha_s, the chain has a closed-form jump from any x0x_0 directly to xtx_t: q(xtx0)=N ⁣(xt;  αˉtx0,  (1αˉt)I)q(x_t \mid x_0) = \mathcal{N}\!\left(x_t;\; \sqrt{\bar\alpha_t}\, x_0,\; (1-\bar\alpha_t) I\right) This shortcut is what makes DDPM training cheap: you never simulate the chain step by step during training, you sample tt, jump straight to xtx_t, and learn from there.
Output from cell 4

The reverse (denoising) process

Generation is the forward process run backwards. We learn a Gaussian transition pθ(xt1xt)=N ⁣(xt1;  μθ(xt,t),  σt2I)p_\theta(x_{t-1} \mid x_t) = \mathcal{N}\!\left(x_{t-1};\; \mu_\theta(x_t, t),\; \sigma_t^2 I\right) Ho et al. reparameterize the mean by training a network ϵθ(xt,t)\epsilon_\theta(x_t, t) to predict the noise that was added when producing xtx_t from x0x_0. The mean is then μθ(xt,t)=1αt(xt1αt1αˉtϵθ(xt,t))\mu_\theta(x_t, t) = \frac{1}{\sqrt{\alpha_t}} \left( x_t - \frac{1-\alpha_t}{\sqrt{1-\bar\alpha_t}}\, \epsilon_\theta(x_t, t) \right) and the entire variational lower bound collapses to a simple denoising objective: Lsimple=Ex0,t,ϵ ⁣[ϵϵθ ⁣(αˉtx0+1αˉtϵ,  t)2]L_{\text{simple}} = \mathbb{E}_{x_0, t, \epsilon}\!\left[\,\left\| \epsilon - \epsilon_\theta\!\left(\sqrt{\bar\alpha_t}\, x_0 + \sqrt{1-\bar\alpha_t}\, \epsilon,\; t\right) \right\|^2\,\right] No KL divergence to manage, no encoder, no posterior approximation, pure regression on noise.

The noise predictor

For 2D data, ϵθ\epsilon_\theta is a small MLP. The only non-obvious piece is the time embedding: the network must condition on which timestep tt we are denoising. The conventional trick is sinusoidal positional features (same idea as transformers).

Training

The training loop is one of the simplest in modern generative modeling:
  1. Sample a batch from pdatap_{\text{data}}.
  2. Sample a random timestep tUniform(1,T)t \sim \text{Uniform}(1, T) for each example.
  3. Sample noise ϵN(0,I)\epsilon \sim \mathcal{N}(0, I) and form xtx_t via the closed-form forward jump.
  4. Predict ϵ^=ϵθ(xt,t)\hat\epsilon = \epsilon_\theta(x_t, t).
  5. Minimize ϵϵ^2\|\epsilon - \hat\epsilon\|^2.
That is the whole algorithm.
Output from cell 7

Sampling: the reverse process in action

Now run the chain backwards. Start with xTN(0,I)x_T \sim \mathcal{N}(0, I) and, for t=T,T1,,1t = T, T-1, \dots, 1, take a step: xt1=1αt ⁣(xt1αt1αˉtϵθ(xt,t))+σtzx_{t-1} = \frac{1}{\sqrt{\alpha_t}}\!\left( x_t - \frac{1-\alpha_t}{\sqrt{1-\bar\alpha_t}}\, \epsilon_\theta(x_t, t)\right) + \sigma_t z with zN(0,I)z \sim \mathcal{N}(0, I) for t>1t > 1 and z=0z = 0 at the final step. The standard variance choice is σt=βt\sigma_t = \sqrt{\beta_t}.
Output from cell 9

Did it work?

Compare the generated samples to the original training data. The model never learned that there are three components, that they are Gaussian, or where their centers are, it only saw 300 data points and a noise-prediction objective. If the three clusters reappear in the generated cloud, the diffusion model has captured the data distribution. Output from cell 10

Connections to other concepts

  • Black-box density modeling. DDPM treats pdatap_{\text{data}} as opaque. Compare with EM, which assumes a parametric mixture form and fits its parameters.
  • Same recipe, bigger backbone. Replace the 4-layer MLP with a U-Net and the same noise-prediction objective generates 256×256 images. The schedule, the closed-form forward jump, and the training loop do not change.
  • Conditional and guided generation. Condition ϵθ(xt,t,y)\epsilon_\theta(x_t, t, y) on a label, prompt, or class to obtain conditional models, and combine with classifier-free guidance to trade diversity for fidelity.
  • Latent diffusion. Run the entire chain inside a learned latent space (encode → diffuse in latents → decode) for orders-of-magnitude faster image generation.
  • Score-based unification. The Score MoG Tutorial trains sθ(x,σ)s_\theta(x, \sigma) directly, a network that approximates logpσ(x)\nabla \log p_\sigma(x). DDPM’s noise predictor ϵθ(xt,t)\epsilon_\theta(x_t, t) is, up to a known scaling, a score predictor at the variance-preserving SDE. Same network, different parameterization.
  • Faster, deterministic sampling. The DDIM tutorial reuses this same trained model with a different sampler that takes a fraction of the steps and is deterministic, opening the door to latent interpolation and editing.

References

  1. Ho, Jain, Abbeel. Denoising Diffusion Probabilistic Models. NeurIPS 2020. arxiv.org/abs/2006.11239
  2. Sohl-Dickstein et al. Deep Unsupervised Learning using Nonequilibrium Thermodynamics. ICML 2015. arxiv.org/abs/1503.03585
  3. Nichol, Dhariwal. Improved Denoising Diffusion Probabilistic Models. ICML 2021. arxiv.org/abs/2102.09672

PyTorch reference