Level 3 — ProductionGenerative Models

Generative Models

45 minutes60 marksprintable — key stays hidden on paper

Chapter: 4.5 Generative Models Difficulty: Level 3 — Production (from-scratch derivations, code-from-memory, explain-out-loud) Time limit: 45 minutes Total marks: 60


Question 1 — ELBO Derivation from Scratch (12 marks)

Starting from the marginal log-likelihood logpθ(x)\log p_\theta(x) with latent variable zz and an approximate posterior qϕ(zx)q_\phi(z\mid x):

(a) Derive the Evidence Lower Bound (ELBO), showing every algebraic step, and prove that logpθ(x)=ELBO+DKL(qϕ(zx)pθ(zx))\log p_\theta(x) = \text{ELBO} + D_{KL}(q_\phi(z\mid x)\,\|\,p_\theta(z\mid x)). (6)

(b) Explain why maximizing the ELBO is a valid surrogate for maximizing logpθ(x)\log p_\theta(x), and what the gap between them represents. (3)

(c) Write the ELBO in its "reconstruction + regularization" decomposed form and name each term. (3)


Question 2 — Reparameterization Trick (10 marks)

(a) For a Gaussian posterior qϕ(zx)=N(z;μϕ(x),σϕ2(x))q_\phi(z\mid x) = \mathcal{N}(z;\mu_\phi(x), \sigma^2_\phi(x)), write the reparameterized sample zz in terms of μ\mu, σ\sigma and a noise variable ϵ\epsilon. State the distribution of ϵ\epsilon. (3)

(b) Explain out loud (in words) why the naive Monte-Carlo gradient ϕEqϕ[f(z)]\nabla_\phi \mathbb{E}_{q_\phi}[f(z)] is problematic to estimate, and how reparameterization fixes it. (4)

(c) Derive the closed-form KL term DKL(N(μ,σ2)N(0,1))D_{KL}(\mathcal{N}(\mu,\sigma^2)\,\|\,\mathcal{N}(0,1)) for a single dimension. (3)


Question 3 — GAN Objective & Optimal Discriminator (12 marks)

Given the minimax GAN value function minGmaxDV(D,G)=Expdata[logD(x)]+Ezpz[log(1D(G(z)))].\min_G \max_D V(D,G) = \mathbb{E}_{x\sim p_{data}}[\log D(x)] + \mathbb{E}_{z\sim p_z}[\log(1 - D(G(z)))].

(a) Derive the optimal discriminator D(x)D^*(x) for a fixed generator GG. (5)

(b) Substitute DD^* back into VV and show the generator objective reduces to 2DJS(pdatapg)log42\cdot D_{JS}(p_{data}\|p_g) - \log 4. (5)

(c) From this result, explain why mode collapse and vanishing generator gradients can occur, and one concrete fix (e.g. WGAN). (2)


Question 4 — DDPM Forward Process (10 marks)

The DDPM forward process is q(xtxt1)=N(xt;1βtxt1,βtI)q(x_t\mid x_{t-1}) = \mathcal{N}(x_t; \sqrt{1-\beta_t}\,x_{t-1}, \beta_t I).

(a) Derive the closed-form marginal q(xtx0)q(x_t\mid x_0) in terms of αˉt=s=1t(1βs)\bar\alpha_t = \prod_{s=1}^{t}(1-\beta_s). Show the recursion collapse. (6)

(b) Write xtx_t as a reparameterized function of x0x_0 and ϵN(0,I)\epsilon\sim\mathcal{N}(0,I). (2)

(c) State what happens to q(xTx0)q(x_T\mid x_0) as TT\to\infty and why this matters for sampling. (2)


Question 5 — Code from Memory: VAE Loss (8 marks)

Write a PyTorch-style function vae_loss(x, x_recon, mu, logvar) that returns the negative ELBO (reconstruction + KL). Use logvar =logσ2=\log\sigma^2. Assume binary cross-entropy reconstruction. Comment each line explaining the term it implements. (8)


Question 6 — Explain Out Loud: Evaluation & Guidance (8 marks)

