狗都能看懂的Classifier Guidance和Classifier-free Guidance详解

条件生成模型

DDPM的提出的扩散模型已经非常强大了,但短板也很明显,没有办法按照指令控制模型生成指定的图像。往往就是你训练过什么类别,它就只会生成什么类别的图片,模型的泛化性比较差。而Guidance技术则是引导扩散模型生成指定类别的图像。那么今天来讲解一下两种Guidance方法:

  • Classifier guidance
  • Classifier-free guidance

Classifier guidance

条件生成模型,指的是给定一个条件 y y y,我们根据这个条件生成对应的内容 x x x,其概率表示为 p ( x ∣ y ) p(x|y) p(xy)。例如在文生图的场景中, y y y是文本提示词, x x x是对应的图片。根据贝叶斯公式,我们可以得到:
p ( x ∣ y ) = p ( y ∣ x ) ⋅ p ( x ) p ( y ) p(x|y) = \frac{p(y|x) \cdot p(x)}{p(y)} p(xy)=p(y)p(yx)p(x)
对其求梯度,有:

∇ x log ⁡ p ( x ∣ y ) = ∇ x log ⁡ ( p ( x ) ⋅ p ( y ∣ x ) p ( y ) ) = ∇ x ( log ⁡ p ( x ) + log ⁡ p ( y ∣ x ) − log ⁡ p ( y ) ) \begin{aligned} \nabla_x \log p(x|y) &= \nabla_x \log(\frac{p(x) \cdot p{(y|x)}}{p(y)}) \\ & = \nabla_x (\log p(x) + \log p(y|x) - \log p(y)) \\ \end{aligned} xlogp(xy)=xlog(p(y)p(x)p(yx))=x(logp(x)+logp(yx)logp(y))

我们解释一下这个公式,log的运算规律,乘法变加法,除法变减法。其中 p ( y ) p(y) p(y)是某个类别的先验概率,是一个常数,其梯度为0,所以直接忽略。可得:
∇ x p ( x ∣ y ) = ∇ x log ⁡ p ( x ) ⏟ u n c o n d i t i o n a l   s c o r e + ∇ x log ⁡ p ( y ∣ x ) ⏟ c l a s s i f i e r   g r a d i e n t (1) \nabla_x p(x|y) = \underbrace{\nabla_x \log p(x)}_{\scriptstyle{unconditional\ score}} + \underbrace{\nabla_x \log p(y|x)}_{\scriptstyle{ \quad classifier\ gradient \quad}} \tag{1} xp(xy)=unconditional score xlogp(x)+classifier gradient xlogp(yx)(1)

log ⁡ p ( x ) \log p(x) logp(x)则是原本无条件生成的梯度,即从一个噪声图直接生成图像的过程。在SDE中,对其求梯度,也就是算score,这两者也是等价的。而 log ⁡ p ( y ∣ x ) \log p(y|x) logp(yx)这一项就比较有趣了,已知生成的结果 x x x,求其是某种文本提示词的概率,那这不就是一个分类器吗?所以按照这个思路,我们用神经网络再训练一个分类器就可以了。作者在此基础上,又引入了一个控制参数 λ \lambda λ
∇ x p λ ( x ∣ y ) = ∇ x log ⁡ p ( x ) + λ ∇ x log ⁡ p ( y ∣ x ) (2) \nabla_x p_\lambda(x|y) = \nabla_x \log p(x) + \lambda \nabla_x \log p(y|x) \tag{2} xpλ(xy)=xlogp(x)+λxlogp(yx)(2)
λ = 0 \lambda = 0 λ=0,表示不加入任何条件。当 λ \lambda λ很大时,模型会产生大量附带条件信息的样本。

因此在向无条件生成模型引入条件时,我们只需要额外训练一个分类模型就可以了。这就是Classifier-Guidance。优点很明显,即**可以直接用别人训好的大数据集下的无条件生成模型,直接自己训练一个分类模型,就可以进行采样生成条件下的生成数据。**但是!这个推理过程并没有将分类模型限制在扩散模型上,所以也带来了一些问题。

