GAN Training Challenges and Loss Functions
Why GANs are hard to train, and the practical tricks that keep them from falling apart
Why GANs are hard to train, and the practical tricks that keep them from falling apart
GAN training is a two-player game, not a simple descent to a minimum — which means it can fail in specific, well-known ways (mode collapse, vanishing gradients, instability), and a handful of practical tricks exist to keep it on track.
Every GAN-based exam question eventually asks "why is this hard to train" or "name a mitigation" — this is one of the most commonly tested sections in a GAN unit because it's where theory meets real engineering pain.
Yaha samajhna zaroori hai ki a GAN doesn't have one loss surface going downhill — it has two networks pulling against each other, and if either one gets too strong or too weak relative to the other, training breaks. A good analogy: if the detective (Discriminator) gets way too good too fast, the forger (Generator) gets no useful feedback — it's being told "wrong, wrong, wrong" with no signal about which direction to improve in. That imbalance is the root of most GAN training problems.
Discriminator loss: maximizes log D(x) + log(1 − D(G(z))) — i.e. in practice, minimize the
negative of this (standard binary cross-entropy against labels "real"=1, "fake"=0).
Generator loss — saturating (original) vs non-saturating (used in practice):
G minimizes log(1 − D(G(z))).G instead maximizes log D(G(z)).Early in training, G is bad and D easily rejects its fakes, so D(G(z)) is close to 0. Under the
saturating loss log(1 − D(G(z))), when D(G(z)) is near 0, this function is nearly flat — its
gradient with respect to G's parameters is tiny, so G barely learns anything exactly when it needs
the strongest signal. Under the non-saturating loss log D(G(z)), the same region (D(G(z)) near 0)
has a steep gradient, giving G a strong learning signal early on. Both objectives push G in
the same direction (fool D more), but the non-saturating form just has much better-behaved
gradients where it matters most, so it's the one used in practice.
G's objective only cares about
fooling D — if a narrow set of outputs does that well enough, G has no incentive to explore
further, especially if D hasn't learned to penalize that narrow set specifically.D becomes too confident/accurate too early (outputting near-0 for
all fakes and near-1 for all real with high confidence), the gradient signal flowing back to G
shrinks toward zero — G stops learning. This is the same underlying issue the non-saturating loss
partially addresses, but it can still happen even with the non-saturating form if D is drastically
overpowered relative to G.G and D are updated alternately against a constantly moving
target (each other), the training dynamics can oscillate instead of converging smoothly — losses
can bounce around indefinitely rather than settling, unlike typical supervised training curves.D with hard targets (1 for real, 0 for fake), use
slightly softened targets (e.g. 0.9 for real) — makes D less overconfident, which keeps gradients
to G from vanishing as easily.G purely to maximize D's output score, train it to
match the statistics of intermediate feature-layer activations that D computes for real vs fake
data — gives G a richer, less gameable training signal than a single scalar.D look at an entire minibatch of samples together (not just one
at a time) so it can notice if the Generator is producing suspiciously similar outputs across the
batch — directly discourages mode collapse by making lack-of-diversity itself detectable.D is confident; WGAN replaces the Discriminator with
a "Critic" that estimates the Wasserstein distance between real and fake distributions instead of a
real/fake probability, giving a more stable and more meaningful training signal that correlates
better with actual sample quality. (StyleGAN's architecture-level innovations get their own topic.)Discriminator loss: maximizes log D(x) + log(1 − D(G(z))).
Generator loss (saturating, original): minimizes log(1 − D(G(z))).
Generator loss (non-saturating, used in practice): maximizes log D(G(z)) instead — stronger
gradients early in training, when D easily rejects G's samples.
Where D(x) is the Discriminator's estimated probability that real sample x is real, and D(G(z))
is its estimated probability that the Generator's fake G(z) is real.
Early training, illustrative values: D(G(z)) = 0.02 (D is confidently rejecting the fake).
log(1 - 0.02) = log(0.98) ≈ -0.0202 — very close to the flat region of
log(1-t) near t=0, so its slope here is small — weak gradient to G.log(D(G(z))) = log(0.02) ≈ -3.91 — this is in the steep region of
log(t) near t=0, so the gradient magnitude here is much larger — strong, useful gradient to G.
Same situation, very different gradient quality — this is exactly why practice uses the
non-saturating form.G in different directions — both want D(G(z)) to
increase; the difference is purely in gradient magnitude in the region where D(G(z)) is small,
not in the direction of improvement.D(x) in a standard GAN.The non-saturating Generator loss (maximize log D(G(z))) is used in practice specifically because
it gives strong gradients exactly when the Generator is weakest — the saturating original form goes
flat right when the signal is needed most.