https://antkillerfarm.github.io/

GAN(续)

基本原理

上面的解释虽然通俗,却并未涉及算法的实现。要实现上述原理,至少要解决三个问题:

1.什么是伪造者。

2.什么是鉴别者。

3.如何对抗。

以下文章的组织顺序,主要参考下文:

http://kexue.fm/archives/4439/

互怼的艺术:从零直达WGAN-GP

老规矩,摘要+点评。

伪造者

伪造者在这里实际上是一种Generative算法。伪造的内容是:将随机噪声映射为我们所希望的正样本

随机噪声我们一般定义为均匀分布,于是上面的问题可以转化为:如何将均匀分布X映射为正样本分布Y

首先,我们思考一个简单的问题:如何将 U[0,1] <script type="math/tex" id="MathJax-Element-360">U[0,1]</script>映射为 N(0,1) <script type="math/tex" id="MathJax-Element-361">N(0,1)</script>?

理论上的做法是:将 XU[0,1] <script type="math/tex" id="MathJax-Element-362">X∼U[0,1]</script>经过函数 Y=f(X) <script type="math/tex" id="MathJax-Element-363">Y=f(X)</script>映射之后,就有 YN(0,1) <script type="math/tex" id="MathJax-Element-364">Y∼N(0,1)</script>了。设 ρ(x) <script type="math/tex" id="MathJax-Element-365">\rho(x)</script>是 U[0,1] <script type="math/tex" id="MathJax-Element-366">U[0,1]</script>是概率密度函数,那么 [x,x+dx] <script type="math/tex" id="MathJax-Element-367">[x,x+dx]</script> <script type="math/tex" id="MathJax-Element-368">和</script>[y,y+dy]<script type="math/tex" id="MathJax-Element-369">[y,y+dy]</script>这两个区间的概率应该相等,而根据概率密度定义, ρ(x) <script type="math/tex" id="MathJax-Element-370">\rho(x)</script>不是概率, ρ(x)dx <script type="math/tex" id="MathJax-Element-371">\rho(x)dx</script>才是概率,因此有:

ρ(x)dx=12πexp(y22)dy
<script type="math/tex; mode=display" id="MathJax-Element-12">\rho(x)dx=\frac{1}{\sqrt{2\pi}}\exp\left(-\frac{y^2}{2}\right)dy</script>

即:

x0ρ(t)dt=y12πexp(t22)dt=Φ(y)
<script type="math/tex; mode=display" id="MathJax-Element-179">\int_{0}^x \rho(t)dt=\int_{-\infty}^{y}\frac{1}{\sqrt{2\pi}}\exp\left(-\frac{t^2}{2}\right)dt=\Phi(y)</script>

其中, Φ(y) <script type="math/tex" id="MathJax-Element-180">\Phi(y)</script>是标准正态分布的累积分布函数,所以

y=Φ1(x0ρ(t)dt)
<script type="math/tex; mode=display" id="MathJax-Element-175">y=\Phi^{-1}\left(\int_0^x \rho(t)dt\right)</script>

注意到累积分布函数是无法用初等函数显式表示出来的,更不用说它的逆函数了。说白了, Y=f(X) <script type="math/tex" id="MathJax-Element-176">Y=f(X)</script>的f的确是存在的,但很复杂,以上解只是一个记号,该算的还是要用计算机算。

正态分布是常见的、相对简单的分布,但这个映射已经这么复杂了。如果换了任意分布,甚至概率密度函数都不能显式写出来,那么复杂度可想而知~

考虑到我们总可以用一个神经网络来拟合任意函数。这里不妨用一个带有多个参数的神经网络 G(X,θ) <script type="math/tex" id="MathJax-Element-177">G(X,\theta)</script>去拟合f?只要把参数$$\theta$训练好,就可以认为$Y=G(X,\theta)$了。这里的G是Generator*的意思。

正样本分布

如上所述,一般的正样本分布是很难给出概率密度函数的。然而,我们可以换个角度思考问题。

假设有一批服从某个指定分布的数据 Z=(z1,z2,,zN) <script type="math/tex" id="MathJax-Element-148">Z=(z_1,z_2,\dots,z_N)</script>,根据概率论的相关定义,我们至少可以使用离散采样的方法,根据Z中的样本分布,来近似求出Z的指定分布。下文如无特殊指出,均以Z中的样本分布来代替Z的指定分布,简称Z的分布

