4.5.8Generative Models

GAN training instability and mode collapse

3,281 words15 min readdifficulty · medium

Overview

Training GANs is notoriously difficult because we're trying to balance two networks playing a minimax game. The generator tries to fool the discriminator, while the discriminator tries to catch the generator's fakes. When this balance breaks, we get either training instability (wild oscillations, non-convergence) or mode collapse (generator produces limited variety).

Figure — GAN training instability and mode collapse

The Minimax Game: Why Balance Matters

where:

  • D(x)D(x) is the discriminator's probability that xx is real
  • G(z)G(z) generates a fake sample from noise zz
  • The discriminator DD tries to maximize VV (correctly classify real vs fake)
  • The generator GG tries to minimize VV (fool the discriminator)

Deriving the Training Instability from First Principles

Step 1: What does the discriminator optimize?

For fixed GG, the discriminator maximizes: V(D,G)=Expdata[logD(x)]+Expg[log(1D(x))]V(D,G) = \mathbb{E}_{x \sim p_{data}}[\log D(x)] + \mathbb{E}_{x \sim p_g}[\log(1 - D(x))]

where pgp_g is the generator's distribution.

Taking the functional derivative with respect to D(x)D(x) and setting to zero: δVδD(x)=pdata(x)D(x)pg(x)1D(x)=0\frac{\delta V}{\delta D(x)} = \frac{p_{data}(x)}{D(x)} - \frac{p_g(x)}{1-D(x)} = 0

Solving for the optimal discriminator: D(x)=pdata(x)pdata(x)+pg(x)D^*(x) = \frac{p_{data}(x)}{p_{data}(x) + p_g(x)}

Why this step? We're finding what discriminator outputs give maximum classification accuracy when both distributions are known. Notice that if pdata(x)=pg(x)p_{data}(x) = p_g(x) everywhere (perfect generator), then D(x)=12D^*(x) = \frac{1}{2} everywhere—the discriminator is reduced to random guessing.

Step 2: What gradient does the generator receive?

The generator optimizes by gradient descent on: Ezpz[log(1D(G(z)))]\mathbb{E}_{z \sim p_z}[\log(1 - D(G(z)))]

Using the chain rule, the gradient w.r.t. generator parameters θ\theta is: θEz[log(1D(G(z)))]=Ez[11D(G(z))xD(G(z))θG(z)]\nabla_\theta \mathbb{E}_z[\log(1 - D(G(z)))] = \mathbb{E}_z\left[\frac{-1}{1-D(G(z))} \cdot \nabla_x D(G(z)) \cdot \nabla_\theta G(z)\right]

