# Generative Models

> Use when building GANs, VAEs, or diffusion models.

- Skill: `loopyluci/generative-models` (Agent Skill)
- Install (CLI): `npx skillmds@latest add loopyluci/generative-models`
- Raw SKILL.md: https://api.skillmd.com/api/skills/loopyluci/generative-models/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: LoopyLuci (https://skillmd.com/u/loopyluci)
- Updated: 2026-09-08
- Page: https://skillmd.com/skills/loopyluci/generative-models

---

# Generative Models

Building and training GANs, VAEs, and diffusion models.

## Variational Autoencoders (VAEs)

```python
import torch
import torch.nn as nn

class VAE(nn.Module):
    def __init__(self, input_dim=784, latent_dim=32):
        super().__init__()
        self.encoder = nn.Sequential(
            nn.Linear(input_dim, 256), nn.ReLU(),
            nn.Linear(256, 128), nn.ReLU(),
        )
        self.mu = nn.Linear(128, latent_dim)
        self.logvar = nn.Linear(128, latent_dim)
        self.decoder = nn.Sequential(
            nn.Linear(latent_dim, 128), nn.ReLU(),
            nn.Linear(128, 256), nn.ReLU(),
            nn.Linear(256, input_dim), nn.Sigmoid(),
        )

    def encode(self, x):
        h = self.encoder(x)
        return self.mu(h), self.logvar(h)

    def reparameterize(self, mu, logvar):
        std = torch.exp(0.5 * logvar)
        eps = torch.randn_like(std)
        return mu + eps * std

    def decode(self, z):
        return self.decoder(z)

    def forward(self, x):
        mu, logvar = self.encode(x)
        z = self.reparameterize(mu, logvar)
        return self.decode(z), mu, logvar

# Loss: reconstruction + KL divergence
def vae_loss(recon_x, x, mu, logvar):
    recon = nn.functional.binary_cross_entropy(recon_x, x, reduction='sum')
    kl = -0.5 * torch.sum(1 + logvar - mu.pow(2) - logvar.exp())
    return recon + kl
```

## Diffusion Models (Simplified)

```python
# Forward: add noise step by step
# Reverse: denoise step by step (learned)

class DiffusionModel:
    def __init__(self, model, timesteps=1000):
        self.model = model
        self.T = timesteps
        self.beta = torch.linspace(1e-4, 0.02, timesteps)
        self.alpha = 1 - self.beta
        self.alpha_bar = torch.cumprod(self.alpha, dim=0)

    def forward_diffusion(self, x0, t):
        # q(x_t | x_0) = N(x_t; sqrt(ᾱ_t)x_0, (1-ᾱ_t)I)
        noise = torch.randn_like(x0)
        xt = torch.sqrt(self.alpha_bar[t]) * x0 + \
             torch.sqrt(1 - self.alpha_bar[t]) * noise
        return xt, noise

    def training_loss(self, x0):
        t = torch.randint(0, self.T, (x0.shape[0],))
        xt, noise = self.forward_diffusion(x0, t)
        predicted_noise = self.model(xt, t)
        return nn.functional.mse_loss(predicted_noise, noise)

    @torch.no_grad()
    def sample(self, shape):
        x = torch.randn(shape)
        for t in reversed(range(self.T)):
            z = torch.randn_like(x) if t > 0 else 0
            predicted_noise = self.model(x, t)
            x = (1 / torch.sqrt(self.alpha[t])) * \
                (x - (1 - self.alpha[t]) / torch.sqrt(1 - self.alpha_bar[t]) * predicted_noise) + \
                torch.sqrt(self.beta[t]) * z
        return x
```

## GANs (Generative Adversarial Networks)

```python
class Generator(nn.Module):
    def __init__(self, latent_dim=100, img_dim=784):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(latent_dim, 256), nn.ReLU(),
            nn.BatchNorm1d(256),
            nn.Linear(256, 512), nn.ReLU(),
            nn.BatchNorm1d(512),
            nn.Linear(512, img_dim), nn.Tanh(),
        )

class Discriminator(nn.Module):
    def __init__(self, img_dim=784):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(img_dim, 256), nn.LeakyReLU(0.2),
            nn.Dropout(0.3),
            nn.Linear(256, 128), nn.LeakyReLU(0.2),
            nn.Dropout(0.3),
            nn.Linear(128, 1), nn.Sigmoid(),
        )

# Training loop alternates
# 1. Train discriminator on real + fake
# 2. Train generator to fool discriminator
```

## Pitfalls

- VAEs produce blurry images — use β-VAE or VQ-VAE for sharper output
- Diffusion models are slow to sample (1000 steps) — use DDIM or LCM for speed
- GAN training is unstable — use WGAN-GP or StyleGAN architecture
- Mode collapse in GANs: generator produces limited variety
- Diffusion models need careful noise schedule tuning

