GAN基本原理

理论推导

Posted by LT on May 27, 2019

零,参考资料

一,Introduction

Basic idea(1)

  • G generator:只学习细节,不知道全局 如果单独使用G来生成图像,VAE(variational auto-encoder)中的decoder就是我们想要的G。 VAE的过程是:input image—encoder—>code—decoder—>output image 但是这里的G有个问题:只学习细节,不知道全局(比如像素之间的相关性)。that’s to say,采用模型中的解码端作为G,本质是在生成训练集已有的数据类似的数据,无法生成训练集中没有的数据。

  • D discriminator: 只学习全局,不知道细节。 只有positive example,没有negative example。 如果单独使用D来生成图像(穷举所有的pixel?),那么不管生成什么样的图像,都会被认为是positive example。

  • 将G和D结合起来->GAN 实验证明,GAN生成的图像质量比VAE要好。

Basic idea(2)

Pdata是真实数据的分布,PG是生成数据的分布。G是生成网络Generator,D是判别网络Discriminator。开山作paper中的value function V(D, G)定义如下。(可以理解为PG和Pdata之间的divergence)

$ V(D, G) = E_{ x \sim p_{data}(x)} \log D(x)+ E_{z \sim p_z(z)} \log (1-D(G(z))) $

$ D ^* = \max_D V(D, G) $

$ G ^* = \min_G D ^* \ \ = \min_G E_{z \sim p_z(z)}\log (1-D(G(z)))
= \max_G E_{z \sim p_z(z)}\log D(G(z)) $

步骤:

  1. 初始化G和D的相关参数
  2. 先fix G 训练Discriminator,使得divergence越大越好(便于分类);
  3. 再fix D(此时V(D, G)中的第一项是常数,计算时无需考虑了)训练Generator,使得divergence越小越好。

Discriminator与binary classifier

  1. V(D, G)可以看作正例真实数据x(cover)和反例生成数据G_z(stego)之间的差距。 (多一个负号就是交叉熵)
  2. D其实就是一个二分类器(可以是使用了sigmoid作为输出的深层网络),来自Pdata的x是正例,label=1;来自PG的x’=G_z是反例,label=0。

二,Theory

  1. GAN的思想是,generator最小化生成数据和真实数据之间的Div,而discriminator想要最大化Div。了解更多
  2. 从generator角度来看,$ G^* = arg \min_G Div(P_G,P_{data}) $ (式2)。这个Div其实是JS-Div,下文细说。
  3. 怎样衡量这个$Div(P_G,P_{data})$?
    • 让D来衡量Div。 我们虽然不知道$P_{data}$和$P_G$,但是可以从这两个分布里sample,把真实数据和生成数据喂给discriminator D。
    • 理论上,D量出来的Div是JS-Div
      • 把D想要最大化的目标V写成期望形式:

      $ V = E_{x \sim P_{data}}log D(x) + E_{x \sim P_G}log (1-D(x)) $

      • 对x积分,把积分里面的每个项拿出来:

      $ V = P_{data}(x)logD(x) + P_G(x)log(1-D(x)) $

      • 要想求V的极大值,我们对让V对D的偏导数=0。算得

      $ D^*= \frac{P_{data}}{P_{data}+P_G} $。

      把$D^{*}$代入V中,发现此时的V,就是$P_{data}$和$P_G$的JS-divergence。

    • 实践上,V的表示,用sample来代替期望。用V替换式2里的Div即可。

    $V^{\sim}= \frac{1}{m} \sum_{i=1}^{m}( log D(x)+log(1-D(G(z))) ) $

  4. 两个问题
    • Discriminator能衡量data和G(z)的Div吗?
      • 证据1 有些人用GAN做pre-training,训好的D直接拿来用。说明D没有烂掉。
      • 证据2 如果D想衡量data和G(z)的Div,那么,用前一次的D(基于前一次G)来初始化下一个D的参数,这样就不太对。现在的G已经变了,我要以前的D有何用?然而事实证明,这样做有用。(可能因为,G改变很小)。
    • D可以最大化JS-Div。那么,G真的是在最小化JS-Div吗?答曰:理论上不是。实践中,采取一些训练手段,假设它是。
      • 例子:G1更新为G2。如果G2与G1差距太大,那么G2最小化的就不是JS-Div。
      • 这个问题,可以通过限制训练次数来解决。(D训练快一些,G训练慢一些。理论上,每次重新训练D,train到底。达到极大值的V,才是JS-Div,才能给G)
        • 对于判别器,理论上,我们需要让它训练非常多次,直到判别器找到的𝐷0∗是ArgMax V(G,𝐷)的全局最大解,这样𝐷0∗在传给生成器时才能保证V(G,𝐷)是𝑃𝑑𝑎𝑡𝑎与𝑃𝐺之间的 JS Div 距离;
        • 而对于生成器,限制它只训练 1 次。这是为了防止训练完一次后V(G,𝐷)发生变化导致𝐷0∗不再是ArgMax V(G,𝐷)的解。
        • 但是,在实际操作中,我们不会非常多次地训练判别器,因为找到真正的解𝐷0∗需要的训练次数太多,为了减小训练代价,我们只会训练 k 次,找到𝐷0∗的近似解𝐷0~即可停止。
        • 所以,在实际的应用中,我们计算的都是 JS Div 的近似值,最终 GAN 学到的是近似分布而不是数据的真实分布。

三,其它问题、原因、解决方法