在佛罗伦萨这座艺术之城里,住着两位亦敌亦友的对手——赝品画师“小奇”和艺术鉴定师“老甄”。小奇毕生的心愿是画出以假乱真的画作,老甄的日常则是揭穿每一幅赝品。两人在一间画坊里日复一日地过招:小奇画出一幅,老甄立刻指出破绽;小奇记下教训回来重画,老甄也磨炼出更毒辣的眼力。这样你追我赶多年后,小奇的画技突飞猛进,老甄的出错率越来越高,直到某一天,老甄看着小奇的新作脱口而出:“这……这不是我在博物馆见过的那幅真迹吗?” 这个故事听起来像武侠小说,但它正是生成对抗网络(GAN)的缩影。而 DCGAN(深度卷积生成对抗网络),就是给“小奇”换上最专业的画布与画笔,让这场博弈从盲人摸象变成真正的艺术修炼。本文将带你走进 DCGAN 的世界,看它如何用卷积搭建生成器与判别器,如何靠批量归一化和 LeakyReLU 驯服训练过程,又是如何凭空画出逼真的人脸。

岗位关联

掌握 DCGAN 是理解生成式 AI 的必修课——它奠定了 StyleGAN、Stable Diffusion 等主流图像生成模型的技术基石,是 AI 绘画工程师与大模型训练师的看家本领。

目录
  1. 可视化演示
  2. GAN 基础
  3. DCGAN 架构
  4. 关键技术
  5. 训练技巧
  6. 图像生成
  7. 意义局限
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

本节配有交互动效(进入视口后自动加载,约 3KB)。

DCGAN架构:生成器(上采样) vs 判别器(下采样) 生成器 Generator判别器 Discriminator生成器 Generator生成器 Generator判别器 Discriminator生成器 Generator 生成器 Generator判别器 Discriminator生成器 Generator生成器 Generator判别器 Discriminator生成器 Generator

GAN 基础

在艺术之城的那个画坊里,小奇(生成器)的工作是把一团毫无章法的草稿(随机噪声)变成看起来真实的画作;老甄(判别器)的工作则是回答“这幅画是真迹还是赝品?”这就是 GAN 的两位主角——生成器 G 和判别器 D。小奇要让老甄认不出假画,老甄则要让自己永远火眼金睛,两人于是陷入一场永无止境的“猫鼠游戏”,这正是 GAN 最迷人的对抗思想。

从故事到数学,这场博弈可以被写成一个巧妙的“胜负记分牌”。判别器想最大化自己的辨识正确率,生成器想最小化自己被识破的概率,于是就有了 GAN 的核心目标函数:

就这样,两个对手共用一个记分牌,在无数轮比拼中,小奇的画技被一点一点逼了出来。这个故事的底层逻辑正是 GAN 的第一性原理——最好的造假者,是被最严苛的鉴定师练出来的。原始 GAN 用全连接网络实现这对师徒,画出来的作品总是一团迷雾,于是 DCGAN 的登场就顺理成章了。

min⁡Gmax⁡DV(D,G)=Ex∼pdata[log⁡D(x)]+Ez∼pz[log⁡(1−D(G(z)))]\displaystyle \min_G \max_D V(D,G) = \mathbb{E}_{x \sim p_{data}}[\log D(x)] + \mathbb{E}_{z \sim p_z}[\log(1 - D(G(z)))]
这个公式是 GAN 的“宪法”:判别器 D 努力把真画判为 1、假画判为 0;生成器 G 则努力让 D 把假画误判为 1。两者在同一把尺子上互相拉扯。
  1. min-max 双层博弈外层 $\min_G$ 表示生成器希望整个目标函数越小越好,内层 $\max_D$ 表示判别器希望它越大越好,两者针锋相对。
    min⁡Gmax⁡D\displaystyle \min_G \max_D
  2. 真实样本打分$x \sim p_{data}$ 表示从真实画作分布中抽样,$\log D(x)$ 是判别器给真画打高分的收益——真画被认出来应该受到奖励。
    Ex∼pdata[log⁡D(x)]\displaystyle \mathbb{E}_{x \sim p_{data}}[\log D(x)]
  3. 假样本惩罚$z \sim p_z$ 是生成器的草稿噪声,$G(z)$ 是生成的假画,$D(G(z))$ 是判别器给假画的分数,$\log(1 - D(G(z)))$ 在假画被识破时会变大,从而惩罚生成器。
    Ez∼pz[log⁡(1−D(G(z)))]\displaystyle \mathbb{E}_{z \sim p_z}[\log(1 - D(G(z)))]