Why this step? We need the gradient to update generator parameters θ\theta. Notice there are two factors that depend on the discriminator: the scalar 11D(G(z))\frac{-1}{1-D(G(z))} and the term xD(G(z))\nabla_x D(G(z)) (how the discriminator's output changes as we move the sample).

Step 3: The vanishing gradient problem (corrected)

When the discriminator is near-perfect, D(G(z))0D(G(z)) \approx 0 for fake samples. Let's examine both factors:

  1. The scalar factor: 11D(G(z))110=1\dfrac{-1}{1-D(G(z))} \approx \dfrac{-1}{1-0} = -1 — this is a constant, not small, so it does NOT cause the vanishing gradient by itself.

  2. The real culprit is xD(G(z))\nabla_x D(G(z)). A confident, well-trained discriminator has a saturated output: it outputs values very close to 00 (fake) or 11 (real) and is flat in between. A flat output means its input-gradient xD0\nabla_x D \to 0. So even though the scalar is 1-1, the whole product

(1)constantxD(G(z))0θG(z)    0\underbrace{(-1)}_{\text{constant}} \cdot \underbrace{\nabla_x D(G(z))}_{\to\, 0} \cdot \nabla_\theta G(z) \;\to\; 0

vanishes. The generator receives almost no learning signal.

Why this step? This corrects a common misconception: the gradient does not vanish because 11D\frac{-1}{1-D} shrinks (it approaches the constant 1-1). It vanishes because a too-confident discriminator saturates, making its input-derivative xD0\nabla_x D \to 0. When DD wins too hard, GG stops improving.

maxGEzpz[logD(G(z))]\max_G \mathbb{E}_{z \sim p_z}[\log D(G(z))]

Gradient becomes: θEz[logD(G(z))]=Ez[1D(G(z))xD(G(z))θG(z)]\nabla_\theta \mathbb{E}_z[\log D(G(z))] = \mathbb{E}_z\left[\frac{1}{D(G(z))} \cdot \nabla_x D(G(z)) \cdot \nabla_\theta G(z)\right]

Now when D(G(z))0D(G(z)) \approx 0, the scalar prefactor 1D(G(z))\frac{1}{D(G(z))} becomes large (1/0.001=10001/0.001 = 1000). This large prefactor amplifies the (small) saturated xD\nabla_x D, rescuing the learning signal that the original loss lost. This provides a stronger signal early in training.

Why this works: We inverted the problem—instead of minimizing "probability of being fake," we maximize "probability of being real." The two losses share the same fixed points but have very different gradient magnitudes when DD is confident.

Mode Collapse: The Copy-Paste Problem

Deriving Mode Collapse from Game Dynamics

Step 1: The generator's incentive structure

At iteration tt, suppose the generator has learned to produce sample x1x_1 that fools DD. The generator's loss for producing x1x_1 is: LG(x1)=logD(x1)L_G(x_1) = -\log D(x_1)

If D(x1)=0.9D(x_1) = 0.9 (discriminator thinks it's real), then LG=log(0.9)0.105L_G = -\log(0.9) \approx 0.105 (low loss, good!).

Step 2: What if the generator tries variety?

Now suppose the generator tries a different mode x2x_2 from the true distribution. But DD hasn't seen GG produce x2x_2 type samples before, so D(x2)=0.3D(x_2) = 0.3 (discriminator is suspicious).

LG(x2)=log(0.3)1.204L_G(x_2) = -\log(0.3) \approx 1.204

The loss is much higher! The generator is penalized for trying new modes.

Why this step? The generator's objective only cares about fooling DD right now, not about covering the full distribution.

Step 3: The discriminator can only punish current samples

The discriminator updates based on: LD=Expdata[logD(x)]Ez[log(1D(G(z)))]L_D = -\mathbb{E}_{x \sim p_{data}}[\log D(x)] - \mathbb{E}_{z}[\log(1-D(G(z)))]

If GG never produces samples from mode x2x_2, the discriminator never learns to check for that mode. The generator has no incentive to explore it.

Why this step? This is the core of mode collapse—GG exploits DD's blindness to unseen modes.

Iteration 1-100: Generator learns to produce digit "1" (easiest to generate, nearly straight line). Discriminator learns "1" is suspicious.

Iteration 101-200: Generator switches to producing digit "7" (also simple). Discriminator now focused on detecting "7", forgets about "1".

Iteration 201-300: Generator switches back to "1". Discriminator has drifted, doesn't recognize "1" anymore.

Result: Generator oscillates between 2-3 digit types, never learns the full distribution of 0-9. This is mode collapse.

Why this happens: The generator found that switching between a few modes is easier than covering all modes, and the discriminator can't "remember" all modes simultaneously.

Solution: WGAN uses a critic fw(x)f_w(x) that outputs a real number (no sigmoid), and optimizes the Wasserstein distance:

W(pdata,pg)=supfL1Expdata[f(x)]Expg[f(x)]W(p_{data}, p_g) = \sup_{\|f\|_L \leq 1} \mathbb{E}_{x \sim p_{data}}[f(x)] - \mathbb{E}_{x \sim p_g}[f(x)]

The critic is constrained to be 1-Lipschitz continuous (gradient clipping or gradient penalty).

Generator loss becomes: LG=Ez[fw(G(z))]L_G = -\mathbb{E}_z[f_w(G(z))]

Why this works:

  1. The critic provides non-vanishing gradients everywhere (no sigmoid saturation)
  2. The Wasserstein distance "pulls" the generator distribution toward the data distribution across all modes, not just currently visible ones
  3. Training is more stable because the objective correlates with sample quality

Detailed steps:

  1. Critic update (multiple steps per generator update): ww+αw[1mi=1mfw(x(i))1mi=1mfw(G(z(i)))]w \leftarrow w + \alpha \cdot \nabla_w \left[\frac{1}{m}\sum_{i=1}^m f_w(x^{(i)}) - \frac{1}{m}\sum_{i=1}^m f_w(G(z^{(i)}))\right] Then clip: wclip(w,c,c)w \leftarrow \text{clip}(w, -c, c) or apply gradient penalty

  2. Generator update: θθαθ[1mi=1mfw(G(z(i)))]\theta \leftarrow \theta - \alpha \cdot \nabla_\theta \left[-\frac{1}{m}\sum_{i=1}^m f_w(G(z^{(i)}))\right]

Why these steps: We're alternating between making the critic better at distinguishing (step 1) and making the generator better at fooling (step 2), but with continuous gradients throughout.

Common Training Instabilities

Why it feels right: "Both networks are equally important, so equal learning rates seem fair."

Why it's wrong: The discriminator's task (binary classification on already-generated samples) is easier than the generator's task (creating realistic samples from noise). With equal learning rates, DD typically learns much faster and becomes too strong.

The fix: Use a lower learning rate for DD than for GG, or train DD fewer times per GG update. Common ratio: train DD once per 1-3 GG updates (or use TTUR: Two Time-scale Update Rule with different learning rates for D and G in Adam).

Why it feels right: "When D(G(z))0D(G(z)) \to 0, surely some term in the gradient shrinks to zero and kills learning."

Why it's wrong: The scalar 11D(G(z))1\frac{-1}{1-D(G(z))} \to -1 is a constant, not small. The real cause is that a too-confident discriminator saturates, so its input-gradient xD(G(z))0\nabla_x D(G(z)) \to 0. The product vanishes because of the saturated derivative, not the scalar prefactor.

The fix: Use the non-saturating loss logD(G(z))\log D(G(z)) (whose prefactor 1D\frac{1}{D} blows up to counteract the small xD\nabla_x D), or switch to WGAN whose critic never saturates.

Why it feels right: "Batch norm stabilizes training in other deep networks, so it should help GANs."

Why it's wrong: Batch norm creates dependencies between samples in a batch. In the discriminator, this lets it detect fake batches (all fakes are correlated through BN statistics) vs real batches.

The fix:

  • Use Virtual Batch Normalization (VBN): normalize each sample using statistics from a fixed reference batch
  • Use Spectral Normalization instead: controls Lipschitz constant of layers without batch dependencies
  • Use Layer Normalization or Instance Normalization in generator

Advanced Stabilization Techniques

For a weight matrix WW in layer ll, divide by its spectral norm (largest singular value): Wˉ=Wσ(W)\bar{W} = \frac{W}{\sigma(W)}

where σ(W)=maxh=1Wh2\sigma(W) = \max_{\|h\|=1} \|Wh\|_2 is the spectral norm.

Why this works: This constrains the Lipschitz constant of each layer to be at most 1: fW(x)fW(y)xy\|f_W(x) - f_W(y)\| \leq \|x - y\|

The discriminator can't have extremely sharp transitions, which prevents mode collapse and stabilizes training.

How to compute efficiently: Use power iteration method:

  1. Initialize random vector vv
  2. Iterate: u=Wv/Wvu = Wv / \|Wv\|, v=WTu/WTuv = W^T u / \|W^T u\|
  3. After convergence: σ(W)uTWv\sigma(W) \approx u^T W v

Why this step: Computing exact SVD is O(n3)O(n^3); power iteration gives us σ(W)\sigma(W) in O(n2)O(n^2) per iteration, and we only need 1-2 iterations per training step.

Instead of weight clipping, add a penalty term: λEx^[(x^fw(x^)21)2]\lambda \mathbb{E}_{\hat{x}}[(\|\nabla_{\hat{x}} f_w(\hat{x})\|_2 - 1)^2]

where x^=ϵx+(1ϵ)G(z)\hat{x} = \epsilon x + (1-\epsilon)G(z) with ϵU[0,1]\epsilon \sim U[0,1] (points on lines between real and fake samples).

Why this works: The Wasserstein distance requires the critic to be 1-Lipschitz. This penalty enforces that the gradient norm is close to 1, which is the tightest form of the Lipschitz constraint.

Derivation:

  1. A 1-Lipschitz function satisfies f(x)f(y)xy|f(x) - f(y)| \leq \|x - y\|
  2. For differentiable ff, this means f(x)1\|\nabla f(x)\| \leq 1 everywhere
  3. The optimal critic has f(x)=1\|\nabla f(x)\| = 1 almost everywhere
  4. So we penalize deviation from norm = 1

Why interpolated points: The region between real and fake samples is where the critic must distinguish most sharply, so that's where we enforce the constraint.

Problem: Training high-resolution GANs (1024×1024) directly is unstable—too much detail for early training.

Solution: Start with low resolution (4×4), gradually add layers to increase resolution (8×8, 16×16, ..., 1024×1024). Each resolution trains until stable before growing.

Implementation:

  1. Start Generator outputs 4×4, Discriminator inputs 4×4
  2. Add layers: Smoothly fade in new layers using α[0,1]\alpha \in [0,1]: output=αnew_layer(x)+(1α)upsample(old_output)\text{output} = \alpha \cdot \text{new\_layer}(x) + (1-\alpha) \cdot \text{upsample}(\text{old\_output})
  3. Increase α\alpha from 0 to 1 over several thousand iterations
  4. Stabilize at α=1\alpha=1, then add next resolution layer

Why this works: Low-resolution images have less information, so the GAN learns the broad structure first (shape, layout) before details (texture, fine edges). This hierarchical learning is more stable than learning all scales simultaneously.

Monitoring and Diagnosing GAN Training

Q: What are signs that the discriminator is too strong? A: Generator loss stays high and constant, D(G(z))0D(G(z)) \approx 0 for all generated samples, generated samples don't improve visually

Q: What are signs of mode collapse? A: Low diversity in generated samples (e.g., all faces have same pose/expression), generator loss oscillates but samples don't improve in variety, Inception Score or FID suddenly drops

Q: How can you distinguish oscillation from convergence? A: Plot loss curves over time—convergence shows stabilizing losses, oscillation shows periodic swings. Check sample diversity over time—oscillation often means samples cycle between a few types.

Connections

  • 4.5.01-Generative-Adversarial-Networks-fundamentals - Core GAN setup and original objective
  • 4.5.07-Wasserstein-GAN-and-improved-training - WGAN solution to instability
  • 4.5.09-StyleGAN-and-progressive-growing - Progressive training for high-res stability
  • 4.5.10-Conditional-GANs-and-control - Mode collapse in conditional generation
  • 3.4.05-Optimization-challenges-in-deep-learning - General optimization issues relevant to GANs
  • 4.3.06-Batch-normalization-and-alternatives - Why batch norm causes GAN issues

Flashcards

#flashcards/ai-ml

What is the optimal discriminator D*(x) for a fixed generator?
D*(x) = p_data(x) / (p_data(x) + p_g(x)). When the generator is perfect (p_g = p_data), this equals 1/2 everywhere—the discriminator can only guess randomly.
What actually causes the vanishing gradient in original GAN training?
The discriminator's output saturates when it becomes too confident, making its input-gradient ∇_x D(G(z)) → 0. It is NOT caused by the scalar -1/(1-D), which approaches the constant -1.
Why is it wrong to say the vanishing gradient comes from the -1/(1-D) factor?
Because when D(G(z)) → 0, that factor approaches -1 (a constant), which does not shrink the gradient. The gradient vanishes due to the saturated discriminator's input-derivative ∇_x D → 0.
What is the non-saturating GAN loss fix?
Instead of minimizing log(1-D(G(z))), the generator maximizes log(D(G(z))). The prefactor 1/D(G(z)) blows up when D(G(z)) is small, amplifying the saturated ∇_x D and rescuing the learning signal.
What is mode collapse in GANs?
When the generator learns to produce only a small subset of the target distribution (sometimes just one output) because it finds that producing variety is riskier than sticking to "safe" outputs that fool the discriminator.
Why does mode collapse occur from a game theory perspective?
The generator's objective only cares about fooling D right now, not covering the full distribution. If G never produces samples from a mode, D never learns to check for it, so G has no incentive to explore that mode.
What is the key innovation of Wasserstein GAN for stability?
WGAN uses a critic (real-valued, no sigmoid) that optimizes Wasserstein distance, providing non-saturating gradients everywhere and pulling the generator toward the data distribution across all modes.
What is spectral normalization and why does it stabilize GAN training?
Dividing weight matrices by their spectral norm (largest singular value) to constrain the Lipschitz constant of each layer to ≤1, preventing extremely sharp discriminator transitions that cause mode collapse.
Why is training D and G with the same learning rate often problematic?
The discriminator's task (binary classification on generated samples) is easier than the generator's task (creating realistic samples), so D learns faster and becomes too strong with equal learning rates.
What is the gradient penalty in WGAN-GP?
A penalty term λ𝔼[(‖∇f(x̂)‖₂ - 1)²] applied at interpolated points x̂ between real and fake samples to enforce the 1-Lipschitz constraint more effectively than weight clipping.
How does progressive GAN training improve stability?
Starting at low resolution (4×4) and gradually adding layers to increase resolution allows the GAN to learn broad structure first before fine details, which is more stable than learning all scales simultaneously.
What are three signs that a discriminator is too strong?
(1) Generator loss stays high and constant, (2) D(G(z)) ≈ 0 for all generated samples, (3) generated samples don't improve visually over time.
Why does batch normalization cause issues in GAN discriminators?
Batch norm creates dependencies between samples in a batch, letting the discriminator detect fake batches (correlated through BN statistics) versus real batches rather than evaluating samples individually.
Recall Feynman: Explain to a 12-year-old

Imagine you have two friends playing a game. One friend (the Gener

Concept Map

involves

involves

minimizes

maximizes

solve for D

near-perfect D

chain rule

weakens

too weak

requires

breaks

breaks

limited variety

Minimax Game

Generator G

Discriminator D

GAN Objective V

Optimal D*

Generator Gradient

Vanishing Gradient

Training Instability

Mode Collapse

Fragile Balance

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Hinglish (regional understanding)

Intuition Hinglish mein samjho

GAN training samajhne ke liye ek simple picture socho: do students hain jo ek doosre ko compete karte hue improve kar rahe hain. Ek hai generator (jo fake images banata hai) aur doosra hai discriminator (jo pakadta hai ki image asli hai ya nakli). Dono ek "minimax game" khel rahe hain — generator chahta hai discriminator ko bewakoof banana, aur discriminator chahta hai har fake ko pakadna. Problem yeh hai ki inn dono ko ek same pace pe improve karna padta hai. Agar discriminator bahut jaldi bahut acha ban gaya, toh woh generator ko koi useful hint nahi deta ("tera sab kuch obviously fake hai"), aur generator seekhna band kar deta hai. Isko hi bolte hain training instability aur uska ek roop hai mode collapse jahan generator sirf limited variety produce karta hai.

Ab thodi si math intuition — jab discriminator bahut confident ho jata hai, toh woh fake samples ke liye output almost 0 dene lagta hai aur uska output curve "saturate" ho jata hai (matlab flat ho jata hai). Yahan ek common galatfehmi hai: log jaan-te hain ki gradient vanish ho jata hai, par wajah galat samajhte hain. Asli reason yeh hai ki jab discriminator ka output flat hota hai, toh uska input ke saath change (xD\nabla_x D) almost zero ho jata hai. Jab yeh zero ho jaye, toh generator ko poora learning signal hi nahi milta — chahe baaki factor constant (1-1) hi kyun na ho. Isliye jab discriminator "too hard" jeet jata hai, generator improve karna bilkul rok deta hai.

Yeh baat kyun important hai? Kyunki jab bhi tum real world mein GANs train karoge — chahe images generate karni ho, ya data augmentation karna ho — yeh instability tumhe zaroor face karni padegi. Is core intuition ko samajhne se tum debug kar paoge ki kyun tumhara model achanak fail ho raha hai, aur solutions jaise "non-saturating loss" ya learning rate balance karna kyun kaam karte hain. Basically, GANs ki asli challenge sirf architecture nahi, balki dono networks ko ek delicate balance mein rakhna hai — aur yeh samajhna hi ek accha ML engineer banne ka pehla step hai.

Go deeper — visual, from zero

Test yourself — Generative Models

Connections