那么接着就有另一个问题:如何评估 G(X,θ) <script type="math/tex" id="MathJax-Element-149">G(X,\theta)</script>生成的样本的分布和Z的分布之间的差异呢?

KL散度

比较两个分布的差异的最常用指标是KL散度。其定义参见《机器学习(八)》。

JS散度

因为KL散度不是对称的,有时候将它对称化,即得到JS散度(Jensen–Shannon divergence):

JS(p1(x),p2(x))=12KL(p1(x)p2(x))+12KL(p2(x)p1(x))
<script type="math/tex; mode=display" id="MathJax-Element-22">JS\Big(p_1(x),p_2(x)\Big)=\frac{1}{2}KL\Big(p_1(x)\|p_2(x)\Big)+\frac{1}{2}KL\Big(p_2(x)\|p_1(x)\Big)</script>

注:Claude Elwood Shannon,1916~2001,美国数学家,信息论之父。密歇根大学双学士+MIT博士。先后供职于贝尔实验室和MIT。

KL散度和JS散度,也是Ian Goodfellow在原始GAN论文中,给出的评价指标。

虽然KL散度和JS散度,在这里起着距离的作用,但它们不是距离,它们不满足距离的三角不等式,因此只能叫“散度”。

神经距离

假设我们可以将实数域分成若干个不相交的区间 I1,I2,,IK <script type="math/tex" id="MathJax-Element-143">I_1,I_2,\dots,I_K</script>,那么就可以估算一下给定分布Z的概率分布:

pz(Ii)=1Nj=1N#(zjIi)
<script type="math/tex; mode=display" id="MathJax-Element-136">p_z(I_i)=\frac{1}{N}\sum_{j=1}^{N}\#(z_j\in I_i)</script>

其中 #(zjIi) <script type="math/tex" id="MathJax-Element-137">\#(z_j\in I_i)</script>表示如果 zjIi <script type="math/tex" id="MathJax-Element-138">z_j\in I_i</script>,那么取值为1,否则为0。

接着我们生成M个均匀随机数 x1,x2,,xM <script type="math/tex" id="MathJax-Element-139">x_1,x_2,\dots,x_M</script>(这里不一定要 M=N <script type="math/tex" id="MathJax-Element-140">M=N</script>,还是那句话,我们比较的是分布,不是样本本身,因此多一个少一个样本,对分布的估算也差不了多少。),根据 Y=G(X,θ) <script type="math/tex" id="MathJax-Element-141">Y=G(X,\theta)</script>计算对应的 y1,y2,,yM <script type="math/tex" id="MathJax-Element-142">y_1,y_2,\dots,y_M</script>,然后根据公式可以计算:

py(Ii)=1Mj=1M(yjIi)
<script type="math/tex; mode=display" id="MathJax-Element-65">p_y(I_i)=\frac{1}{M}\sum_{j=1}^{M}(y_j\in I_i)</script>

现在有了 pz(Ii) <script type="math/tex" id="MathJax-Element-66">p_z(I_i)</script>和 py(Ii) <script type="math/tex" id="MathJax-Element-67">p_y(I_i)</script>,那么我们就可以算它们的差距了,比如可以选择JS距离

Loss=JS(py(Ii),pz(Ii))
<script type="math/tex; mode=display" id="MathJax-Element-57">\text{Loss} = JS\Big(p_y(I_i), p_z(I_i)\Big)</script>

假如我们只研究单变量概率分布之间的变换,那上述过程完全够了。然而,很多真正有意义的事情都是多元的,比如在MNIST上做实验,想要将随机噪声变换成手写数字图像。要注意MNIST的图像是28*28=784像素的,假如每个像素都是随机的,那么这就是一个784元的概率分布。按照我们前面分区间来计算KL距离或者JS距离,哪怕每个像素只分两个区间,那么就有 278410236 <script type="math/tex" id="MathJax-Element-58">2^{784}\approx 10^{236}</script>个区间,这是何其巨大的计算量!

为此,我们用神经网络L定义距离:

L({yi}Mi=1,{zi}Ni=1,Θ)
<script type="math/tex; mode=display" id="MathJax-Element-53">L\Big(\{y_i\}_{i=1}^M, \{z_i\}_{i=1}^N, \Theta\Big)</script>

