Skip to main content

CS231n Lecture 14: Generative AI II

·370 words·2 mins· loading · loading ·
Author
Tab_1bit0
咕咕咕

Lecture 13
#

Generative Adversarial Networks 生成对抗网络
#

它不要求对 p(x) 进行建模,但是允许从 \(x_i\sim p_{\text{data}}(x)\) 抽选样本数据。

引入可以直接采样z (一般服从标准正态分布),通过generator生成\(x_{\text{fake}}=G(z)\)。之后为了辨别生成图片画的像不像,引入判别器\(D(x)=P(x\text{ is true})\)

两边同时升级,最终希望:

\[p_G=p_{\text{data}}\]

即重建图片还原原图片。

minimax 目标
#

\[ \min_G\max_D V(G,D) \]

\[ V(G,D)= \mathbb E_{x\sim p_{\text{data}}}[\log D(x)] + \mathbb E_{z\sim p(z)} [\log(1-D(G(z)))] \]
  • 判别器D希望最大值在 \(D(x)=1\),\(D(G(z))=0\),即可以判别图片的真伪
  • 生成器G希望 \(D(G(z))\to1\),也就是让假图骗过判别器。

训练过程
#

  • 固定 \(G\),训练 \(D\) 分辨真假。
  • 固定 \(D\),训练 \(G\) 欺骗 \(D\)。
  • 不断重复。
    • 判别器对 \(V\) 做梯度上升,而生成器对 \(V\) 做梯度下降,loss不一定稳定。

Non-saturing loss
#

问题:开始时生成器容易梯度消失

训练初期,生成器画得非常糟,判别器很容易发现;而

(假设最后一层是Sigmoid函数)那么 \(D(G(z))\approx0\) 时由于函数相关性质,梯度也接近 0。

解决:实际训练时生成器最小化:\(L_G^{\text{NS}}=-\mathbb E_z[\log D(G(z))]\),对D的训练不改变

这样并不改变对G的期待,但是可以给予更大的早期梯度。

理论理解
#

固定生成分布 \(p_G\),对每个位置 \(x\),判别器需要最大化:

\[ p_{\text{data}}(x)\log D(x) + p_G(x)\log(1-D(x)) \]

求导并令其为 0,可得到最优判别器:

\[ D_G^*(x)= \frac{p_{\text{data}}(x)} {p_{\text{data}}(x)+p_G(x)} \]

把最优判别器代回目标,可以得到:

\[V(G,D_G^*)=-\log4+2\,\mathrm{JS}\left(p_{\text{data}}\Vert p_G\right)\]

JS divergence 永远非负,而且只有两个分布完全相同时等于 0。因此全局最优点为:

\[ p_G=p_{\text{data}}\]

此时:

\[D^*(x)=\frac12\]

意义是判别器无法识别真假,但理论不等于实际训练一定收敛。

  • 神经网络容量有限,未必能表示理论上的最优 \(G\) 和 \(D\)。
  • 数据有限,只能看到经验分布。
  • 梯度交替更新不保证到达博弈均衡。
  • 判别器过强可能造成生成器梯度太弱。
  • 生成器可能只生成少数几类结果,即 mode collapse。

实际架构
#

  • DCGAN 的生成器与判别器都主要使用卷积网络
    • 它的重要意义是证明 GAN 不仅能处理玩具数据,也能在真实图像上生成有意义的结果。
  • StyleGAN 不只是把 \(z\) 从网络开头输入一次,而是将潜变量变成不同层级的 style,再注入生成器的多个层。
    • \(\operatorname{AdaIN}(x,w,b)_i=w_i\frac{x_i-\mu(x)}{\sigma(x)}+b_i\)

潜空间插值
#

\(z_t=t z_0+(1-t)z_1\) 再生成 \(x_t=G(z_t)\)

t 连续变化时,图像也可以平滑变化。这说明生成器学到的不是“背诵训练图片”,而是一个具有连续结构的图像流形

Diffusion Models
#

考虑(默认用标准正态分布)用噪声分布生成 z,设置noise levels t 控制噪声化的程度,从原始数据 x 得到噪声处理过的 x_t

训练一个神经网络,用来通过 \(f_\theta(x_t, t)\),从噪点还原图片。

Rectified Flow
#

训练过程:

for x in dataset:
    z = torch.randn_like(x)
    t = random.uniform(0, 1)
    xt = (1-t)*x + t*z
    v = model(xt, t)
    loss = (z-x-v).square().sum()

采样过程:

设置步数 T,以 1/T 为步长迭代t,并以 v_t/T 为步长迭代并得到最终的x

sample = torch.randn(x_shape)
for t in torch.linspace(1, 0, num_steps):
    v = model(sample, t)
    sample = sample - v/num_steps

Conditional Rectified Flow
#

通过条件约束来引导x落在某个范围内。

Classifier-Free Guidance (CFG)
#

for (x, y) in dataset:
    z = torch.randn_like(x)
    t = random.uniform(0, 1)
    xt = (1-t)*x + t*z
    if random.random() < 0.5: y = y_null # 有0.5的概率使x向条件y偏移
    v = model(xt, y, t)
    loss = (z-x-v).square().sum()
sample = torch.randn(x_shape)
for t in torch.linspace(1, 0, num_steps):
    vy = model(sample, y, t)
    v0 = model(sample, y_null, t)
    # Doubles the cost of sampling
    v = (1+w) * vy - w*v0 # points more toward p(x|y)
    sample = sample - v/num_steps

Classifier-Free 是因为我们不需要训练模型计算分类 p(y|x),以及根据此决定梯度更新方向

Optimal Prediction
#

理论上,能得到x_t(x, z) 不止有一对;需要对结果取平均得到最优预测

\(v^*(x_t,t,y)=\mathbb E[z-x\mid x_t,t,y]=\frac{x_t-\mathbb E[x\mid x_t,t,y]}{t}\)

  • t=1x_t 在终点位置,只需要求 p_data 平均
  • t=0x_t 在起点位置,只需要求 p_noise 平均
  • 对于中间部分难求的Solution: 对 t Use a non-uniform noise schedule
    • 原因:后验分布可能复杂、多峰,而且会随 \(x_t\) 剧烈变化,因此最难学习。
    • 非均匀分布(比如sigmoid函数)可以使训练更经常采到中等噪声,把训练资源放在最复杂最影响生成质量的区域
    • 再比如,For high-res data, often shift to higher noise to account for pixel correlations

Latent Diffusion Models (LDMs)
#

alt text

结合VAE训练encoder+decoder,结合GAN训练逼真性(解决输出模糊的问题)

Modern LDM pipelines use VAE + GAN + diffusion!

Diffusion Transformers
#

alt text

进一步应用于 Text to Image / Videos 等。

通过蒸馏 (Distillation) 减少重复跑diffusion models的次数步数。

Generalized Diffusion 广义Diffusion
#

alt text

选择这些函数的依据数学形式