Quiz 2

GANs for Computer Vision: Generator, Discriminator, DCGAN, CGAN, WGAN, CycleGAN

784 words
4 min read
Python Week 1: the first filter for runtime behavior
Visual companion
Python
Type and operator map

Python Week 1: the first filter for runtime behavior

View
Revision summary

What this note is really saying

Short form

# GANs for Computer Vision: Generator, Discriminator, DCGAN, CGAN, WGAN, CycleGAN ## 🎯 Learning Objectives - Understand the GAN framework for image generation - Implement DCGAN with convolutional layers - Generate conditional images with CGAN - Stabilize training with Wasserstein GAN (WGAN) - Apply CycleGAN for unp...

GANs for Computer Vision: Generator, Discriminator, DCGAN, CGAN, WGAN, CycleGAN

🎯 Learning Objectives

  • Understand the GAN framework for image generation
  • Implement DCGAN with convolutional layers
  • Generate conditional images with CGAN
  • Stabilize training with Wasserstein GAN (WGAN)
  • Apply CycleGAN for unpaired image-to-image translation

📋 Prerequisites

  • CNN Fundamentals (Week 1): Convolution, transposed convolution
  • Transfer Learning (Week 3): Feature extraction concepts
  • Object Detection (Week 4): Feature map understanding

1. 📖 Core Content

1.1 GAN Framework for Images

GANs pit two networks against each other:
  • Generator: Creates fake images from random noise
  • Discriminator: Distinguishes real from fake images (Diagram)

1.2 DCGAN Architecture

DCGAN (Radford et al., 2016) was the first to make GANs work consistently with CNNs: Generator (noise → 64×64 image):
python
# runnable
import torch.nn as nn
class DCGANGenerator(nn.Module):
    def __init__(self, latent_dim=100, feature_dim=64, img_channels=3):
        super().__init__()
        self.main = nn.Sequential(
            # Input: latent_dim x 1 x 1
            nn.ConvTranspose2d(latent_dim, feature_dim*8, 4, 1, 0, bias=False),
            nn.BatchNorm2d(feature_dim*8),
            nn.ReLU(True),
            # 4x4
            nn.ConvTranspose2d(feature_dim*8, feature_dim*4, 4, 2, 1, bias=False),
            nn.BatchNorm2d(feature_dim*4),
            nn.ReLU(True),
            # 8x8
            nn.ConvTranspose2d(feature_dim*4, feature_dim*2, 4, 2, 1, bias=False),
            nn.BatchNorm2d(feature_dim*2),
            nn.ReLU(True),
            # 16x16
            nn.ConvTranspose2d(feature_dim*2, feature_dim, 4, 2, 1, bias=False),
            nn.BatchNorm2d(feature_dim),
            nn.ReLU(True),
            # 32x32
            nn.ConvTranspose2d(feature_dim, img_channels, 4, 2, 1, bias=False),
            nn.Tanh()
            # 64x64
        )
    def forward(self, z):
        return self.main(z.view(z.size(0), -1, 1, 1))
Discriminator (64×64 image → real/fake):
python
# runnable
class DCGANDiscriminator(nn.Module):
    def __init__(self, feature_dim=64, img_channels=3):
        super().__init__()
        self.main = nn.Sequential(
            nn.Conv2d(img_channels, feature_dim, 4, 2, 1, bias=False),
            nn.LeakyReLU(0.2, inplace=True),
            nn.Conv2d(feature_dim, feature_dim*2, 4, 2, 1, bias=False),
            nn.BatchNorm2d(feature_dim*2),
            nn.LeakyReLU(0.2, inplace=True),
            nn.Conv2d(feature_dim*2, feature_dim*4, 4, 2, 1, bias=False),
            nn.BatchNorm2d(feature_dim*4),
            nn.LeakyReLU(0.2, inplace=True),
            nn.Conv2d(feature_dim*4, feature_dim*8, 4, 2, 1, bias=False),
            nn.BatchNorm2d(feature_dim*8),
            nn.LeakyReLU(0.2, inplace=True),
            nn.Conv2d(feature_dim*8, 1, 4, 1, 0, bias=False),
            nn.Sigmoid()
        )
    def forward(self, x):
        return self.main(x).view(-1)