DCGAN 架构

初始的 GAN 可以理解为小奇在画布上“闭眼乱泼墨”——它用全连接网络把 100 维噪声直接映射到像素上,画出来的是模糊的马赛克,既没有轮廓也没光影。2015 年,Radford 等人提出 DCGAN,核心思想只有一句话:让小奇与老甄都用“卷积画笔”,彻底告别全连接层。画师不再是抽象派乱涂,而是一层一层构图:先铺底色,再勾轮廓,最后刻画细节。

DCGAN 的判别器使用步幅卷积从细到粗地“俯瞰”画面:每次移动卷积核跳过若干像素,画面尺寸逐渐减半,特征越来越抽象。生成器则使用转置卷积反着来:从 4×4 的“草图”开始,逐层放大到 64×64 的完整画作。转置卷积的每一层相当于画家把草图中的每一个抽象笔触“放大”成一片具体的色彩区域。输出尺寸公式为:

告别全连接层的 DCGAN,让小奇的画不再随机泼墨,而是拥有了清晰的层次感——从 4×4 草稿到 64×64 成图,每一步都踩在卷积的节拍上。这正是“深度卷积”四个字的含义:用卷积的语言画画,画出来的东西才真的有“骨骼”。

sout=(sin−1)×stride−2×padding+kernel_size\displaystyle s_{\text{out}} = (s_{\text{in}} - 1) \times \text{stride} - 2 \times \text{padding} + \text{kernel\_size}
这个公式好比在画布上铺瓷砖:stride 决定每次手伸多长,padding 决定四周留不留白边,kernel_size 决定每块瓷砖的尺寸。三者配合,就能精确算出画布最终被铺成多大。
  1. 输入尺寸$s_{\text{in}}$ 是前一层特征图的一边长,比如初始草图 4×4 中的 4。
    sout=(sin−1)\displaystyle s_{\text{out}} = (s_{\text{in}} - 1)
  2. 步幅缩放乘以 $\text{stride}$,每次转置卷积把特征图放大约 stride 倍,这是“从草图到大幅画作”的关键一步。
    (sin−1)×stride\displaystyle (s_{\text{in}} - 1) \times \text{stride}
  3. 边界修正减去 $2 \times \text{padding}$ 的白边,加上 $\text{kernel\_size}$ 得到最终边长,组合起来就是放大后的画布尺寸。
    (sin−1)×stride−2×padding+kernel_size\displaystyle (s_{\text{in}} - 1) \times \text{stride} - 2 \times \text{padding} + \text{kernel\_size}

关键技术

换了画笔之后,小奇遇到了新麻烦:颜料容易飞溅,画面忽亮忽暗;画错一笔,整个画面就死黑一片。DCGAN 的工程师们对症下药,献上三样法宝。

第一样是批量归一化,它像一个自动调色的调色盘:每当一批画作堆在一起时,先把所有颜料(特征)的亮度拉回均值为 0、方差为 1 的标准状态,再让网络自己学习合适的偏移和缩放。

第二样法宝是 LeakyReLU 激活函数。之前的 ReLU 像一个“单向排水管”:正水流过没问题,负值全部堵死,梯度为零、神经元死亡。LeakyReLU 在负半轴留了一条细缝,让信号总能渗过去。

第三样法宝是 Adam 优化器。它像一位聪明的能量调度师,为每个参数单独设计步长:梯度大的地方小步慢走,梯度小的地方大步快跑,自带“动量记忆”防止来回震荡。配合 $\text{lr}=0.0002$ 的小学习率与 (0.5, 0.999) 的 betas 参数,加上标准差为 0.02 的权重初始化,训练过程就像画家被按住手腕慢慢描线——虽然慢,但笔笔扎实。

