分布无重叠问题
上几篇讲述了GAN的原理,实际上是衡量JS散度,又讲了散度函数,其实我们可以替换衡量散度函数,只要符合一定的条件就行,这次来讲讲JS散度的问题,从而引出新的衡量散度的方法。
首先我们的分布Pdata
和PG
是在高维空间的低维流形(暂时理解成一种高维到低纬的映射吧),所以几乎没有重合部分,这样我们的JS散度就会有问题,具体问题后面会讲。
其次,即使分布有重叠,但是我们是根据采样来进行训练的,由于采样数有限,采到的样本几乎不会有重叠,所以还是会产生JS散度问题。
JS散度的问题
上面讲了分布不重叠会影响JS散度,具体是怎么回事呢,如果没有重叠,JS散度会是个常数log2
.
我们可以看到,在没有重叠的情况下,我们希望Pdata
和PG
距离原来越近,理论上PG
应该越来越好,但是JS散度始终是常数,因为没有重合部分,直到两个一样了,才会等于0,因此就会出现JS散度是常数,梯度是0,生成器G无法继续学习了,因此你无法把G变得更好了。
从另一方面直觉上说,2个分布没有重叠的,D分类器就可以100%把他们区别出来了,那就意味着每次训练的loss都是样了,也就是JS散度一样了,梯度是0,跟上面一样的道理,所以G就没办法学习了。
补充下为什么没有重合的情况下JS散度始终是log2
,先看看上次推导的散度公式,由于公式打起来麻烦,我就截取一点,其他的手写推导吧:
上图可以看到JS散度和KL散度的关系,然后我就手写啦:
字难看了点,其实就是个思路,就是不重叠的话,必定有个概率为0,代入式子,算出来都是log2
.
LSGAN
那怎么办呢,有人从分类器这里下手了:
传统的二分类器都是用sigmoid
函数,如果我们数据像左边的图一样,分类器训练的很好的情况下,把2个分布完全分开了,由于sigmoid
的左右两边的斜率几乎为0,G不会继续学习了,所以你的左边蓝色的PG
不会往右边移动了,就这样练不动了。以前的做法是说我们不要把D训练的太好,不要让蓝色这边的点都给0,绿色都给1,这样就没有梯度了,无法训练G了,但是不要训练的太好很难掌握啊,难度量啊。所以就有提出了LSGAN
,把分类器问题改成线性回归问题,用线性激活函数,让蓝色的PG
越靠近0,绿色的Pdata
越靠近1,不会存在斜率为0的问题。
WGAN
WGAN换了个衡量分布差异的方法,叫Earth Mover’s Distance。
简单的说,就是我们有2堆土,一堆PG
,一堆Pdata
,我们要计算把PG
堆成Pdata
的平均距离。
很多情况是这样:
我们要把P堆到Q,有很多种做法,也就是moveing plans,我们用最小的平均距离来定义Earth Mover’s Distance。
最好的做法可能是这样:
我们用矩阵来定义我们的方法,下图为最佳方法:
我们定义每个P的土堆,都可能往Q的每个土堆上堆一部分土,所以Q的每个土堆可能是来自P的很多个土堆。每个矩阵的格子对应着P的某个土堆应该给Q的土堆对多少土,颜色越深越多,即可以理解成,每个P的土堆,应该给每个Q的土堆贡献多少土。
因此Earth Mover’s Distance定义就是上面的式子,也就是最小代价的意思。简单的举个例子,假设你是搬砖的,老板让你把5叠砖头叠成一个形状,每个位置有砖块数量要求,你是根据搬运的砖块数量(
γ
(
X
p
,
X
q
)
γ(Xp,Xq)
γ(Xp,Xq))的多少和搬运的距离(
∣
∣
X
p
−
X
q
∣
∣
||Xp-Xq||
∣∣Xp−Xq∣∣)乘积来计费的,那老板肯定要花钱最少啦,所以看到会有一个最小花费的方案,就这个意思。
上图所示,为什么我们要选择Earth Mover’s Distance,不选择JS散度呢,从进化的角度也可以理解,要进化出眼睛,不可能一下子就出来的,肯定是一点点来的,因为进化出来有好处,才会继续进化,越来越好。然后JS散度就算是有进化了,但是发现并没有什么好处,没啥改变,于是也就不进化了,所以很难训练起来,相反Earth Mover’s Distance每次进化一点,都能看到差别,看到进步,于是可以慢慢进化,越来越好。
上图解释了,我们的D和Earth Mover’s Distance的关系,可以推导出那么一个式子。我们希望D来自Pdata
的越大越好,来自PG
的越小越好,但是如果没有约束条件,就会出现真实的数据的D会无限大,生成的数据的D会无限小,也就不会收敛了,所以我们要给个约束,让D足够平滑,不至于出现无限训练不收敛。
上面足够函数就是约束条件,我们希望当输入数据有变化时,输出的数据不要变化的太大,如果k=1,则说明我们希望输出的变化不大于输入的变化,因此就会变得平滑(可以理解成斜率为1时候,输入变化和函数变化一样,但是小于1的时候,输出变化永远小于输入变化,就不会出现变化很大的的情况,最大斜率1也就45度的角度,后面会有提出限制梯度的大小值小于1的方案)。
上图绿色就是非常平滑的情况,蓝色就是变化很大的情况。
那我们现在讨论下具体怎么做约束呢,原始的是约束参数,把参数限制在一个范围内。
另外一种方法就是约束D(x)
的梯度,因为D(x)
是受限于1-Lipschitz
,那就表示对于所有的x,
∣
∣
▽
D
(
x
)
∣
∣
<
=
1
||▽D(x)||<=1
∣∣▽D(x)∣∣<=1.
所以我们就可以等价于给个惩罚项:
但是这么做会有问题,因为实际上我们不可能保证所有x都能符合
∣
∣
▽
D
(
x
)
∣
∣
<
=
1
||▽D(x)||<=1
∣∣▽D(x)∣∣<=1,所以我们就另外找了个分布P-penality
,里面的x都符合
∣
∣
▽
D
(
x
)
∣
∣
<
=
1
||▽D(x)||<=1
∣∣▽D(x)∣∣<=1。
那这个P-penality
怎么来呢,从直觉上来讲应该是PG
和Pdata
的中间区域,因为我们的PG
是通过D(x)
的梯度来改变参数进行更新的,所以中间区域就是更新的方向,所以反推中间区域应该是符合D(x)
是受限于1-Lipschitz
,对于所有的x,
∣
∣
▽
D
(
x
)
∣
∣
<
=
1
||▽D(x)||<=1
∣∣▽D(x)∣∣<=1,这样才能更新过去。
实际操作的时候,右进行了优化,希望梯度就是1,不然就给惩罚,据说实验证明这样会快点。但是直觉上貌似有点问题,更多的情况应该是下面右边的图,红色是Pdata
,黄色是PG
,黄色要移动到红色去,应该是按红色的这个梯度,慢慢的过去,不会直接就直线过去,所以惩罚应该在红色的地方,不应该是直接中间的直线。
下面说说具体要怎么在原始GAN算法上改成WGAN:
其实就是根据下面这个式子改:
EBGAN
再来说下一个新的EBGAN,他的不同就是D是一个Autoencoder,因此有不需要负样本,只需要真实样本,然后会输出会有个loss,如果把loss训练得很低,那就说明这个自编码器很好,可以把真实的样本复原了,因此对于不好的样本,自然给出的loss就大了,如果把D训练的很强,自然就可以区分PG和Pdata了,G也更好训练,G可能通过少量迭代就可以出现较好的效果。G通过的最小化D的loss来训练了,直到最后loss为0,就是生成最好的图片了。
他的好处就是可以用真实样本训练,不用管G。
但是他也有要注意的地方,在训练的时候,可以给D练的很好,但是不要给G的分数太低,如果没有限制就会无限低了。所以会有一个margin,让分出不超过这个值。
总结
这篇主要还是讲述JS散度的一些问题,并且提出了一些改进的GAN,具体想深入的了解,还是需要看论文学习下,之后可能会专门出点研究论文的文章,这些都只能是先介绍下,希望有个了解吧。
好了,今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵,图片来自李宏毅课件,侵删。