1.3 Training Tips for GANs

ProblemSymptomFix
Mode collapseGenerator produces same imageLabel smoothing, minibatch discrimination
Non-convergenceLoss oscillatesWGAN loss, gradient penalty
Blurry imagesLow qualityIncrease capacity, feature matching
Discriminator too strongD loss ≈ 0 alwaysReduce D capacity, add dropout

1.4 WGAN-GP (Wasserstein GAN with Gradient Penalty)

WGAN replaces the binary discriminator with a critic that outputs a score, and uses the Wasserstein distance:
python
# runnable
def gradient_penalty(critic, real, fake, device):
    """WGAN-GP gradient penalty."""
    batch_size = real.size(0)
    # Random interpolation
    epsilon = torch.rand(batch_size, 1, 1, 1, device=device)
    interpolated = epsilon * real + (1 - epsilon) * fake
    interpolated.requires_grad_(True)
    # Critic score for interpolated images
    d_interpolated = critic(interpolated)
    # Gradients
    gradients = torch.autograd.grad(
        outputs=d_interpolated,
        inputs=interpolated,
        grad_outputs=torch.ones_like(d_interpolated),
        create_graph=True,
        retain_graph=True
    )[0]
    # GP loss: (||grad|| - 1)^2
    gradients = gradients.view(batch_size, -1)
    grad_norm = gradients.norm(2, dim=1)
    gp = ((grad_norm - 1) ** 2).mean()
    return gp

1.5 Why This Matters

GANs revolutionized computer vision: image generation (StyleGAN), super-resolution (SRGAN), image-to-image translation (Pix2Pix), and data augmentation for training other models.

2. 📐 Key Formulas / Concepts

VariantLoss FunctionStabilityQuality
Vanilla GANmin_G max_D E[log D] + E[log(1-D(G))]LowModerate
DCGANSame + architectural constraintsMediumGood
WGANmin_G max_D E[D(x)] - E[D(G(z))], LipschitzHighGood
WGAN-GPWGAN + gradient penaltyVery highExcellent
LSGANmin E[(D-1)²] + E[D(G)²]HighGood

3. ⚠️ Common Pitfalls

Pitfall 1: Using Sigmoid at the End of the Generator

Mistake: Using Sigmoid activation at generator output for all image types. Why: Sigmoid bounds outputs to [0, 1]. If your image data isn't normalized to [0, 1], this limits expressiveness. Fix: Use Tanh ([-1, 1]) for the generator and normalize images to [-1, 1]. Tanh produces sharper images because gradients don't saturate as easily as Sigmoid.

Pitfall 2: Balancing Generator and Discriminator

Mistake: Using identical learning rates for both networks. Why: The two-player game requires careful balancing. A stronger discriminator kills gradient flow; a stronger generator fools too easily. Fix: Use different LR (2e-4 for G, 1e-4 for D), update G more frequently (5 G steps per D step), or use different optimizer betas.

4. 📝 Practice Questions

Q1: Your GAN generates the same cherry-red sports car for every noise input. What's wrong and how do you fix it?
Problem: Mode collapse — the generator found one plausible image that fools the discriminator and sticks to it.
Fixes:
  1. Minibatch discrimination: Add feature statistics across the batch so the discriminator can detect when the generator produces uniform outputs.
  2. Label smoothing: Use soft labels (0.9/0.1 instead of 1/0) to prevent the discriminator from being overconfident.
  3. WGAN loss: Wasserstein loss doesn't saturate like binary cross-entropy, making mode collapse less likely.
  4. Increase latent dimension: More noise dimensions give the generator more room to diversify.
  5. Add noise to discriminator inputs: Inject Gaussian noise to force the discriminator to tolerate variation.

5. 🔗 Cross-References

Document outline

Keep your place and jump directly to a heading.

Table of Contents
System Normal // Awaiting Context

Intelligence Hub

Navigate the knowledge graph to generate context. The Hub adapts dynamically to surface backlinks, related notes, and metadata insights.