x^=x−μBσB2+ϵ×γ+β\displaystyle \hat{x} = \frac{x - \mu_B}{\sqrt{\sigma_B^2 + \epsilon}} \times \gamma + \beta
这个公式好比把一锅浓汤先尝一尝咸淡(减去均值、除以方差),再按厨师口味加盐加味精($\gamma$ 和 $\beta$)。$\epsilon$ 是防止“淡到分母为零”的保险丝。
  1. 中心化分子 $x - \mu_B$ 把这一批数据的均值 $\mu_B$ 减掉,汤的咸淡被校准到“零基线”。
    x−μB\displaystyle x - \mu_B
  2. 标准化除以标准差 $\sqrt{\sigma_B^2 + \epsilon}$,把汤的浓度压到统一水平,梯度在深层网络中传递时就不会忽大忽小。
    x−μBσB2+ϵ\displaystyle \frac{x - \mu_B}{\sqrt{\sigma_B^2 + \epsilon}}
  3. 恢复表示能力$\times \gamma + \beta$ 是网络自己学习的缩放与偏移,决定“这锅汤最终该是什么口味”。
    ×γ+β\displaystyle \times \gamma + \beta
LeakyReLU(x)={xif x>00.2xotherwise\displaystyle \text{LeakyReLU}(x) = \begin{cases} x & \text{if } x > 0 \\ 0.2x & \text{otherwise} \end{cases}
负半轴的 0.2 就像排水管的防堵孔,永远留一道小水流,让梯度在负区间也能缓慢流动,从而救活那些“装死”的神经元。
  1. 正半轴原样通过当 $x > 0$ 时输出 $x$ 本身,信息无损。
    xif x>0\displaystyle x \quad \text{if } x > 0
  2. 负半轴小流量当 $x \le 0$ 时输出 $0.2x$,梯度不会完全消失,神经元的“灵魂”得以保留。
    0.2xotherwise\displaystyle 0.2x \quad \text{otherwise}

训练技巧

DCGAN 虽然比原始 GAN 听话,但训练起来仍像驯服一匹烈马。第一大难题是训练不稳定性:小奇和老甄若一方进步太快,另一方就会被彻底压垮——老甄一旦“开挂”识别率逼近 100%,小奇得到的反馈全是“你不行”,梯度消失,再也学不到东西;反向亦然,小奇太强,老甄的梯度也会乱飞。

第二大难题是模式坍缩,GAN 世界里最臭名昭著的怪病:小奇发现画太阳最容易骗过老甄,于是疯狂画同一幅太阳,丧失多样性。从统计上看,生成器变成了“复读机”,只会背诵一个样本。对付它,工程师们总结了不少土办法——打乱批次、给判别器加噪声、或者让老甄“一次看一打画”(mini-batch discrimination)。

为了让两师徒势均力敌,DCGAN 的实践守则强调:每训练一次判别器,就训练一次生成器,始终保持巅峰对决;固定学习率 0.0002 与 Adam 的 beta=0.5(默认 0.9 会让动量太大、训练震荡)。生成器的损失函数可以写成:

驯马的过程虽惊险,但当你亲眼看到损失曲线从乱成一团到逐渐对齐的那一刻,就会明白这一切付出是值得的。这些技巧的目的只有一个:让对抗这台天平始终悬在“恰好失衡”的位置上。

LG=−Ez∼pz[log⁡D(G(z))]\displaystyle \mathcal{L}_G = -\mathbb{E}_{z \sim p_z}[\log D(G(z))]
生成器的目标非常直白:让判别器给假画打出尽可能高的分。它不关心真画长什么样,只关心怎么蒙混过关——但恰恰是这种“求生欲”,逼它学会了真画的规律。
  1. 取负号负号把“最大化 D 的分数”变成“最小化损失”,方便用梯度下降统一处理。
    −Ez∼pz\displaystyle -\mathbb{E}_{z \sim p_z}
  2. 日志概率$\log D(G(z))$ 是假画被判断为真的概率的对数,数值越小说明骗术越差,损失越大。
    log⁡D(G(z))\displaystyle \log D(G(z))
  3. 期望符号$\mathbb{E}_{z \sim p_z}$ 表示对所有噪声样本求平均,衡量生成器的“平均骗术水平”。
    Ez∼pz[log⁡D(G(z))]\displaystyle \mathbb{E}_{z \sim p_z}[\log D(G(z))]

图像生成

当 DCGAN 在 CelebA 人脸数据集上迭代了若干轮之后,画坊里的成果令人惊叹:小奇从一个 100 维的随机噪声向量出发,竟然能画出逼真的人脸——五官轮廓、光影、发丝走向都像从照片里走出来。它还能画从未真实存在的卧室:床铺、窗户、台灯,每个部件都在合理的位置,虽然细节偶尔歪扭,但整体布局已经像模像样。

最让科学家着迷的是潜在空间插值。潜在空间就是小奇头脑中那个 100 维噪声向量构成的“创意宇宙”。若拿两个分别代表“男人”和“女人”的噪声向量,按比例逐步混合,画出的脸就会从男性渐渐过渡到女性。这个混合过程就是潜在空间插值:

除了插值,DCGAN 的卷积特征还能可视化:科学家把小奇内部某一层的神经元激活值提取出来,发现有的神经元专门负责“画眼镜”,有的负责“画微笑”,有的负责“画窗户”。就像画师把不同的技能刻在不同的脑区,这种可解释性在生成模型中极其罕见,也让研究者第一次摸到了神经网络的“审美直觉”。

zinterp=(1−t)⋅z1+t⋅z2,0≤t≤1\displaystyle z_{\text{interp}} = (1 - t) \cdot z_1 + t \cdot z_2, \quad 0 \le t \le 1
这个公式就像调色盘上的两管颜料从两端慢慢向中间挤,$t$ 从 0 走到 1,画面也就从 $z_1$ 的肖像平滑地变成了 $z_2$ 的肖像。
  1. 端点向量$z_1$ 和 $z_2$ 是两个随机噪声向量,代表创意宇宙中的两个锚点。
    z1,z2\displaystyle z_1, \quad z_2
  2. 比例系数$t$ 从 0 到 1,控制“偏向 $z_1$ 多一点还是 $z_2$ 多一点”。
    0≤t≤1\displaystyle 0 \le t \le 1
  3. 线性混合$(1-t)z_1 + t z_2$ 是两者的加权和,当 $t=0$ 时完全是 $z_1$,$t=1$ 时完全是 $z_2$。
    (1−t)⋅z1+t⋅z2\displaystyle (1 - t) \cdot z_1 + t \cdot z_2

意义局限

回顾这一切,DCGAN 之所以成为 GAN 家族中的里程碑,靠的不是花哨技巧,而是三条朴素军规:全卷积架构、批量归一化、LeakyReLU。它用这些简洁改动证明了卷积神经网络不仅能识别,更能生成;它让 GAN 的训练从“随缘”走向“可控”。此后几乎所有 GAN 变体(WGAN、CycleGAN、StyleGAN)都继承了它的骨架——DCGAN 是 GAN 从玄学走向工程的分水岭。

当生成分布与真实分布完全一致时,最优判别器达到一个优雅的平衡点:

然而,DCGAN 的边界同样清晰:它依然会模式坍缩,训练依然可能崩溃,生成分辨率被限制在 64×64 附近,再往上细节就糊成一团。但正是这些局限催生了 WGAN 对稳定性的重构、StyleGAN 对可控性的革新。理解了 DCGAN 的光荣与边界,才算真正拿到走进生成式 AI 大门的钥匙。

D∗(x)=pdata(x)pdata(x)+pg(x)=12当 pg(x)=pdata(x)\displaystyle D^*(x) = \frac{p_{data}(x)}{p_{data}(x) + p_g(x)} = \frac{1}{2} \quad \text{当 } p_g(x) = p_{data}(x)
当小奇的画技与真迹难分伯仲时,老甄的鉴别能力退化到“抛硬币”——每张画猜对的概率恰好是 50%。这是 GAN 对抗的终极和谐:最厉害的造假者让最厉害的鉴定师“失业”。
  1. 最优判别器$D^*(x)$ 表示理论上的最佳鉴定师,它根据真实分布和生成分布的概率密度之比给画面打分。
    D∗(x)=pdata(x)pdata(x)+pg(x)\displaystyle D^*(x) = \frac{p_{data}(x)}{p_{data}(x) + p_g(x)}
  2. 分布相等当 $p_g(x) = p_{data}(x)$ 时,分子分母相等,比值恰好是 1/2。
    pg(x)=pdata(x)\displaystyle p_g(x) = p_{data}(x)
  3. 五五开局面$D^*(x)=1/2$ 意味着判别器完全无法区分真伪,只能抛硬币,对抗达到纳什均衡。
    =12\displaystyle = \frac{1}{2}

AI 应用场景

AI 绘画工具的图像生成管线

阶段:模型训练与生成

解决的问题:传统图像素材生产依赖设计师手工绘制或模板拼贴,成本高且难以规模化。DCGAN 验证了“从噪声直接生成逼真图像”的可行性,为如今 AI 绘画工具(如 Stable Diffusion 的图像生成管线)提供了最早的工程范式——先用生成网络产生候选图,再用判别网络筛选质量。

具体案例:某电商平台希望自动生成服装海报素材,早期方案需要设计师手绘上千张模特图,周期以月计。基于 DCGAN 架构训练的风格化生成器,可从随机向量批量产生模特试穿效果图,设计师只需在候选图中挑选微调,效率提升数十倍。

医学影像数据增强

阶段:数据预处理与增强

解决的问题:医疗影像数据集往往稀缺且受隐私限制,传统旋转、翻转等几何增强只能提供低层次变体。DCGAN 能生成具有真实解剖结构的合成影像,从语义层面扩充训练集,缓解小样本模型的过拟合问题。

具体案例:某医院只有 2000 张眼底病变照片,不足以训练稳健的诊断模型。工程师用 DCGAN 生成 8000 张逼真的病变合成图,与真实图片混合训练后,诊断模型的 AUC 提升了约 6%,且合成图通过了两位眼科医生的目视抽查。

无监督特征学习

阶段:特征提取与表示学习

解决的问题:高质量标注数据价格昂贵。DCGAN 的判别器在对抗训练中被迫学习大量图像的结构规律,这些中间卷积特征可以直接迁移到下游分类任务,减少对标注样本的依赖。

具体案例:某工业质检团队将 DCGAN 判别器的卷积层输出作为“通用视觉指纹”,用于产品表面瑕疵的零样本检测,仅用几百张标注就达到了生产线的误检率要求——这相当于把鉴定师“老甄”练就的毒辣眼力,转而用来挑出工厂里的次品。

Python 演示

python84 行
import torchimport torch.nn as nnimport torch.optim as optimfrom torchvision import datasets, transformsfrom torch.utils.data import DataLoader  class Generator(nn.Module):    """用转置卷积从噪声上采样的生成器"""    def __init__(self, latent_dim=100):        super(Generator, self).__init__()        self.main = 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, 1, 4, 2, 1, bias=False),            nn.Tanh(),        )     def forward(self, z):        return self.main(z.view(z.size(0), -1, 1, 1))  class Discriminator(nn.Module):    """用步幅卷积下采样的判别器"""    def __init__(self):        super(Discriminator, self).__init__()        self.main = nn.Sequential(            nn.Conv2d(1, 64, 4, 2, 1, bias=False),            nn.LeakyReLU(0.2, inplace=True),            nn.Conv2d(64, 128, 4, 2, 1, bias=False),            nn.BatchNorm2d(128),            nn.LeakyReLU(0.2, inplace=True),            nn.Conv2d(128, 1, 4, 1, 0, bias=False),            nn.Sigmoid(),        )     def forward(self, x):        return self.main(x).view(-1)  def train_one_epoch(G, D, loader, g_opt, d_opt, criterion, latent_dim):    for real, _ in loader:        batch = real.size(0)        real_label = torch.ones(batch)        fake_label = torch.zeros(batch)        # 判别器分成两步走:先看真画,再看假画        d_opt.zero_grad()        noise = torch.randn(batch, latent_dim)        loss_d = criterion(D(real), real_label) + criterion(D(G(noise)).detach(), fake_label)        loss_d.backward()        d_opt.step()        # 生成器要骗过判别器        g_opt.zero_grad()        noise = torch.randn(batch, latent_dim)        fake = G(noise)        loss_g = criterion(D(fake), real_label)        loss_g.backward()        g_opt.step()    return loss_d.item(), loss_g.item()  def main():    transform = transforms.Compose([        transforms.Resize(28),        transforms.ToTensor(),        transforms.Normalize([0.5], [0.5]),    ])    dataset = datasets.MNIST(root="./data", train=True, download=True, transform=transform)    loader = DataLoader(dataset, batch_size=64, shuffle=True)    G, D = Generator(), Discriminator()    g_opt = optim.Adam(G.parameters(), lr=0.0002, betas=(0.5, 0.999))    d_opt = optim.Adam(D.parameters(), lr=0.0002, betas=(0.5, 0.999))    criterion = nn.BCELoss()    for epoch in range(3):        dl, gl = train_one_epoch(G, D, loader, g_opt, d_opt, criterion, 100)        print(f"epoch {epoch}  D_loss={dl:.4f}  G_loss={gl:.4f}")  if __name__ == "__main__":    main()
目的:用 PyTorch 实现一个极简 DCGAN,在 MNIST 手写数字上完成生成器与判别器的对抗训练,并打印每轮损失,帮助理解 DCGAN 的完整训练流程。
  1. nn.ConvTranspose2d(latent_dim, 128, 4, 1, 0, bias=False)转置卷积把 100 维噪声变成首张 4×4 特征图,这是画画的第一笔“底色”。
  2. nn.BatchNorm2d(128)批量归一化,把特征分布拉回标准状态,稳定训练。
  3. nn.LeakyReLU(0.2, inplace=True)负半轴留 0.2 的坡度,防止神经元死亡。
  4. criterion(D(real), real_label) + criterion(D(G(noise)).detach(), fake_label)判别器要同时学会“给真画高分、给假画低分”,detach 避免梯度回流到生成器。
  5. loss_g = criterion(D(fake), real_label)生成器试图把假画的标签骗成“真”,这是对抗的关键一步。