(a) Explain the Fréchet Inception Distance (FID) formula and what each of its two terms measures. Why is lower better? (4)

(b) Explain classifier-free guidance: write the guided noise prediction combining conditional and unconditional predictions, and describe the effect of the guidance scale ww. (4)

Answer keyMark scheme & solutions

Question 1 (12 marks)

(a) Start with marginal, multiply/divide by qϕq_\phi: (6) logpθ(x)=logpθ(x,z)dz=logEqϕ(zx)[pθ(x,z)qϕ(zx)]\log p_\theta(x) = \log \int p_\theta(x,z)\,dz = \log \mathbb{E}_{q_\phi(z|x)}\left[\frac{p_\theta(x,z)}{q_\phi(z|x)}\right] By Jensen's inequality (log is concave): (1) Eqϕ[logpθ(x,z)qϕ(zx)]=ELBO.(1)\geq \mathbb{E}_{q_\phi}\left[\log \frac{p_\theta(x,z)}{q_\phi(z|x)}\right] = \text{ELBO}. \quad (1) Exact identity: write pθ(x,z)=pθ(zx)pθ(x)p_\theta(x,z)=p_\theta(z|x)p_\theta(x): (2) logpθ(x)=Eqϕ ⁣[logpθ(x,z)qϕ(zx)]+Eqϕ ⁣[logqϕ(zx)pθ(zx)]\log p_\theta(x) = \mathbb{E}_{q_\phi}\!\left[\log\frac{p_\theta(x,z)}{q_\phi(z|x)}\right] + \mathbb{E}_{q_\phi}\!\left[\log\frac{q_\phi(z|x)}{p_\theta(z|x)}\right] =ELBO+DKL(qϕ(zx)pθ(zx)).(2)= \text{ELBO} + D_{KL}(q_\phi(z|x)\|p_\theta(z|x)). \quad (2)

(b) Since DKL0D_{KL}\geq 0, ELBO logpθ(x)\leq \log p_\theta(x) always (1). Maximizing ELBO pushes the lower bound up; the true posterior pθ(zx)p_\theta(z|x) is intractable so we can't optimize likelihood directly (1). The gap equals the KL between approximate and true posterior — tightness of the bound; zero gap means qϕq_\phi matches the true posterior exactly (1).

(c) (3) ELBO=Eqϕ(zx)[logpθ(xz)]reconstruction (1)DKL(qϕ(zx)p(z))regularization / prior-matching (1)\text{ELBO} = \underbrace{\mathbb{E}_{q_\phi(z|x)}[\log p_\theta(x|z)]}_{\text{reconstruction (1)}} - \underbrace{D_{KL}(q_\phi(z|x)\|p(z))}_{\text{regularization / prior-matching (1)}} Reconstruction rewards accurate decoding; KL keeps latent code close to prior (1).


Question 2 (10 marks)

(a) z=μϕ(x)+σϕ(x)ϵz = \mu_\phi(x) + \sigma_\phi(x)\odot\epsilon, where ϵN(0,I)\epsilon\sim\mathcal{N}(0,I). (3)

(b) The expectation is over qϕq_\phi which depends on ϕ\phi; the sampling operation is not differentiable w.r.t. ϕ\phi (2). The score-function/REINFORCE estimator works but has high variance (1). Reparameterization moves stochasticity to ϵ\epsilon (independent of ϕ\phi), making zz a deterministic differentiable function of ϕ\phi, so ϕ\nabla_\phi passes through and gives a low-variance pathwise estimator (1).

(c) Single-dim KL: (3) DKL=N(μ,σ2)logN(μ,σ2)N(0,1)D_{KL} = \int \mathcal{N}(\mu,\sigma^2)\log\frac{\mathcal{N}(\mu,\sigma^2)}{\mathcal{N}(0,1)} =12(1+logσ2μ2σ2)=12(μ2+σ2logσ21).= -\tfrac12\left(1 + \log\sigma^2 - \mu^2 - \sigma^2\right) = \tfrac12(\mu^2 + \sigma^2 - \log\sigma^2 - 1). (Steps: expand log-ratio, take Gaussian moments E[z]=μ\mathbb{E}[z]=\mu, E[z2]=μ2+σ2\mathbb{E}[z^2]=\mu^2+\sigma^2.)


