Generative Adversarial Networks (GAN)

Generative Adversarial Networks are a class of deep learning models that consist of two competing neural networks: a generator that creates synthetic data and a discriminator that tries to distinguish between real and generated data. This adversarial training process leads to the generation of increasingly realistic data, making GANs powerful tools for image generation, style transfer, and data augmentation.

Core Concepts

GANs are built on several key concepts that enable them to generate realistic data through adversarial training.

  • Network Architecture

    The structure of a GAN consists of:

    • Generator network
    • Discriminator network
    • Latent space
    • Adversarial training

  • Key Operations

    The main operations in GANs include:

    • Data generation
    • Discrimination
    • Adversarial loss
    • Gradient updates

Key Components

  • Conditional GANs - Deep Learning Book chapter on generative models
  • CycleGAN - Deep Learning Book chapter on generative models
  • StyleGAN - Deep Learning Book chapter on generative models
  • Wasserstein GAN - Deep Learning Book chapter on generative models
  • Progressive GAN - Deep Learning Book chapter on generative models

Implementation Examples

GAN with TensorFlow/Keras

import tensorflow as tf
from tensorflow.keras import layers, models

def create_generator(latent_dim):
    model = models.Sequential([
        layers.Dense(256, input_dim=latent_dim),
        layers.LeakyReLU(alpha=0.2),
        layers.BatchNormalization(),
        layers.Dense(512),
        layers.LeakyReLU(alpha=0.2),
        layers.BatchNormalization(),
        layers.Dense(1024),
        layers.LeakyReLU(alpha=0.2),
        layers.BatchNormalization(),
        layers.Dense(784, activation='tanh'),
        layers.Reshape((28, 28, 1))
    ])
    return model

def create_discriminator(input_shape):
    model = models.Sequential([
        layers.Flatten(input_shape=input_shape),
        layers.Dense(512),
        layers.LeakyReLU(alpha=0.2),
        layers.Dropout(0.3),
        layers.Dense(256),
        layers.LeakyReLU(alpha=0.2),
        layers.Dropout(0.3),
        layers.Dense(1, activation='sigmoid')
    ])
    return model

# Example usage
latent_dim = 100
input_shape = (28, 28, 1)

generator = create_generator(latent_dim)
discriminator = create_discriminator(input_shape)

# Compile discriminator
discriminator.compile(
    optimizer='adam',
    loss='binary_crossentropy',
    metrics=['accuracy']
)

GAN with PyTorch

import torch
import torch.nn as nn
import torch.nn.functional as F

class Generator(nn.Module):
    def __init__(self, latent_dim):
        super(Generator, self).__init__()
        self.model = nn.Sequential(
            nn.Linear(latent_dim, 256),
            nn.LeakyReLU(0.2),
            nn.BatchNorm1d(256),
            nn.Linear(256, 512),
            nn.LeakyReLU(0.2),
            nn.BatchNorm1d(512),
            nn.Linear(512, 1024),
            nn.LeakyReLU(0.2),
            nn.BatchNorm1d(1024),
            nn.Linear(1024, 784),
            nn.Tanh()
        )
    
    def forward(self, z):
        img = self.model(z)
        img = img.view(img.size(0), 1, 28, 28)
        return img

class Discriminator(nn.Module):
    def __init__(self):
        super(Discriminator, self).__init__()
        self.model = nn.Sequential(
            nn.Flatten(),
            nn.Linear(784, 512),
            nn.LeakyReLU(0.2),
            nn.Dropout(0.3),
            nn.Linear(512, 256),
            nn.LeakyReLU(0.2),
            nn.Dropout(0.3),
            nn.Linear(256, 1),
            nn.Sigmoid()
        )
    
    def forward(self, img):
        return self.model(img)

# Example usage
latent_dim = 100
generator = Generator(latent_dim)
discriminator = Discriminator()

# Define optimizers
g_optimizer = torch.optim.Adam(generator.parameters(), lr=0.0002, betas=(0.5, 0.999))
d_optimizer = torch.optim.Adam(discriminator.parameters(), lr=0.0002, betas=(0.5, 0.999))