In GANs, we want the generator to create data that looks real, and the discriminator to tell real from fake. The key metrics are discriminator loss and generator loss. These losses show how well each part is learning. Lower loss means better performance. We also look at Inception Score or FID to measure how real the generated images look overall. These metrics help us know if the GAN is improving or stuck.
GAN training loop in PyTorch - Model Metrics & Evaluation
Discriminator predictions:
| Real Data | Fake Data
-----------|-----------|----------
Pred Real | TP | FP
Pred Fake | FN | TN
Where:
- TP (True Positive): Discriminator correctly says real data is real
- FP (False Positive): Discriminator wrongly says fake data is real
- FN (False Negative): Discriminator wrongly says real data is fake
- TN (True Negative): Discriminator correctly says fake data is fake
Losses are computed from these predictions to update both networks.
GAN training balances two goals:
- Discriminator precision: How often it correctly identifies fake images. High precision means few fake images are mistaken as real.
- Generator recall: How well the generator fools the discriminator. High recall means many generated images look real enough to fool the discriminator.
If the discriminator is too strong (high precision), the generator struggles and produces poor images (low recall). If the generator is too strong (high recall), the discriminator fails to learn (low precision). Good GAN training finds a balance where both improve together.
Good:
- Discriminator loss and generator loss both decrease steadily and stabilize.
- Generated images look realistic and diverse.
- Inception Score or FID improves over time (higher IS, lower FID).
Bad:
- Discriminator loss quickly goes to zero while generator loss stays high (discriminator too strong).
- Generator loss goes to zero but discriminator loss stays high (generator collapses to few outputs).
- Generated images are blurry, repetitive, or obviously fake.
- Mode collapse: Generator produces limited variety of outputs. Losses may look good but diversity is poor.
- Overfitting discriminator: Discriminator becomes too perfect, causing generator to fail learning.
- Ignoring qualitative checks: Only looking at loss numbers without checking generated samples can mislead.
- Data leakage: Using test data in training can inflate metrics falsely.
Your GAN training shows discriminator loss near zero but generator loss remains high. Generated images look poor and repetitive. Is this good?
Answer: No. This means the discriminator is too strong and easily spots fakes. The generator is not learning well and may be stuck producing limited outputs. You should adjust training to balance both networks better.
Practice
Solution
Step 1: Understand the discriminator's purpose
The discriminator's job is to tell apart real data from fake data created by the generator.Step 2: Differentiate roles in GAN
The generator creates fake data, while the discriminator judges it. It does not generate data or adjust learning rates.Final Answer:
To distinguish between real and fake data -> Option CQuick Check:
Discriminator = spot fake data [OK]
- Confusing discriminator with generator
- Thinking discriminator generates data
- Assuming discriminator sets learning rate
Solution
Step 1: Recall PyTorch optimizer method
In PyTorch, the method to clear gradients before backpropagation is zero_grad().Step 2: Check each option's validity
Only optimizer_G.zero_grad(); optimizer_D.zero_grad() uses zero_grad(), which is the correct method. Other options use non-existent methods.Final Answer:
optimizer_G.zero_grad(); optimizer_D.zero_grad() -> Option BQuick Check:
Clear gradients = zero_grad() [OK]
- Using non-existent optimizer methods
- Forgetting to zero gradients before backward
- Confusing zero_grad() with optimizer step()
print(loss_D.item(), loss_G.item()) after one iteration?real_data = torch.ones(4) fake_data = torch.zeros(4) criterion = torch.nn.BCELoss() # Discriminator output output_real = torch.tensor([0.9, 0.8, 0.95, 0.85]) output_fake = torch.tensor([0.1, 0.2, 0.05, 0.15]) loss_real = criterion(output_real, real_data) loss_fake = criterion(output_fake, fake_data) loss_D = (loss_real + loss_fake) / 2 # Generator tries to fool discriminator output_fake_for_G = torch.tensor([0.4, 0.3, 0.5, 0.6]) loss_G = criterion(output_fake_for_G, real_data) print(loss_D.item(), loss_G.item())
Solution
Step 1: Calculate discriminator loss
Loss_real = BCELoss([0.9,0.8,0.95,0.85], [1,1,1,1]) ≈ 0.136; Loss_fake = BCELoss([0.1,0.2,0.05,0.15], [0,0,0,0]) ≈ 0.136; Average loss_D ≈ 0.136.Step 2: Calculate generator loss
Generator tries to fool discriminator, so loss_G = BCELoss([0.4,0.3,0.5,0.6], [1,1,1,1]) ≈ 0.831.Final Answer:
Approximately 0.136 and 0.831 -> Option DQuick Check:
Discriminator loss < Generator loss [OK]
- Mixing up real and fake labels in loss
- Confusing which loss belongs to generator
- Ignoring averaging of discriminator losses
for real_data in dataloader:
optimizer_D.zero_grad()
output_real = discriminator(real_data)
loss_real = criterion(output_real, torch.ones_like(output_real))
fake_data = generator(torch.randn(batch_size, noise_dim))
output_fake = discriminator(fake_data.detach())
loss_fake = criterion(output_fake, torch.zeros_like(output_fake))
loss_D = loss_real + loss_fake
loss_D.backward()
optimizer_D.step()
optimizer_G.zero_grad()
output_fake_for_G = discriminator(fake_data)
loss_G = criterion(output_fake_for_G, torch.ones_like(output_fake_for_G))
loss_G.backward()
optimizer_D.step()Solution
Step 1: Analyze optimizer steps
After computing generator loss and backward, the generator's optimizer should update weights, not discriminator's.Step 2: Identify incorrect optimizer call
The code calls optimizer_D.step() twice; the second should be optimizer_G.step() to update generator.Final Answer:
Replace last optimizer_D.step() with optimizer_G.step() -> Option AQuick Check:
Generator update uses optimizer_G.step() [OK]
- Calling discriminator optimizer twice
- Forgetting to update generator weights
- Misplacing zero_grad calls
Solution
Step 1: Understand discriminator overpowering
If the discriminator learns too fast, the generator receives poor feedback and training stalls.Step 2: Evaluate options to balance training
Training discriminator less often than generator slows its learning, giving generator a chance to improve.Final Answer:
Train the discriminator less frequently than the generator -> Option AQuick Check:
Balance training frequency to stabilize GAN [OK]
- Increasing discriminator learning rate worsens imbalance
- Removing generator loss stops generator learning
- Sharing optimizer causes parameter update conflicts
Ready to prove it?
Pass the test and this pattern moves unknown