常见误区

误区很多人以为用了 DCGAN 的架构,训练就稳了,能一次跑通。但实际上一换数据集或任务,仍然会梯度爆炸、模式坍缩,让人怀疑是不是自己写错了代码。

正解DCGAN 只是通过全卷积、批量归一化与 LeakyReLU 把训练难度从“地狱”降到“困难”,并没有从根本上解决对抗博弈的不稳定性。它更像一个经验证的脚手架,而不是万能保险锁——正如给画师换了再好的画笔,也不能保证每幅画都成杰作。

为何常见:人们看到 DCGAN 在 CelebA 上的惊艳效果,容易被“只要按这个配方来就能成功”的错觉误导,忽略了论文背后的反复调参与运气成分。

误区觉得要让两个网络都尽可能强,才叫健康的对抗,于是把判别器训到准确率 99%,结果生成器梯度消失,完全停止学习。

正解两人过招讲究旗鼓相当。判别器太强,生成器得到的反馈全是“0“,毫无改进信号;判别器太弱,生成器的骗术没有压力。实践中要维持适度失衡,甚至让生成器偶尔领先——最好的画师,往往是在鉴定师”差一点点识破”的边界线上成长起来的。

为何常见:直观上觉得“更强=更好”,忽略了对抗训练的本质是一个动态平衡系统,而不是单方面的能力竞赛。