Question 3 (12 marks)

(a) For fixed GG, maximize integrand pointwise: (5) V=x[pdata(x)logD(x)+pg(x)log(1D(x))]dx.V = \int_x \left[p_{data}(x)\log D(x) + p_g(x)\log(1-D(x))\right]dx. For alogD+blog(1D)a\log D + b\log(1-D), set derivative aDb1D=0D=aa+b\frac{a}{D}-\frac{b}{1-D}=0 \Rightarrow D^* = \frac{a}{a+b}. So D(x)=pdata(x)pdata(x)+pg(x).(5)D^*(x) = \frac{p_{data}(x)}{p_{data}(x)+p_g(x)}. \quad (5)

(b) Substitute: (5) V(D,G)=Epdata ⁣[logpdatapdata+pg]+Epg ⁣[logpgpdata+pg].V(D^*,G) = \mathbb{E}_{p_{data}}\!\left[\log\frac{p_{data}}{p_{data}+p_g}\right] + \mathbb{E}_{p_g}\!\left[\log\frac{p_g}{p_{data}+p_g}\right]. Add/subtract log2\log 2 in each: =log4+DKL ⁣(pdatapdata+pg2)+DKL ⁣(pgpdata+pg2)= -\log 4 + D_{KL}\!\left(p_{data}\Big\|\tfrac{p_{data}+p_g}{2}\right) + D_{KL}\!\left(p_g\Big\|\tfrac{p_{data}+p_g}{2}\right) =log4+2DJS(pdatapg).= -\log 4 + 2\,D_{JS}(p_{data}\|p_g). Global minimum when pg=pdatap_g = p_{data}, giving V=log4V = -\log 4.

(c) When supports don't overlap, JS is constant log2\log 2 → gradient vanishes, generator gets no signal → mode collapse (generator maps to few modes to fool DD) (1). Fix: WGAN uses Earth-Mover distance (with weight clipping / gradient penalty) giving smooth, non-vanishing gradients everywhere (1).


Question 4 (10 marks)

(a) Let αt=1βt\alpha_t = 1-\beta_t. Recursively: (6) xt=αtxt1+1αtϵt1x_t = \sqrt{\alpha_t}\,x_{t-1} + \sqrt{1-\alpha_t}\,\epsilon_{t-1} Substitute xt1=αt1xt2+1αt1ϵt2x_{t-1}=\sqrt{\alpha_{t-1}}x_{t-2}+\sqrt{1-\alpha_{t-1}}\epsilon_{t-2}: xt=αtαt1xt2+αt(1αt1)ϵt2+1αtϵt1.x_t = \sqrt{\alpha_t\alpha_{t-1}}\,x_{t-2} + \sqrt{\alpha_t(1-\alpha_{t-1})}\epsilon_{t-2} + \sqrt{1-\alpha_t}\epsilon_{t-1}. Sum of two independent Gaussians → variance adds: αt(1αt1)+(1αt)=1αtαt1\alpha_t(1-\alpha_{t-1}) + (1-\alpha_t) = 1-\alpha_t\alpha_{t-1} (2). Repeating: q(xtx0)=N ⁣(xt;αˉtx0, (1αˉt)I),αˉt=s=1tαs.(2)q(x_t\mid x_0) = \mathcal{N}\!\left(x_t; \sqrt{\bar\alpha_t}\,x_0,\ (1-\bar\alpha_t)I\right),\quad \bar\alpha_t=\prod_{s=1}^t \alpha_s. \quad (2)

(b) xt=αˉtx0+1αˉtϵ,ϵN(0,I)x_t = \sqrt{\bar\alpha_t}\,x_0 + \sqrt{1-\bar\alpha_t}\,\epsilon,\quad \epsilon\sim\mathcal{N}(0,I). (2)

