📚 课程目录

第34课:GAN生成

📖 本课概述

生成对抗网络(GAN)让AI学会"创造"——生成逼真的图像、音频、文本。本课深入GAN的原理和实现。

🎭 一、GAN原理

1.1 对抗博弈

min_G max_D V(D,G) = E_x~p_data[log D(x)] + E_z~p_z[log(1-D(G(z)))]

D:判别器——区分真实/生成数据

G:生成器——生成逼真的假数据

训练目标:G和D不断对抗,共同进步

1.2 纳什均衡

理论最优:D*(x) = p_data(x) / (p_data(x) + p_g(x))

当p_g = p_data时:D*(x) = 1/2(无法区分真假)

1.3 GAN训练的挑战

1.4 DCGAN实现


import torch
import torch.nn as nn

# GAN实现
print("=== DCGAN生成对抗网络 ===")

# 生成器
class Generator(nn.Module):
    def __init__(self, latent_dim=100, img_channels=1):
        super().__init__()
        self.net = nn.Sequential(
            nn.ConvTranspose2d(latent_dim, 128, 4, 1, 0, bias=False),
            nn.BatchNorm2d(128), nn.ReLU(True),
            nn.ConvTranspose2d(128, 64, 4, 2, 1, bias=False),
            nn.BatchNorm2d(64), nn.ReLU(True),
            nn.ConvTranspose2d(64, 32, 4, 2, 1, bias=False),
            nn.BatchNorm2d(32), nn.ReLU(True),
            nn.ConvTranspose2d(32, img_channels, 4, 2, 1, bias=False),
            nn.Tanh()
        )
    
    def forward(self, z):
        return self.net(z)

# 判别器
class Discriminator(nn.Module):
    def __init__(self, img_channels=1):
        super().__init__()
        self.net = nn.Sequential(
            nn.Conv2d(img_channels, 32, 4, 2, 1, bias=False),
            nn.LeakyReLU(0.2, True),
            nn.Conv2d(32, 64, 4, 2, 1, bias=False),
            nn.BatchNorm2d(64), nn.LeakyReLU(0.2, True),
            nn.Conv2d(64, 128, 4, 2, 1, bias=False),
            nn.BatchNorm2d(128), nn.LeakyReLU(0.2, True),
            nn.Conv2d(128, 1, 4, 1, 0, bias=False),
            nn.Sigmoid()
        )
    
    def forward(self, x):
        return self.net(x).view(-1)

# 初始化
G = Generator()
D = Discriminator()

print(f"生成器参数: {sum(p.numel() for p in G.parameters()):,}")
print(f"判别器参数: {sum(p.numel() for p in D.parameters()):,}")

# 测试前向传播
z = torch.randn(8, 100, 1, 1)
fake_img = G(z)
print(f"\n生成: z{list(z.shape)} → img{list(fake_img.shape)}")
print(f"判别: img{list(fake_img.shape)} → score{list(D(fake_img).shape)}")

# GAN训练
opt_G = torch.optim.Adam(G.parameters(), lr=0.0002, betas=(0.5, 0.999))
opt_D = torch.optim.Adam(D.parameters(), lr=0.0002, betas=(0.5, 0.999))
loss_fn = nn.BCELoss()

# 模拟真实数据
real_data = torch.randn(32, 1, 32, 32) * 0.5 + 0.5  # 模拟真实图像
real_data = torch.clamp(real_data, -1, 1)

print("\nGAN训练:")
for epoch in range(0, 51, 10):
    # 训练判别器
    opt_D.zero_grad()
    
    real_label = torch.ones(32)
    fake_label = torch.zeros(32)
    
    # 真实数据
    d_real = D(real_data)
    loss_real = loss_fn(d_real, real_label)
    
    # 生成数据
    z = torch.randn(32, 100, 1, 1)
    fake = G(z).detach()
    d_fake = D(fake)
    loss_fake = loss_fn(d_fake, fake_label)
    
    d_loss = loss_real + loss_fake
    d_loss.backward()
    opt_D.step()
    
    # 训练生成器
    opt_G.zero_grad()
    z = torch.randn(32, 100, 1, 1)
    fake = G(z)
    d_fake = D(fake)
    g_loss = loss_fn(d_fake, real_label)  # 生成器希望判别器认为生成数据是真实的
    g_loss.backward()
    opt_G.step()
    
    print(f"Epoch {epoch:2d}: D_loss={d_loss.item():.4f}, G_loss={g_loss.item():.4f}, "
          f"D(real)={d_real.mean().item():.3f}, D(fake)={D(fake.detach()).mean().item():.3f}")