误区既然 LeakyReLU 比 ReLU 好,那负斜率改成 0.9 岂不是更安全?训练应该更稳定、效果更好。

正解负斜率过大时,激活函数在负半轴会把噪声梯度放大,导致特征分布被稀释,模型学不到关键的判别模式。DCGAN 论文默认 0.2 是经验调优的结果,并非越大越好——排水管留一道细缝即可,凿开一扇大门反而会发洪水。

为何常见:没有理解 LeakyReLU 的初衷只是“保留小流量梯度”,而不是“完全放行”。

误区批归一化既然是关键配置,那应该每一层都加,尤其是判别器的输入层和生成器的输出层,这样效果一定更好。

正解DCGAN 原文明确指出,判别器的输入层与生成器的输出层不适合加 BN。输入层加 BN 会破坏原始图像的真实分布信息,输出层加 BN 会让生成图像出现“块状伪影”——就像给一幅画的画框也刷了颜料,反而毁了整幅作品。

为何常见:把技巧当成万能公式,忽略了技巧的适用边界和论文中的细节描述。

误区看到人脸生成效果很好,以为把生成器的通道数加倍,就能生成 4K 高清图,于是把分辨率调到 256×256 甚至更高。

正解DCGAN 输出的默认分辨率是 64×64,超出后容易出现棋盘伪影和纹理崩溃。高分辨率生成需要更复杂的架构(分层生成、渐进增长),这正是后来 PGGAN、StyleGAN 等模型存在的理由——画布越大,对笔触和构图的要求是指数级上升的。

