目录
一、生成对抗网络的定义及优势
GAN 主要包括了两个部分,即生成器 (generator)与判别器 (discriminator)。
(1)生成器主要用来学习真实图像分布从而让自身生成的图像更加真实,以骗过判别器。
(2)判别器则需要对接收的图片进行真假判别。
在整个过程中,生成器努力地让生成的图像更加真实,而判别器则努力地去识别出图像的真假,这个过程相当于一个二人博弈。随着时间推移,生成器和判别器不断地进行对抗,最终两个网络达到了一个动态均衡:生成器生成的图像接近于真实图像分布,而判别器识别不出真假图像,对于给定图像的预测为真的概率基本接近 0.5(相当于随机猜测类别)。
因此,我们可以将上面的内容进行一个总结。给定真 = 1,假 = 0,那么有:
对于给定的真实图片(real image),判别器要为其打上标签 1;
对于给定的生成图片(fake image),判别器要为其打上标签 0;
对于生成器传给辨别器的生成图片,生成器希望辨别器打上标签 1。
二、生成对抗网络原理深入理解
GAN可以视作:结构化学习(structured learning),输出复杂的结构数据,如:序列、矩阵等。
上面应该已经对GAN有了一个基本的认识,那么GAN是如何来做的呢?
将第一代的Generator产生的图片和一些真实的图片丢到第一代的Discriminator里面去学习,让第一代的Discriminator能够真实的分辨生成的图片和真实的图片;然后又有了第二代的Generator产生的图片,能够骗过第一代的Discriminator,此时我们再训练第二代的Discriminator,依次类推。
上面的描述中,你可能不太明白如何训练新一代的Generator来骗过上一代的Discriminator。将一个随机的向量输入到第一代Generator v1中,将得到的图片输入到第一代的Discriminator v1中,得到的分数为0.13,表明是生成的图片。进一步利用梯度下降法更新Generator的参数得到第二代的Generator v2,此时Discriminator的参数是被固定冻结住的,第二代的Generator v2生成的图片骗过第一代的Discriminator v1使得输出得分为1(将第二Generator生成的图片当作真实图片)。其实很简单,即:可以把新一代的Generator和上一代的Discriminator连起来形成一个新的NN,我们希望最终的输出接近1,然后我们就可以拿中间的结果当作新的图片的输出,下图很形象的显示了上面的过程:
GAN基础思想:
在没有GAN出现之前,采用的方法是极大似然估计,一起来回顾一下:假设我们有一大堆data,服从的分布是,这里可以认为data是一大堆图片,但是有了这一大堆东西,再想生成一个新的data是不容易的,因为我们不知道这个分布的具体参数,所以,我们就想估计这堆数据的所服从的参数。那么,我们可以从
产生一大堆sample,然后,我们就希望找一组参数,使得服从这组参数的分布产生这堆sample的可能性最大。
下面是极大似然估计的化简过程,因为这堆sample都是从Pdata(x)里面出来的,所以,我们可以进行下面的约等转换。然后我们把期望转换为积分,同时加上后面一项(后面一项是一个常数,只是为了更简单的表示KL散度)
KL散度又称相对熵。设P(x)和Q(x)是X取值的两个概率分布,则对的相对熵为:
在一定程度上,熵可以度量两个随机变量的距离。KL散度是两个概率分布P和Q差别的非对称性的度量。KL散度是用来度量使用基于Q的编码来编码来自P的样本平均所需的额外的位元数。 典型情况下,P表示数据的真实分布,Q表示数据的理论分布,模型分布,或P的近似分布。
那么,在GAN中,我们用NN的参数表示PG的参数θ:
当我们的V写成下面这样子的时候,我们取maxV(G,D)就能表示Pg和Pdata的差异:
为什么V要写成这样能表示二者的差异呢?这个可以通过严格的数学证明推导出,这里,对于一个给定的G,我们来求解maxV(G,D):
对于任何一个常数,因为Pdata和PG这里都是给定的,我们可以认为这里是常数,那么D取什么可以得到最大呢,很简单,导数为0的情况下。
在有了D的值之后,我们就可以带入原式中:
继续化简,我们可以得到两个KL散度,进而得到JS散度:
所以,我们最终的求解目标是:
我们可以用下面的图来形象的表示上面的求解问题,看下面的图,我们可以很清楚的知道,我们要找的使得V最大的D就是最高点的D(红点处),使得V最小的G则是G3。
按照上面的V的定义,我们就能得到二者的差距,当然我们可以定别的,就能产生别的散度度量。
那么,给定了一个G,我们能够通过最大化V得到D,那么我们如何求解G呢,用梯度下降就好啦:
实际中的GAN:
刚才是理论部分的内容,但是在实际中,Pdata和Pg我们是不知道的,我们没办法穷举所有的x,所以,我们只能采用采样的方法,同时可以采用我们二分类的思路,我们把Pdata(x)中产生的样本当作正例,把Pg(x)产生的样本当作负例,那么,下面V可以看作是我们二分类的一个损失函数的相反数(少了负号嘛):
三、生成对抗网络的训练过程
在实际中,我们有可能做下面的变换,可以加快我们的训练速度:
为了在数据上学习生成器的分布
,我们在输入噪声变量
上定义先验,然后将数据空间的映射定义为
,其中G是由具有参数
的多层感知器表示的可微函数。我们还定义了第二个多层感知器
,它输出单个标量scalar。我们训练
以最大化为训练样本和来自
的样本分配正确标签的概率,我们同时训练
来最小化
。换句话说,
和
对函数值
的优化是一个二元的极小极大博弈(minimax two-player game):
注:极小化极大算法(找出失败的最大可能性中的最小值的算法)。
实际上,上面的等式可能无法为很好的学习提供有效的梯度,在学习的初期,当
很差时
可以高度自信地判别出样本的真假,因为它们与训练数据明显不同。在这种情况下,
达到饱和,我们可以训练
以最大化
,而不是训练
以最小化
。
在实践中,我们必须使用迭代的数值方法来实现博弈。 在训练的内循环中优化D到完成在计算上是不可行的,并且在有限数据集上将导致过度拟合。 相反,在优化D的k个步骤和优化G的一个步骤之间交替。这导致D保持接近其最优解,只要G变化足够慢。
总结:训练两个模型的方法:单独交替迭代训练
GAN的训练在同一轮梯度反传的过程中可以细分为2步,先训练D再训练G;注意不是等所有的D训练好以后,才开始训练G,因为D的训练也需要上一轮梯度反传中G的输出值作为输入。
(1)当训练D的时候,上一轮G产生的图片,和真实图片,直接拼接在一起,作为x。然后根据,按顺序摆放0和1,假图对应0,真图对应1。然后就可以通过,x输入生成一个score(从0到1之间的数),通过score和y组成的损失函数,就可以进行梯度反传了。(我在图片上举的例子是batch = 1,len(y)=2*batch,训练时通常可以取较大的batch)
(2)当训练G的时候, 需要把G和D当作一个整体,我在这里取名叫做’D_on_G。这个整体(下面简称DG系统)的输出仍然是score。输入一组随机向量,就可以在G生成一张图,通过D对生成的这张图进行打分,这就是DG系统的前向过程。score=1就是DG系统需要优化的目标,score和y=1之间的差异可以组成损失函数,然后可以反向传播梯度。注意,这里的D的参数是不可训练的。这样就能保证G的训练是符合D的打分标准的。这就好比:如果你参加考试,你别指望能改变老师的评分标准。
判别模型: 希望真样本集尽可能输出1,假样本集输出0。对于判别网络,此时问题转换成一个有监督的二分类问题,直接送到神经网络模型中训练就ok。
生成网络:目的是生成尽可能逼真的样本。原始生成网络如何知道真不真?就是送到判别网络中。在训练生成网络的时候,需要联合判别网络才能达到训练的目的。什么意思?如果单单只用生成网络,那么后面怎么训练,误差来源在哪里?细想一下没有,但是如果把刚才的判别网络串接在生成网络的后面,这样就知道真假来,也就有了误差。!!!所以对生成网络的训练其实是对生成-判别网络串接的训练,就像图中显示的那样。 生成来假样本,要把这些假样本的标签都设置为 1,也就是认为这些假样本在生成网络训练的时候是真样本。起到了迷惑判别器的目的。!!!在训练这个串接网络的时候,一个很重要的操作就是不要判别网络的参数发生变化,也就是不让它参数发生更新,只是把误差一直传,传到生成网络那块后更新生成网络的参数。这样就完成来生成网络的训练。
假样本在训练过程中的真假变换
公式:
目标公式
先优化D,然后再优化G,拆解之后就如下:
优化D:
优化D,即优化判别网络时,没有生成网络什么事,后面的G(z)这里就相当于已经得到的假样本。优化D的公式的第一项,使得真样本x输入的时候,得到的结果越大越好,因为真样本的预测结果越接近1越好;对于假样本,需要优化的是其结果越小越好,也就是D(G(z))越小越好,因为它的标签为0。但是第一项越大,第二项越小,就矛盾了,所以把第二项改为1-D(G(z)),这样就是越大越好。
优化G:
在优化G的时候,这个时候没有真样本什么事,所以把第一项直接去掉,这时候只有假样本,但是我们说这个时候是希望假样本的标签是1,所以是D(G(z))越大越好,但是为了统一成1-D(G(z))的形式,那么只能是最小化1-D(G(z)),本质上没有区别,只是为了形式的统一。之后这两个优化模型可以合并起来写,就变成最开始的最大最小目标函数了。