其中, Θ <script type="math/tex" id="MathJax-Element-54">\Theta</script>为神经网络的参数。

对于特定的任务来说, {zi}Ni=1 <script type="math/tex" id="MathJax-Element-55">\{z_i\}_{i=1}^N</script>是给定的,并非变量,因此上式可简写成:

L({yi}Mi=1,Θ)
<script type="math/tex; mode=display" id="MathJax-Element-39">L\Big(\{y_i\}_{i=1}^M, \Theta\Big)</script>

通常,我们采用如下的L实现:

L=1Mi=1MD(yi,Θ)
<script type="math/tex; mode=display" id="MathJax-Element-372">L=\frac{1}{M}\sum_{i=1}^M D\Big(y_i,\Theta\Big)</script>

上式可以简单的理解为:分布之间的距离,等于单个样本的距离的平均

这里的神经网络 D(Y,Θ) <script type="math/tex" id="MathJax-Element-373">D(Y,\Theta)</script>,实际上就是GAN的另一个主角——鉴别者。这里的D是Discriminator的意思。

如何对抗

因为 D(Y,Θ) <script type="math/tex" id="MathJax-Element-446">D(Y,\Theta)</script>的均值,也就是L,是度量两个分布的差异程度,这就意味着,L要能够将两个分布区分开来,即L越大越好;但是我们最终的目的,是希望通过均匀分布而生成我们指定的分布,所以 G(X,θ) <script type="math/tex" id="MathJax-Element-447">G(X,\theta)</script>则希望两个分布越来越接近,即L越小越好。

形式化的描述就是:

argminGmaxDV(G,D)
<script type="math/tex; mode=display" id="MathJax-Element-417">\arg \min_G \max_D V(G,D)</script>

具体的做法是:

Step1

随机初始化 G(X,θ) <script type="math/tex" id="MathJax-Element-441">G(X,\theta)</script>,固定它,然后生成一批Y,这时候我们要训练 D(Y,Θ) <script type="math/tex" id="MathJax-Element-442">D(Y,\Theta)</script>,既然L代表的是“与指定样本Z的差异”,那么,如果将指定样本Z代入L,结果应该是越小越好,而将Y代入L,结果应该是越大越好,所以

Θ=Θ=argminΘL=argminΘ1Ni=1ND(zi,Θ)argmaxΘL=argmaxΘ1Mi=1MD(yi,Θ)
<script type="math/tex; mode=display" id="MathJax-Element-420">\begin{aligned}\Theta =& \mathop{\arg\min}_{\Theta} L = \mathop{\arg\min}_{\Theta} \frac{1}{N}\sum_{i=1}^N D\Big(z_i,\Theta\Big)\\ \Theta =& \mathop{\arg\max}_{\Theta} L = \mathop{\arg\max}_{\Theta} \frac{1}{M}\sum_{i=1}^M D\Big(y_i,\Theta\Big)\end{aligned}</script>

然而有两个目标并不容易平衡,所以干脆都取同样的样本数B(一个batch),然后一起训练就好:

Θ==argminΘL1argminΘ1Bi=1B[D(zi,Θ)D(yi,Θ)]
<script type="math/tex; mode=display" id="MathJax-Element-421">\begin{aligned}\Theta =& \mathop{\arg\min}_{\Theta} L_1\\ =&\mathop{\arg\min}_{\Theta} \frac{1}{B}\sum_{i=1}^B\left[D\Big(z_i,\Theta\Big)-D\Big(y_i,\Theta\Big)\right]\end{aligned}</script>

Step2

G(X,θ) <script type="math/tex" id="MathJax-Element-435">G(X,\theta)</script>希望它生成的样本越接近真实样本越好,因此这时候把 Θ <script type="math/tex" id="MathJax-Element-436">\Theta</script>固定,只训练 θ <script type="math/tex" id="MathJax-Element-437">\theta</script>让L越来越小:

θ==argminθL2argminθ1Bi=1B[D(G(xi,θ),Θ)]
<script type="math/tex; mode=display" id="MathJax-Element-425">\begin{aligned}\theta =& \mathop{\arg\min}_{\theta} L_2\\ =&\mathop{\arg\min}_{\theta} \frac{1}{B}\sum_{i=1}^B\left[D\Big(G(x_i,\theta),\Theta\Big)\right]\end{aligned}</script>

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