为何常见:混淆了“擅长生成”与“擅长生成高清图”两个概念,忽略了分辨率对显存和训练稳定性的双重约束。

面试题

Q1. DCGAN 的生成器主要使用哪种卷积层把低分辨率特征图放大为高分辨率图像?

单选题 · easy

  • A.标准卷积层
  • B.转置卷积层← 正确答案
  • C.空洞卷积层
  • D.深度可分离卷积层

答案:B。生成器需要从 4×4 的草图放大到 64×64 的成图,转置卷积正是实现上采样、给“像素画布”填色的画笔。标准卷积会缩小特征图,空洞卷积用于扩大感受野,深度可分离卷积用于压缩计算量。

Q2. 在 DCGAN 中,判别器使用 LeakyReLU 的主要目的是什么?

单选题 · easy

  • A.加快前向传播速度
  • B.让负半轴保留小梯度,防止神经元死亡← 正确答案
  • C.让输出分布满足高斯分布
  • D.减小模型参数量

答案:B。ReLU 在负半轴直接截断,导致梯度为 0,神经元“装死”。LeakyReLU 在负半轴保留 0.2 的小斜率,让梯度始终有细流通过,维护对抗训练的稳定性——就像排水管永远留一道缝。

Q3. DCGAN 论文中的“向量算术”实验(戴眼镜的男人减去不戴眼镜的男人,加上不戴眼镜的女人,得到戴眼镜的女人)证明了什么?

