条件GAN与Pix2Pix 本节摘要:2014—2017 年生成式 AI 的第一个大解锁,是控制 GAN 生成什么——贴一个标签、一张图、一句话都行。Pix2Pix(Isola 等 2017)做了图像版:把对抗损失从「无条件生成」升级为「图像到图像翻译」,用 U-Net 生成器 + PatchGAN 判别器 + L1 损失,实现线稿转照片、地图转航拍、白天转黑夜。哪怕到了 2026 年,在窄领域、有成对数据的图像到图像任务上,Pix2Pix 依然击败从零训练的通用文生图模型——因为它手里有「成对监督」这一最直接的信号。
本节摘要:2014—2017 年生成式 AI 的第一个大解锁,是控制 GAN 生成什么——贴一个标签、一张图、一句话都行。Pix2Pix(Isola 等 2017)做了图像版:把对抗损失从「无条件生成」升级为「图像到图像翻译」,用 U-Net 生成器 + PatchGAN 判别器 + L1 损失,实现线稿转照片、地图转航拍、白天转黑夜。哪怕到了 2026 年,在窄领域、有成对数据的图像到图像任务上,Pix2Pix 依然击败从零训练的通用文生图模型——因为它手里有「成对监督」这一最直接的信号。本节讲透条件 GAN 的条件注入机制、U-Net 为何必须带跳跃连接、PatchGAN 的「局部即真实」马尔可夫假设,以及当没有成对数据时 CycleGAN 如何用循环一致性救场。
对应原课程:Phase 08 · Lesson 04 ·
conditional-gans-pix2pix(原英文phases/08-generative-ai/04-conditional-gans-pix2pix/docs/en.md)。
阅读完本节,你应当能够:
c 同时注入 G 和 D,以及为什么 D 必须判别「(x, y) 这一对是否一致」而非「y 是否真实」。一个无条件 GAN 采样出任意人脸——做演示有用,做生产没用。你真正想要的是:把线稿映射成照片、把地图映射成航拍图、把白天场景映射成黑夜、给灰度图上色。所有这些场景里,你给定一张输入图 x,要输出一张与之有语义对应的 y。而每个 x 对应多个合理的 y:MSE 会把它们压成一团浆糊;对抗损失不会,因为「看起来真」是锐利的。
条件 GAN(Mirza & Osindero,2014)给 G 和 D 都加了一个条件输入 c。Pix2Pix(Isola 等,2017)把它特化:条件是一张完整输入图,生成器是 U-Net,判别器是逐块分类器(PatchGAN),损失是「对抗 + L1」。这一配方在窄领域图像到图像翻译上至今仍优于从零训练的文生图模型,因为它是用成对数据训练的——你手里正好有你需要的那个信号。
U-Net 生成器。 关键是跨瓶颈的跳跃连接(skip connection)。在线稿转照片这种「输入与输出共享低层结构(边缘、轮廓)」的任务里,没有跳跃连接,高频细节就会消失——因为信息被迫挤过瓶颈层再还原。跳跃连接把编码器的早期特征直接送到解码器的对应层,让网络只需「在共享结构上加细节」。
PatchGAN 判别器。 不再输出单个真假分数,而是输出一个 N×N 网格,每格判别一个约 70×70 像素的感受野,再求平均。这是一个马尔可夫随机场假设:真实性是局部的。它训练更快、参数更少、输出更锐利——因为判别器可以独立地惩罚每一块的高频伪影。
为什么是 L1 而不是 L2。 L1 给出的边缘比 L2 锐利——因为 L1 的最优解是中位数,L2 的最优解是均值,而均值天生模糊。Pix2Pix 的默认 λ = 100。
💡 判别器为什么必须看输入
x? 如果D只看y,它只能判「y像不像真的」,无法判「y与x是否一致」。把(x, y)拼接后送入D,D才能惩罚「生成了一张真实但与输入无关的图」——这是 Pix2Pix 区别于普通 GAN 的命脉。
Pix2Pix 需要成对的 (x, y) 数据。CycleGAN(Zhu 等,2017)用一个额外的损失去掉了这个要求:循环一致性损失。训两个生成器 G: X → Y 和 F: Y → X,要求 F(G(x)) ≈ x 且 G(F(y)) ≈ y。这让你能在没有成对样本的情况下,把马翻译成斑马、夏天翻译成冬天。
⚠️ 2026 年,无配对图像到图像翻译主要用扩散(ControlNet、IP-Adapter)而非 CycleGAN。但「循环一致性」这个想法,几乎活在每一篇无配对领域自适应论文里。
code/main.py 在一维数据上实现一个迷你条件 GAN。条件 c 是类别标签(0 或 1),任务是:对给定类别,从其条件分布采样出样本。
def G(z, c, params): return mlp(concat([z, one_hot(c)]), params) def D(x, c, params): return mlp(concat([x, one_hot(c)]), params)
独热编码是最简单的注入方式。更大的模型会用学到的嵌入、FiLM 调制,或交叉注意力。
for step in range(steps): x, c = sample_real_conditional() noise = sample_noise() update_D(x_real=x, x_fake=G(noise, c), c=c) update_G(noise, c)
生成器必须匹配给定条件下的真实分布,而不是边缘分布。这一点是条件 GAN 与无条件 GAN 的根本区别。
for c in [0, 1]: samples = [G(noise, c) for noise in batch] mean_c = mean(samples) assert_near(mean_c, real_mean_for_class_c)
如果 G 真的「听懂」了条件,那么对每个类别,生成样本的均值应当接近该类真实分布的均值。否则说明条件被忽略了。
条件被忽略:G 学会了边缘化,D 因为条件信号弱从未惩罚。修复:让 D 更早注入条件(不只是后期层),或用投影判别器(projection discriminator,Miyato & Koyama 2018)。
L1 权重过低:G 漂移到「看起来真但不忠实于输入」的输出。Pix2Pix 风格任务从 λ ≈ 100 起步。
L1 权重过高:G 产出模糊输出,因为 L1 仍是 L_p 范数。训练稳定后逐步退火下调。
D 中真值泄漏:必须把 (x, y) 拼接送入 D,不能只送 y,否则 D 无法检查一致性。
每类独立崩塌:每个类别都可能各自崩塌,要按类别做多样性检查。
💡 条件注入的演化:独热拼接 → FiLM(逐特征仿射变换,便宜)→ 交叉注意力(Transformer 时代主流)→ ControlNet(给冻结的扩散骨干并行一个条件副本)。下一节的 StyleGAN 用 AdaIN,第 08 节的 ControlNet 用零卷积副本,都是这条演化线的产物。
| 任务 | 最优方案 |
|---|---|
| 线稿→照片,同领域,成对数据 | Pix2Pix / Pix2PixHD(依然快、依然锐利) |
| 线稿→照片,无配对 | ControlNet + Scribble 条件模型 |
| 语义分割→照片 | SPADE / GauGAN2 或 SD + ControlNet-Seg |
| 风格迁移 | 扩散 + IP-Adapter 或 LoRA;GAN 方法已是遗留 |
| 深度→照片 | Stable Diffusion + ControlNet-Depth |
| 超分辨率 | Real-ESRGAN(GAN)、ESRGAN-Plus,或 SD-Upscale(扩散) |
| 上色 | ColTran、扩散上色器,或 Pix2Pix-color |
| 白天→黑夜、季节、天气 | CycleGAN 或基于 ControlNet 的方案 |
判断标准:当你(a) 有数千成对样本、(b) 任务窄且可重复、(c) 需要快推理时,Pix2Pix 是对的工具。开放领域则扩散胜出。
在成对数据 + 窄任务的场景下,Pix2Pix 的一次性推理在延迟上比扩散快一个数量级。典型对比(单卡 L4,512²):
| 路径 | 步数 | 典型延迟 |
|---|---|---|
| Pix2Pix(U-Net 前向) | 1 | ~30 ms |
| SD-Inpaint 或 SD-Img2Img | 20 | ~1.2 s |
| SDXL-Turbo Img2Img | 1-4 | ~0.15-0.35 s |
| ControlNet + SDXL base | 20-30 | ~3-5 s |
Pix2Pix 在静态批处理下吞吐量胜出(每个请求 FLOPs 相同),扩散在质量与泛化上胜出。现代做法常常是:窄任务用 Pix2Pix 风格的蒸馏模型,长尾输入用扩散兜底。
本节产出一个选择技能文件(位于原课程 outputs/skill-img2img-chooser.md)。
skill-img2img-chooser.md:输入「任务描述、数据可用性(成对 vs 无配对、N 个样本)、延迟/质量预算」,输出:方案选择(Pix2Pix / CycleGAN / ControlNet 变体 / SDXL + IP-Adapter)、训练数据需求、推理成本、评估协议(LPIPS、FID、任务特定指标)。简单。 修改 code/main.py,加入第三个类别。确认 G 仍能把每个类别的噪声映射到正确模式。
中等。 在一维设置里把 L1 换成「感知风格损失」(例如一个冻结的小 D 当特征提取器)。它会改变条件分布的锐度吗?
困难。 在一维设置里草拟一个 CycleGAN:两个分布、两个生成器、循环损失。展示它在没有成对数据的情况下学会在两个分布间互译。
c 注入 G 和 D。(x, y) 对:否则只能判真假、不能判一致性——这是条件 GAN 的命脉。F(G(x))≈x;2026 年无配对翻译主要由扩散(ControlNet/IP-Adapter)接管,但循环一致性思想仍在。下一节,我们进入 GAN 家族的皇冠——StyleGAN:映射网络把噪声解耦成风格向量,AdaIN 在每一层注入风格,生成分辨率逐步翻倍的「渐进式」照片级人脸,至今仍是窄领域真实度的金标准。