(c) As TT\to\infty, αˉT0\bar\alpha_T\to 0 so q(xTx0)N(0,I)q(x_T\mid x_0)\to\mathcal{N}(0,I) — independent of x0x_0 (1). This lets sampling begin from pure Gaussian noise then run the learned reverse process (1).


Question 5 (8 marks)

import torch.nn.functional as F
 
def vae_loss(x, x_recon, mu, logvar):
    # reconstruction term: -E[log p(x|z)] via BCE, summed over pixels
    recon = F.binary_cross_entropy(x_recon, x, reduction='sum')
    # KL(N(mu,sigma^2)||N(0,1)) = 0.5*sum(mu^2 + sigma^2 - logvar - 1)
    kl = 0.5 * torch.sum(mu.pow(2) + logvar.exp() - logvar - 1)
    # negative ELBO = reconstruction + KL regularizer
    return recon + kl

Marks: correct BCE recon (2), correct KL formula matching Q2c (3), sign/sum correct (2), comments (1).


Question 6 (8 marks)

(a) FID: (4) FID=μrμg2+Tr ⁣(Σr+Σg2(ΣrΣg)1/2).\text{FID} = \|\mu_r - \mu_g\|^2 + \text{Tr}\!\left(\Sigma_r + \Sigma_g - 2(\Sigma_r\Sigma_g)^{1/2}\right). Computed on Inception activations. First term = squared distance between mean feature vectors (measures difference in average content) (1); second term = covariance mismatch (measures difference in feature diversity/spread) (1). It is the Fréchet (Wasserstein-2) distance between two Gaussians fit to real/generated features (1). Lower = generated distribution closer to real → better quality & diversity (1).

(b) Guided prediction: (4) ϵ~θ(xt,c)=ϵθ(xt,)+w(ϵθ(xt,c)ϵθ(xt,)).\tilde\epsilon_\theta(x_t,c) = \epsilon_\theta(x_t,\varnothing) + w\big(\epsilon_\theta(x_t,c) - \epsilon_\theta(x_t,\varnothing)\big). ϵθ(xt,)\epsilon_\theta(x_t,\varnothing) = unconditional prediction (condition dropped during training) (1); the difference is the "conditional direction" (1). w=0w=0 → unconditional; w=1w=1 → standard conditional; w>1w>1 amplifies conditioning → sharper prompt adherence but reduced diversity / possible artifacts (2).


[
  {"claim": "KL(N(mu,sigma^2)||N(0,1)) = 0.5*(mu^2+sigma^2-log(sigma^2)-1)",
   "code": "mu,s=symbols('mu s',positive=True); z=symbols('z'); import sympy as sp; p=1/sp.sqrt(2*pi*s**2)*sp.exp(-(z-mu)**2/(2*s**2)); q=1/sp.sqrt(2*pi)*sp.exp(-z**2/2); kl=sp.integrate(p*sp.log(p/q),(z,-oo,oo)); target=sp.Rational(1,2)*(mu**2+s**2-sp.log(s**2)-1); result=sp.simplify(kl-target)==0"},
  {"claim": "Optimal GAN value equals -log4 + 2*JSD at p_g=p_data i.e. min value = -log(4)",
   "code": "a=symbols('a',positive=True); Dstar=a/(a+a); val=a*sp.log(Dstar)+a*sp.log(1-Dstar); result=sp.simplify(2*val - (-sp.log(4)))==0"},
  {"claim": "DDPM variance recursion: alpha_t*(1-alpha_{t-1})+(1-alpha_t) = 1-alpha_t*alpha_{t-1}",
   "code": "at,a1=symbols('at a1'); lhs=at*(1-a1)+(1-at); rhs=1-at*a1; result=sp.simplify(lhs-rhs)==0"},
  {"claim": "Classifier-free guidance at w=1 reduces to conditional prediction",
   "code": "e_c,e_u,w=symbols('e_c e_u w'); g=e_u+w*(e_c-e_u); result=sp.simplify(g.subs(w,1)-e_c)==0"}
]