共计 1357 个字符,预计需要花费 4 分钟才能阅读完成。
为什么我们需要语义控制?
在扩散模型中,生成图像的过程是通过逐步去噪实现的。但单纯去噪很容易导致生成的图像虽然看起来自然,却与输入的文本描述(prompt)不符。这就是语义控制的重要性——我们需要在图像的自然度和语义一致性之间找到一个平衡点。

早期的 classifier guidance 方法虽然有效,但它需要一个额外的分类器模型,这大大增加了实现的复杂度。而 classifier-free guidance(cfg) 则巧妙地去掉了这个额外分类器,直接在训练时通过随机丢弃文本条件来学习有条件和无条件两种情况下的噪声预测。
cfg 的数学原理
cfg 的核心思想其实很简单:我们同时计算有条件(conditional)和无条件(unconditional)的噪声预测,然后把它们按一定比例混合。这个比例就是 guidance scale 参数。
数学表达式为:
$$\epsilon_{\theta}(x_t|c) = \epsilon_{\theta}(x_t|\emptyset) + s \cdot (\epsilon_{\theta}(x_t|c) – \epsilon_{\theta}(x_t|\emptyset))$$
其中:
– $\epsilon_{\theta}(x_t|c)$ 是最终使用的噪声预测
– $\epsilon_{\theta}(x_t|\emptyset)$ 是无条件预测
– $\epsilon_{\theta}(x_t|c)$ 是条件预测
– $s$ 就是 guidance scale
代码实现
import torch
import torch.nn as nn
class DiffusionModel(nn.Module):
def __init__(self):
super().__init__()
# 模型定义
self.unet = UNet() # 假设已经定义了 UNet
def forward(self, x, t, c=None):
# 无条件预测
uncond_pred = self.unet(x, t, None)
if c is None:
return uncond_pred
# 条件预测
cond_pred = self.unet(x, t, c)
# 计算 cfg
noise_pred = uncond_pred + guidance_scale * (cond_pred - uncond_pred)
return noise_pred
guidance scale 的影响
guidance scale 参数对生成效果有很大影响:
| scale 值 | 语义一致性 | 图像自然度 | 适用场景 |
|---|---|---|---|
| 1.0 | 低 | 高 | 创意生成 |
| 3.0 | 中 | 中 | 一般使用 |
| 7.0 | 高 | 低 | 精准控制 |
常见问题与优化
-
过饱和问题 :当 guidance scale 过大时,图像容易出现色彩过饱和。解决方法是在训练时对预测值进行 clipping。
-
显存优化 :在生产环境中,可以通过以下方式优化显存:
- 使用梯度检查点
- 采用混合精度训练
- 分批处理条件和非条件预测
思考题
- 如何设计动态 guidance scale 策略,使其在采样过程中自动调整?
- cfg 方法是否可以应用于其他生成模型,如 GAN 或 VAE?
- 在保持语义一致性的前提下,还有哪些方法可以进一步提升图像质量?
结语
cfg 是扩散模型中一个简单却强大的技术,通过本文的介绍,希望你能理解其工作原理并掌握调参技巧。记住,没有放之四海皆准的最佳参数,关键是根据你的具体需求找到合适的平衡点。
