共计 2871 个字符,预计需要花费 8 分钟才能阅读完成。
背景介绍
人脸生成一直是计算机视觉领域的挑战性任务。传统方法如 3D 建模需要人工参与且难以实现自然效果,而早期神经网络生成的图像往往存在模糊、细节缺失等问题。生成对抗网络 (GAN) 通过让生成器和判别器相互博弈,能够自动学习数据分布,产生高度逼真的图像。

GAN 的核心优势在于:
- 无需显式建模,自动学习数据特征
- 能够生成高分辨率、细节丰富的图像
- 通过对抗训练不断优化生成质量
技术选型
常见的 GAN 架构有:
- DCGAN:基础架构,适合快速验证和入门
- ProGAN:渐进式增长,适合高分辨率生成
- StyleGAN:支持风格混合,生成质量最佳但训练复杂
对于人脸生成任务,我们选择 DCGAN 作为起点,因为:
- 结构简单,训练速度快
- 包含卷积和反卷积等基础操作
- 适合中等分辨率 (64×64 或 128×128) 图像生成
核心实现
生成器网络设计
生成器将随机噪声转换为图像,关键设计要点:
- 使用反卷积层 (ConvTranspose2d) 进行上采样
- 每层后接 BatchNorm 和 ReLU 激活
- 输出层使用 Tanh 将像素值归一化到[-1,1]
class Generator(nn.Module):
def __init__(self, latent_dim=100, img_channels=3):
super().__init__()
self.main = nn.Sequential(
# 输入: latent_dim x 1 x 1
nn.ConvTranspose2d(latent_dim, 512, 4, 1, 0, bias=False),
nn.BatchNorm2d(512),
nn.ReLU(True),
# 输出: 512 x 4 x 4
nn.ConvTranspose2d(512, 256, 4, 2, 1, bias=False),
nn.BatchNorm2d(256),
nn.ReLU(True),
# 输出: 256 x 8 x 8
nn.ConvTranspose2d(256, 128, 4, 2, 1, bias=False),
nn.BatchNorm2d(128),
nn.ReLU(True),
# 输出: 128 x 16 x 16
nn.ConvTranspose2d(128, 64, 4, 2, 1, bias=False),
nn.BatchNorm2d(64),
nn.ReLU(True),
# 输出: 64 x 32 x 32
nn.ConvTranspose2d(64, img_channels, 4, 2, 1, bias=False),
nn.Tanh()
# 输出: 3 x 64 x 64
)
判别器网络设计
判别器区分真实和生成图像,设计要点:
- 使用卷积层逐步下采样
- LeakyReLU 激活避免梯度消失
- 输出通过 Sigmoid 得到 0 - 1 的判别概率
class Discriminator(nn.Module):
def __init__(self, img_channels=3):
super().__init__()
self.main = nn.Sequential(
# 输入: 3 x 64 x 64
nn.Conv2d(img_channels, 64, 4, 2, 1, bias=False),
nn.LeakyReLU(0.2, inplace=True),
# 输出: 64 x 32 x 32
nn.Conv2d(64, 128, 4, 2, 1, bias=False),
nn.BatchNorm2d(128),
nn.LeakyReLU(0.2, inplace=True),
# 输出: 128 x 16 x 16
nn.Conv2d(128, 256, 4, 2, 1, bias=False),
nn.BatchNorm2d(256),
nn.LeakyReLU(0.2, inplace=True),
# 输出: 256 x 8 x 8
nn.Conv2d(256, 512, 4, 2, 1, bias=False),
nn.BatchNorm2d(512),
nn.LeakyReLU(0.2, inplace=True),
# 输出: 512 x 4 x 4
nn.Conv2d(512, 1, 4, 1, 0, bias=False),
nn.Sigmoid()
# 输出: 1 x 1 x 1
)
损失函数选择
基础 GAN 使用二元交叉熵 (BCELoss),但存在训练不稳定的问题。Wasserstein GAN(WGAN) 通过以下改进提升稳定性:
- 使用 Wasserstein 距离衡量分布差异
- 移除判别器最后的 Sigmoid
- 采用梯度惩罚 (GP) 替代权重裁剪
# WGAN-GP 损失函数实现
def compute_gradient_penalty(D, real_samples, fake_samples):
# 随机插值
alpha = torch.rand(real_samples.size(0), 1, 1, 1).to(device)
interpolates = (alpha * real_samples + (1 - alpha) * fake_samples).requires_grad_(True)
d_interpolates = D(interpolates)
# 计算梯度
gradients = torch.autograd.grad(
outputs=d_interpolates,
inputs=interpolates,
grad_outputs=torch.ones_like(d_interpolates),
create_graph=True,
retain_graph=True,
only_inputs=True
)[0]
# 梯度惩罚项
gradient_penalty = ((gradients.norm(2, dim=1) - 1) ** 2).mean()
return gradient_penalty
训练优化
学习率调整
使用 Adam 优化器,典型参数:
- 生成器学习率:0.0001
- 判别器学习率:0.0001
- β1=0.5, β2=0.999
模式崩溃应对
现象:生成器只产生少量模式样本
解决方案:
- 增加噪声维度
- 使用小批量判别(minibatch discrimination)
- 调整学习率或优化器参数
评估指标
FID(Frechet Inception Distance)
衡量生成图像与真实图像在特征空间的分布距离,值越小越好。计算步骤:
- 用 Inception-v3 提取特征
- 计算两个特征分布的均值和协方差
- 计算 Frechet 距离
IS(Inception Score)
同时考虑图像质量和多样性,基于分类器的预测结果计算。
生产环境建议
计算资源
- 64×64 图像:单卡 GPU(如 RTX 2080)可训练
- 256×256 图像:需要多卡并行
分布式训练
使用 PyTorch 的 DistributedDataParallel:
torch.distributed.init_process_group(backend='nccl')
model = DDP(model, device_ids=[local_rank])
伦理考量
- 生成人脸需明确标注为 AI 生成
- 避免用于伪造身份等非法用途
- 训练数据需获得合法授权
延伸思考
- 如何将 DCGAN 扩展到更高分辨率 (如 512×512) 的人脸生成?
- 在有限计算资源下,有哪些技巧可以加速 GAN 训练?
- 除了 FID 和 IS,还有哪些评估生成图像质量的方法?
正文完