我们知道在扩散模型中,模型的输入是随机噪声,然后通过逐时间片的随机去噪来生成一个真实的图像。而且Classifier Gudiance使用分类器的方式也非常“粗暴”,它是直接将分类器的梯度直接加到模型的梯度上。从公式上看,也没有限制加的时间点,那么问题就来了:

  • 在扩散模型的靠前的step中,它生成的图像的噪声是非常多的,这个分类器能够根据噪声图像预测最终图像的类别,但这些噪声图像却没有足够的信息能够让分类模型准确的预测它的类别。所以这个分类器很难训练,训练成本高。
  • 因为噪声图中包含的信息不足以正确训练分类器,因此分类器得到的参数,不一定是图像 x x x到文本 y y y的正确映射。这个错误的梯度加到生成模型上,那么训练结果反而偏离目标,直接体现的结果就是模型生成的结果不对或者没有按照文本提示生成指定的类别。这也就是Classifier-free Guidance论文中所说的对抗攻击(adversarial attack)。
  • 分类器的类别毕竟是有限集,不能涵盖全部情况,对于没有覆盖的标签类别会很不友好。而且采样的时候,需要用到两个模型,采样效率比较低。

Classifier-free guidance

面对上述Classifier Guidance的种种缺点,Classifier-free Guidance技术应运而生。

首先要提及的一点是:Classifier-Free Guidance 是一种用于扩散模型(Diffusion Models)的推理技术,而不是训练技术。它的目的是在推理阶段(生成阶段)提高生成样本的质量。但是需要注意的是其效果依赖于训练阶段的特定设置。也就代表,采用这个方法,在训练Diffusion Models的时候就需要考虑。

下面,我们从数学角度理解一下,对分类器使用贝叶斯公式:
p ( y ∣ x ) = p ( x ∣ y ) ⋅ p ( y ) p ( x ) p(y|x) = \frac{p(x|y) \cdot p(y)}{p(x)} p(yx)=p(x)p(xy)p(y)
同样对其求梯度,根据log的运算规律,乘法变加法,除法变减法。
∇ x log ⁡ p ( y ∣ x ) = ∇ x ( log ⁡ p ( x ∣ y ) + log ⁡ p ( y ) − log ⁡ p ( x ) ) ∇ x log ⁡ p ( y ∣ x ) = ∇ x log ⁡ p ( x ∣ y ) − ∇ x log ⁡ p ( x ) (3) \begin{aligned} \nabla_x \log p(y|x) &= \nabla_x(\log p(x|y) + \log p(y) - \log p(x)) \\ \nabla_x \log p (y|x) &= \nabla_x \log p(x|y) - \nabla_x \log p(x) \end{aligned} \tag{3} xlogp(yx)xlogp(yx)=x(logp(xy)+logp(y)logp(x))=xlogp(xy)xlogp(x)(3)
把式子(3)代入到公式(2)中可得:
∇ x p λ ( x ∣ y ) = ∇ x log ⁡ p ( x ) + λ ( ∇ x log ⁡ p ( x ∣ y ) − ∇ x log ⁡ p ( x ) ) = ( 1 − λ ) ∇ x log ⁡ p ( x ) ⏟ u n c o n d i t i o n a l   s c o r e + λ ∇ x log ⁡ p ( x ∣ y ) ⏟ c o n d i t i o n a l   s c o r e (4) \begin{aligned} \nabla_x p_\lambda(x|y) &= \nabla_x \log p(x) + \lambda (\nabla_x \log p(x|y) - \nabla_x \log p(x)) \\ & = \underbrace{(1-\lambda) \nabla_x \log p(x)}_{\scriptstyle{unconditional\ score}} + \underbrace{\lambda \nabla_x \log p(x|y)}_{\scriptstyle{conditional\ score}} \end{aligned} \tag{4} xpλ(xy)=xlogp(x)+λ(xlogp(xy)xlogp(x))=unconditional score (1λ)xlogp(x)+conditional score λxlogp(xy)(4)
从式(4)我们可以看出,Classifier-free Guidance其实就是条件得分(conditional score)和无条件得分(unconditional score)线性组合。