🟢 运行结果 ✅验证通过 === DCGAN生成对抗网络 === 生成器参数: 369,600 判别器参数: 166,784 生成: z[8, 100, 1, 1] → img[8, 1, 32, 32] 判别: img[8, 1, 32, 32] → score[8] GAN训练: Epoch 0: D_loss=1.3913, G_loss=0.9563, D(real)=0.446, D(fake)=0.392 Epoch 10: D_loss=1.1826, G_loss=0.9621, D(real)=0.543, D(fake)=0.388 Epoch 20: D_loss=1.1234, G_loss=0.9713, D(real)=0.620, D(fake)=0.385 Epoch 30: D_loss=1.0532, G_loss=0.9523, D(real)=0.664, D(fake)=0.396 Epoch 40: D_loss=0.9731, G_loss=1.1269, D(real)=0.687, D(fake)=0.329 Epoch 50: D_loss=0.9616, G_loss=1.2038, D(real)=0.702, D(fake)=0.306

🔬 深入拓展

核心要点回顾

本课的核心知识点构成了实战项目学习的重要一环。让我们从更高维度审视这些知识之间的关系:

常见陷阱与最佳实践

⚠️ 初学者常犯的错误:

💡 最佳实践:

与前后课程的联系

深度学习是一个整体——每一课的知识都不是孤立的:

📖 延伸阅读

💡 继续深入的学习路径:

📝 练习

练习1:WGAN

实现Wasserstein GAN,对比DCGAN的训练稳定性。

练习2:条件GAN

实现cGAN,按类别条件生成图像。

练习3:StyleGAN概念

了解StyleGAN的风格注入和渐进增长策略。

💡 GAN训练技巧

稳定GAN

常见错误与解决方案

⚠️ 需要避免的典型错误:

  1. 不了解模型假设就盲目使用
  2. 没有建立基线就追求复杂方法
  3. 忽视数据质量和预处理
  4. 过度调参而不理解原理
  5. 只看训练指标忽略验证指标

性能优化建议

💡 提升模型性能的系统方法:

  1. 确保数据管道正确且高效
  2. 建立简单但正确的基线模型
  3. 分析基线的错误类型
  4. 针对性地改进(数据/模型/训练)
  5. 持续迭代,每步验证

🔬 深度拓展:从理论到实践

核心概念网络

理解本课内容需要将其置于更大的知识网络中。每个核心概念都不是孤立的,它们相互关联、相互支撑:

关键洞察与直觉

建立正确的直觉比记住公式更重要:

1. 维度直觉:高维空间中,数据分布与低维直觉截然不同(维度诅咒)

2. 信息瓶颈:神经网络逐层压缩信息,保留任务相关的、丢弃无关的

3. 流形假设:高维数据实际分布在低维流形上,学习即发现流形结构

4. 偏差-方差权衡:简单模型欠拟合(高偏差),复杂模型过拟合(高方差)

与其他课程的关联

本课作为实战项目阶段的核心内容,与前后课程紧密关联:

关联课程关联点协同效应
前序课程提供了本课的基础知识循序渐进的理解
后续课程本课内容是后续的基础逐步构建能力
平行课程同一阶段的互补知识多角度深入理解
实战项目综合运用所有知识理论与实践结合

面试常见问题

💡 准备面试时,确保能回答以下问题:

  1. 用简单语言解释本课核心概念
  2. 画出关键算法/结构的流程图
  3. 比较不同方法的优缺点
  4. 举出实际应用场景
  5. 讨论常见误解和注意事项

进阶学习路径

掌握本课内容后,可以通过以下方式继续深入:

🎭

成就解锁:GAN创造者

生成对抗网络——AI学会了创造!