单选题 · mid

  • A.生成器画的人脸有 50% 概率是男性
  • B.潜在空间中的特征方向具有可操作性,向量加减能控制语义属性← 正确答案
  • C.判别器能准确识别性别
  • D.批量归一化能编码性别信息

答案:B。向量算术实验说明潜在空间存在语义方向——“眼镜”“性别”等属性被编码在不同方向上,这是潜在空间可解释性的经典证据,也为后来的属性编辑生成模型(如 StyleGAN)奠定了基础。

Q4. DCGAN 相比原始 GAN 的主要架构改进有哪些?

多选题 · mid

  • A.用全连接层替换全卷积层
  • B.用步幅卷积替代池化层进行上下采样← 正确答案
  • C.在生成器和判别器中广泛使用批量归一化← 正确答案
  • D.判别器使用 LeakyReLU 而非 ReLU← 正确答案

答案:BCD。DCGAN 核心改进是“全卷积”:去掉全连接、用步幅卷积做下采样、转置卷积做上采样;生成器用 ReLU,判别器用 LeakyReLU;除输入输出层外都加批量归一化。A 说反了,其余三个都是论文中的关键改动。

Q5. 判别器输入层不能加批量归一化的原因是什么?

单选题 · hard

  • A.输入层加 BN 会让模型无法收敛
  • B.输入层加 BN 会破坏原始数据的空间结构← 正确答案
  • C.输入层加 BN 会放大噪声
  • D.输入层加 BN 会使得参数过多