此时我们来考虑一下,不同 λ \lambda λ取值时的情况:

  • λ = 0 \lambda = 0 λ=0时,第二项完全为0,会忽略条件;
  • λ = 1 \lambda = 1 λ=1时,完全使用第二项,就是有附带条件情况下的的生成;
  • λ > 1 \lambda > 1 λ>1时,模型会优先考虑条件生成样本,并且远离无条件生成,更明确使用有条件生成;

因为Classifier-free Guidance向无条件的扩散模型中添加了一个条件信息,但是又没有像Classifier Gudiance那样添加一个显式的分类器。虽然Classifier-free Guidance的论文读起来很困难,但是它的实现方式却非常简单。

clip_model = ...  

text = "apple"  
uncond_embeddings = clip_model.text_encode("")  # 空文本编码(unconditional score)
cond_embeddings = clip_model.text_encode(text)  # 条件文本编码(conditional score)

text_embeddings = torch.cat(uncond_embeddings, cond_embeddings)  # 把它俩 concate 到一起作为控制条件

input = get_noise(...)  # 从高斯分布随机取一个跟输出图像一样 shape 的噪声图

for t in tqdm(scheduler.timesteps):

    with torch.no_grad():
        # 这里同时预测出了空文本编码的和条件文本编码的图像噪声
        noise_pred = unet(input, t, encoder_hidden_states=text_embeddings).sample

    # Classifier-Free Guidance 引导
    noise_pred_uncond, noise_pred_cond = noise_pred.chunk(2)  # 拆成无条件和有条件的噪声
    
    # 把【“无条件噪声”指向“有条件噪声”】看做一个向量,根据 guidance_scale 的值放大这个向量
    # 当 guidance_scale = 1 时,下面这个式子退化成 noise_pred_cond
    noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_cond - noise_pred_uncond)

    # 用预测出的 noise_pred 和 x_t 计算得到 x_t-1
    latents = scheduler.step(noise_pred, t, latents).prev_sample

cfg

图片来源为知乎作者蓟梗

guidance scale是一个放缩系数,这个值越大,生成的结果越倾向于输入条件,多样性会下降。越小,多样性越大。通常来讲这个值被设为 7.5 比较合适。在ComfyUI和WebUI中就是名为cfg的超参数。

Reference

classifier-free diffusion guidance(无分类器扩散引导)是一种新兴的技术,用于在无需提前训练分类器的情况下进行目标导航。 传统的目标导航技术通常需要使用先验知识已经训练好的分类器来辨别识别目标。然而,这些方法存在许多限制缺点,如对精确的先验知识的需求以及对大量标记数据的依赖。 相比之下,classifier-free diffusion guidance 可以在目标未知的情况下进行导航,避免了先验知识训练好的分类器的依赖。它的主要思想是利用传感器环境反馈信息,通过推测逐步调整来实现导航。 在这种方法中,机器人通过感知环境中的信息,例如物体的形状、颜色、纹理等特征,获取关于目标位置的信息。然后,它将这些信息与先验的环境模型进行比较,并尝试找到与目标最相似的区域。 为了进一步提高导航的准确性,机器人还可以利用扩散算法来调整自己的位置方向。通过比较当前位置的特征与目标位置的特征,机器人可以根据这些差异进行调整,逐渐接近目标。 需要注意的是,classifier-free diffusion guidance还处于研究阶段,目前还存在许多挑战问题。例如,对于复杂的环境多个目标,算法的性能可能会下降。然而,随着技术的发展,我们可以预见classifier-free diffusion guidance将会在未来的目标导航中发挥重要的作用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值