生成对抗网络(GAN)让AI学会"创造"——生成逼真的图像、音频、文本。本课深入GAN的原理和实现。
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不断对抗,共同进步
理论最优:D*(x) = p_data(x) / (p_data(x) + p_g(x))
当p_g = p_data时:D*(x) = 1/2(无法区分真假)
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}")
本课的核心知识点构成了实战项目学习的重要一环。让我们从更高维度审视这些知识之间的关系:
⚠️ 初学者常犯的错误:
💡 最佳实践:
深度学习是一个整体——每一课的知识都不是孤立的:
💡 继续深入的学习路径:
实现Wasserstein GAN,对比DCGAN的训练稳定性。
实现cGAN,按类别条件生成图像。
了解StyleGAN的风格注入和渐进增长策略。
⚠️ 需要避免的典型错误:
💡 提升模型性能的系统方法:
理解本课内容需要将其置于更大的知识网络中。每个核心概念都不是孤立的,它们相互关联、相互支撑:
建立正确的直觉比记住公式更重要:
1. 维度直觉:高维空间中,数据分布与低维直觉截然不同(维度诅咒)
2. 信息瓶颈:神经网络逐层压缩信息,保留任务相关的、丢弃无关的
3. 流形假设:高维数据实际分布在低维流形上,学习即发现流形结构
4. 偏差-方差权衡:简单模型欠拟合(高偏差),复杂模型过拟合(高方差)
本课作为实战项目阶段的核心内容,与前后课程紧密关联:
| 关联课程 | 关联点 | 协同效应 |
|---|---|---|
| 前序课程 | 提供了本课的基础知识 | 循序渐进的理解 |
| 后续课程 | 本课内容是后续的基础 | 逐步构建能力 |
| 平行课程 | 同一阶段的互补知识 | 多角度深入理解 |
| 实战项目 | 综合运用所有知识 | 理论与实践结合 |
💡 准备面试时,确保能回答以下问题:
掌握本课内容后,可以通过以下方式继续深入:
生成对抗网络——AI学会了创造!