答案:B。批量归一化会强制把分布拉回均值为 0、方差为 1 的标准状态,但真实图像本身有原始的对比度和亮度统计。在判别器输入层加 BN 等于把“真画的质感”暴力归一化,破坏了判别器辨别真伪的关键线索。

Q6. 关于模式坍缩(Mode Collapse)的描述,正确的有?

多选题 · mid

  • A.生成器只会生成少数几种或一种相似样本← 正确答案
  • B.判别器损失持续上升是模式坍缩的特征
  • C.模式坍缩时生成样本多样性显著下降← 正确答案
  • D.模式坍缩完全由学习率过大引起

答案:AC。模式坍缩指生成器找到一条“偷懒路径”,只输出能骗过判别器的少数样本,多样性暴跌。B 中“判别器损失持续上升”更常对应训练不稳定或不收敛,并非模式坍缩的专有信号;D 过于绝对,模式坍缩与损失函数、网络容量、对抗平衡都有关系。

Q7. DCGAN 中 Adam 优化器的 betas 参数通常建议设置为多少?

单选题 · easy

  • A.(0.9, 0.999)
  • B.(0.5, 0.999)← 正确答案
  • C.(0.0, 0.9)
  • D.(0.9, 0.9)

答案:B。论文发现默认的 0.9 会让动量积累过大,导致训练震荡;改为 0.5 后动量更小、更新更稳健。记法:DCGAN 推荐 lr=0.0002,betas=(0.5, 0.999),这是复现必须要记住的数字。

Q8. DCGAN 生成的图像默认分辨率是多少?

单选题 · easy

  • A.32×32
  • B.64×64← 正确答案
  • C.128×128
  • D.256×256

答案:B。DCGAN 论文在 LSUN 和 CelebA 上均采用 64×64 输入输出,超出此分辨率后容易产生伪影和训练崩溃,这也是后来 StyleGAN 用渐进式增长提升分辨率的原因。

Q9. 关于 GAN 的目标函数 $V(D,G)=\mathbb{E}[\log D(x)]+\mathbb{E}[\log(1-D(G(z)))]$,下列理解正确的有?

多选题 · hard

  • A.判别器最大化该函数时,相当于最大化正确分类真画与假画的能力← 正确答案
  • B.生成器最小化该函数时,相当于最大化被判别器误判为真的概率← 正确答案
  • C.当生成分布等于真实分布时,最优判别器对所有样本输出 0.5← 正确答案
  • D.该目标函数保证训练一定收敛到全局最优

答案:ABC。$D$ 最大化 $V$ 能同时提升对真画的奖励 $D(x)$ 与对假画的惩罚 $1-D(G(z))$;$G$ 最小化 $V$ 等价于让 $D(G(z))$ 接近 1。分布相等时最优判别器 $D^*=0.5$。D 错误,目标函数不保证收敛,这正是 GAN 训练难的根源。

Q10. 为什么 DCGAN 的生成器输出层使用 Tanh 而不是 ReLU?

单选题 · mid

  • A.Tanh 计算速度更快
  • B.Tanh 输出范围 (-1,1),与归一化到 [-1,1] 的图像数据匹配,避免截断← 正确答案
  • C.ReLU 会导致梯度爆炸
  • D.Tanh 可以让输出自动变成灰度图

答案:B。DCGAN 把真实图像归一化到 [-1,1],Tanh 恰好输出同范围,能完整表达像素的动态范围;若用 ReLU 则输出恒非负,无法表示负值像素,等于人为截断了图像信息——就像画家只有黑色颜料,永远画不出高光。