Hoppa till innehållet
AI-grafen
F· AI engineeringgenerativa-modeller· ca 90 min· utvecklande· verifierad 2026-09-20

Diffusionsmodeller

Kunna förklara framåt- och bakåtprocessen, träna en liten diffusionsmodell och generera bilder.

Förkunskaper

Intuition

Framåtprocessen förstör en bild: lägg till lite gaussiskt brus, om och om igen, i T steg tills bara brus återstår. Den är fast och kräver ingen inlärning.

Bakåtprocessen är det modellen lär sig: givet en brusig bild vid steg t, förutsäg bruset som lades till. Kan man det, kan man ta ett steg tillbaka mot en renare bild. Upprepa från rent brus och en bild växer fram.

Träningen är förvånansvärt enkel: dra en bild, dra ett slumpmässigt t, lägg på motsvarande brus, låt nätet gissa bruset, och mät med MSE. Ingen diskriminator, ingen instabilitet — det är därför diffusion slog GAN.

Formellt

Framåt: q(xt∣xt−1)=N(1−βt xt−1, βtI)q(x_t\mid x_{t-1}) = \mathcal N(\sqrt{1-\beta_t}\,x_{t-1},\ \beta_t I). Med αt=1−βt\alpha_t = 1-\beta_t och αˉt=∏s≤tαs\bar\alpha_t = \prod_{s\le t}\alpha_s kan man hoppa direkt till valfritt steg: xt=αˉt x0+1−αˉt ϵ,ϵ∼N(0,I)x_t = \sqrt{\bar\alpha_t}\,x_0 + \sqrt{1-\bar\alpha_t}\,\epsilon,\qquad \epsilon\sim\mathcal N(0,I)

Träningsmål (Ho m.fl. 2020) — förvånansvärt nog bara en MSE: L=Ex0,ϵ,t[∥ϵ−ϵθ(xt,t)∥2]\mathcal L = \mathbb E_{x_0,\epsilon,t}\big[\|\epsilon - \epsilon_\theta(x_t, t)\|^2\big]

Sampling: starta i xT∼N(0,I)x_T\sim\mathcal N(0,I) och iterera bakåt. DDPM använder alla T steg (ofta 1 000); DDIM gör processen deterministisk och klarar 20–50 steg med nästan samma kvalitet.

Classifier-free guidance: träna modellen både med och utan textvillkor (villkoret slumpas bort i ~10 % av fallen) och extrapolera vid sampling: ϵ^=ϵθ(xt,∅)+w(ϵθ(xt,c)−ϵθ(xt,∅))\hat\epsilon = \epsilon_\theta(x_t,\varnothing) + w\big(\epsilon_\theta(x_t,c) - \epsilon_\theta(x_t,\varnothing)\big) Högre ww ger starkare följsamhet mot prompten men mindre variation — den parameter användare känner som «guidance scale».

Latent diffusion (Stable Diffusion) kör hela processen i ett komprimerat latent rum från en autoencoder, vilket sänker beräkningen ~50× och är varför bildgenerering går på konsumenthårdvara.

Kod

import torch, torch.nn as nn

T = 1000
betas = torch.linspace(1e-4, 0.02, T)
alphas = 1.0 - betas
abar = torch.cumprod(alphas, dim=0)

def brusa(x0, t, eps=None):
    """Hoppa direkt till steg t."""
    eps = torch.randn_like(x0) if eps is None else eps
    a = abar[t].view(-1, 1, 1, 1)
    return a.sqrt() * x0 + (1 - a).sqrt() * eps, eps

def traningssteg(modell, x0, opt):
    t = torch.randint(0, T, (x0.size(0),))
    xt, eps = brusa(x0, t)
    loss = nn.functional.mse_loss(modell(xt, t), eps)     # förutsäg bruset
    loss.backward(); opt.step(); opt.zero_grad()
    return loss.item()

@torch.no_grad()
def sampla(modell, form, steg=50):
    x = torch.randn(form)
    for t in reversed(range(0, T, T // steg)):            # DDIM-liknande hopp
        tt = torch.full((form[0],), t, dtype=torch.long)
        eps = modell(x, tt)
        a = abar[t]
        x0_hat = (x - (1 - a).sqrt() * eps) / a.sqrt()
        a_prev = abar[max(t - T // steg, 0)]
        x = a_prev.sqrt() * x0_hat + (1 - a_prev).sqrt() * eps
    return x

Behärskning innebär

  • Förklarar framåt- och bakåtprocessen
  • Beskriver träningsmålet (förutsäg bruset)
  • Förstår styrning och samplingssteg

Logga in för att göra övningarna och bygga upp din behärskning.

Källor

Alla källor och licenser