GAN原理解析,公式推导与python实现

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_39422642/article/details/79004646

1-生成模型


1-1 生成模型与判别模型

生成式对抗网络,顾名思义就是生成模型嘛!那什么是生成模型呢?与判别模型有什么区别呢?

先来理解一下判别模型。
学过机器学习的人都知道,入门级的算法逻辑回归,最后的预测,是通过sigmoid函数:
这里写图片描述
生成一个0-1之间的数值,然后用某一阀值来做分类,我们称之为判别模型:由数据直接学习,通过决策函数Y=f(X)或者概率模型P(Y|X)预测,判断类别的模型。逻辑回归中的sigmoid函数就是判别函数。

而生成模型,则先学习出一个联合概率密度分布P(X,Y),最后分类,预测的时候,使用条件概率公式

P(Y|X)=P(X,Y)P(X)
来预测当前样本属于每一类的概率。
生成模型的核心,就是先求两个比较好求的概率,然后通过贝叶斯概率公式这样的关系来进行分类。

简单的看,
这里写图片描述

1-2 为什么学习生成模型?

我们可以总结一下它的优点:

  1. 能生成高维的数据或者复杂的概率分布,且高维数据分布在数学和工业界都扮演着重要的作用
  2. 还可以为强化学习做一定准备
  3. 对于缺失数据较多的场景,可以用来生成更多的样例数据,是当前用来解决信息缺失的最好方式。

举一些例子:
Next Video Frame Prediction
这里写图片描述
大概意思是预测下一帧会是什么?比如第一个头像是当前帧的状态,然后给出一个MSE(均方差矩阵),预测下一帧会出现什么,如图就是头转了大约15度或者30度左右的样子。

很明显,这个应用是很强大的,比如某些打码的片子,甚者打码的图片,三级片之类的,或者有损失的古物,古画,都有可能通过生成模型,来生成新的。

Single Image Super-Resolution
这里写图片描述
或者处理比较模糊的图片,因为像素太低,导致人看了不怎么清楚,可以通过GAN来生成更高像素的图片,看的更清晰。上图左为原始图片,第二张为 使用bicubic method的插值法得出的,第三张是使用ResNet,第四张是使用GAN来生成的。

Image to Image Translation
这里写图片描述
根据你画的样子,给你生成一个你可能想都没想过的样子,或者根据地图,生成场景之类的。

总之,GAN的特点之一,就是生成,生成一些你可能想都没想过的东西。

1-3 生成模型原理—似然原理

这里写图片描述
所谓的生成模型,其实就是基于最大似然估计的,而最大似然估计就是用的似然原理。

什么是似然原理呢?我们举个例子,比如你要估计一个学校的数学成绩是多少,肯定不会直接找全校的学生,然后再把他们的数学成绩放在一起计算吧。因为这样做的代价太大了,现实情况根本不允许。

那我们该怎么办呢?
那我们可以随机取样嘛,用样本来估计总体。什么意思呢?我们知道一个群体的某一形状假如服从正态分布,如图所示,那么这个分布的形状由两方面决定,分别是均值μ和方差σ2,只要这两个定了,那么图像的概率密度分布也就定了。

那我们能否用样本(抽到的学生)的均值和方差,估计总体(整个学校的学生)的均值和方差,这样不就得到了总体的概率分布了吗?其实这就是生成模型的原理。
想要详细了解它的公式推导,可以看一下这篇的最后一个部分:概率统计学习基础

2-生成式对抗网络

2-1 生成式对抗网络工作原理

前面我们说的都是前期知识准备,了解生成模型,接下来看一下真正的生成式对抗网络,它的工作流如下:
这里写图片描述
GAN是一种structured probabilistic model,具体介绍在deep learning这本书的第16章有。
顾名思义,生成-对抗,其核心也是两个,一个是生成,用图中的G(z)表示,z是隐变量;一个是对抗,用图中的D(x)表示,x是观测变量。图结构表示如下:

GAN是一个有向图模型,它的每一个隐变量都在影响观测变量。

这里写图片描述
我们希望达到的效果,就如上图所示,生成式对抗网络会训练并更新判别分布(D,图中蓝色虚线部分),希望能将真实的分布(pdata(x),线)和生成分布(pmodel(G(z)),绿线)区分开来。z表示属于某一分布的噪声数据,经过生成器之后,变成x=G(z),得到一个生成分布pmodel(G(z))。而上方的x水平线则代表真实的分布X中的一部分。

主要目标就两个:

  • 判别器D(x)独自训练自己,希望能分辨出真实的数据分布和生成器给的数据分布
  • 生成器G(z)也训练自己,希望以假乱真,让判别器判别不出到底哪个是真,哪个是假

G(z)D(x)它们的区别主要在于输入的数据和参数:θ(G),θ(D).

我们输入noise样本给G(z),让它生成一张图片,因为是noise样本,生成的图片效果应该不会太好,然后交给D(x)D(x)说你生成的图是错的,或者生成的图是正确的,但D(x)却认为你G(z)生成的是错的,也就是说D(x)出现了判断错误,这就会产生误差,自己就可以用梯度下降法来优化自己;

如果D(x)判断你生成的不对,那G(z)就知道自己哪里不对了,也可以用梯度下降法来优化自己,以生成更好的图片。

  • 举个例子,这个过程就像是一个画画的老师在教,或者说监督学生画画一样,老师就是对抗的部分,学生就是生成部分。老师手上有一副真的蒙娜丽莎,学生手上有一副蒙娜丽莎的赝品,学生在模仿赝品画蒙娜丽莎,然后给老师看,老实说你这里画得不像,重来,然后不断改进,直到学生画得蒙娜丽莎老师分辨不出来到底是真是假是,训练停止。

判别部分(Generator Network)

输入z,通过对应的参数,能生成x,x属于生成的概率分布:Pmodel,用公式表示如下:

x=G(z;θ(G))
如果我们想要生成x和生成分布Pmodel相吻合,就得要求输入的数据z的维度至少是和x的维度相差无几的。

训练过程
GAN的训练过程也是使用SGD,或者其他的优化算法来做优化,一般使用minibatch,值得注意的是,我们可以让其中一个先跑一下,一般让生成部分先跑, 使得生成的效率更高一点。

2-2 判别器的损失函数

一个算法模型最重要的,莫过于损失函数和优化的方法了,对于判别部分来说,所有的GAN变体都是使用相同的损失函数J(D)定义,他们之间不同之处在于生成部分选择的损失函数J(G)不同。

首先我们必须先定义样本是从真实分布pdata(x)来的,还是从生成分布pmodel(x)中来的。因此有:

ExpdatalogD(x)
这里的E表示期望。这一项是根据正类(即能判别出x属于真实分布)的对数损失函数构建的,最大化这一项意味着令判别器D在x服从于data的概率密度时能准确预测D(x)= 1,即:
D(x)=1   when  xpdata(x)

另一项是根据负类的对数损失函数构建的:

Ezpmodellog(1D(G(z)))
D(x)=0   when xpmodel(G(z))
合在一起,有判别器的损失函数定义如下:
这里写图片描述
其中左边部分表示 D 判断出 x 是真 x 的情况,右边部分则表示 D 判别出的由生成器 G(也就是骗子)把噪音数据 z 给伪造出来的情况。

这其实就是交叉熵损失函数,与其他算法不同的是,在最小化J(D)的过程中,仅通过调整θ(D)来优化的,而且另一大不同点是损失函数的数据数据有两个部分,一个部分来源于训练数据x,另一部分来源于生成器生成的伪造数据G(z)

2-3 生成器损失定义1(minimax)

零和博弈minimax
在博弈论中,有零和博弈这个概念,意思是说博弈双方的利益之和为零或者为一个常数,即有一方获益了,另一方一定会损失。看一个简单的零和游戏的例子如下:

如图所示,为红蓝双方的零和游戏案例,第一个玩家(红方)选择1,2,而第二个玩家(蓝方)在不知道第一个玩家选择什么的情况下,选择A,或者B,C。玩家的分数根据选择的分数决定。比如红方如果选择了1,蓝方选择了A,那么红方就是得到30分,而相应的蓝方就会损失30分,这就是零和游戏。

但最后结果,双方肯定都希望自己的分数是最高的,问:双方该怎么选择呢?
这就说到了极小化极大算法。是随机事件,无论是谁都应该知道选择让自己赢的概率最大的那个方案,也就是看选哪个方案,让自己得更高分的概率最大。而极小化极大算法(minimax)的想法就是:一方要在可选项中选择将其优势最大化的选择,而另一方则要在可选项中选择令对方优势最小化的选择。

其实GAN的原理就可以认为是这样的双方博弈。

生成器1 minimax

根据前面的零和博弈原理,我们可以给初始的生成器损失函数定义:

J(G)=J(D)
可见最后加和的结果必然是零。这也是最简单的

2-4 生成器损失定义2:Non-Saturating Game

生成器2
由前面我们知道,使用minimax之间的博弈是有直接关联的,如果其中一方学习停止了,那另一方也会跟着停止,为了优化这个模型,我们希望生成器和判别器都能学习到各自的最优,因此对此做的改进就是Non-Saturating Game。

minimax的缺点就是生成器和判别器之间的损失函数直接关联,因此我们可以把他们的联系弄断,就变成了如下的样子:
这里写图片描述
我们重新定义了我们的生成器损失函数,使得在判别器学习到足够好之后,生成器依然能够继续学习,生成更好的图片。其中最好的应用这个想法的就是DCGAN。

2-5 第三种策略:极大似然估计

2-5-1 KL 散度的定义

虽然前面两种都能达成我们的目的,但若是想再次进行优化,我们可以从头开始思考,因为我们的本质是要让我们的生成分布和原始数据的分布尽可能接近,也就是希望找到一种能定义两个分布之间的相似性的度量方法,在统计中,我们可以使用KL散度或者JS距离来度量两个概率分布之间的相似性。

在信息论中,KL散度又被称为相对熵,我们使用香农熵来对整个概率分布中的不确定性进行量化:
这里写图片描述
假设对于同一个随机变量x有两个不同的概率分布P(x),Q(x),使用KL散度(相对熵)来衡量他们的相似性如下:
这里写图片描述
如果他们在离散型变量下为相同的分布,在连续型变量的情况下为几乎处处相同的分布,则他们的KL散度为0,且KL散度为非负。但有一点需要注意的是,KL散度和一般距离公式不太一样,因为它是不可逆,即:DKL(P||Q)DKL(Q||P)
E表示期望,因为离散型和连续型的随机变量的期望计算方法不一样,对于离散型随机变量的KL散度计算公式如下:

DKL(P||Q)=ip(i) logp(i)q(i)
对于连续型随机变量的KL散度可以写成为:
DKL(P||Q)=+p(x) logp(x)q(x)

2-5-2 KL散度的推导

KL散度可以从极大似然估计中推导出来,而极大似然估计又是基于极大似然原理的,极大似然原理可以表示为:选择导致某“结果“发生可能性最大的原因,作为似然“原因“。说白了就是选择合适的参数使得某一事件发生的可能性最大。
设随机变量Y的概率密度函数为f(Y|θ),θ表示参数,假定经过观测可以得到一组观测值为y1,y2,y3,yN,那么它对应的似然函数可以写成:

L(θ)=f(y1|θ)f(y2|θ)f(yN|θ)
我们要在众多的θ中找出使得该似然函数最大的θ̂ ,该函数为一个关于一个变量θ的函数,可以对其求导或采用其他方法使得该函数的最大值,又对数是单调递增的函数,故可以转化成求使得InL(θ)最大时的θ值,
InL(θ)=In f(y1|θ)+In f(y2|θ)++In f(yN|θ)=iNIn f(yi|θ)
N时,几乎处处有:
1NiNIn f(yi|θ)=EIn f(Y|θ)
当观测样本已知时,N为定植,假设Y的真实概率分布为g(y),有:
EIn f(Y|θ)=g(y) Inf(y|θ)dy
那么真实的概率分布和估计的概率分布之间的差异性可以表示为:
EIn g(y)E In f(y|θ)=g(y)In g(y)dy g(y) In f(y|θ)dy=KL(g|f)=g(y) Ing(y)f(y|θ)dy
当f,g属于同一分布时,他们的KL散度为0,如果最小化KL散度,因为E In g(y)已知,可以看成是f去拟合g这个分布。事实上,也正因为这个性质,使得一开始的GAN具有某些问题,这个暂时不讨论。

2-5-3 利用KL散度度量生成分布与真实分布的相似性

GAN的生成器本质上是想使生成的函数尽可能和真实分布相似,以使得判别器没办法判断某一张图片是生成器生成的还是真实分布中的,因为为生成器找到一个度量生成分布中的图片与真实分布中的图片的差异性,是一个非常关键的问题,而KL散度刚好可以度量两个分布的相似性,因此,可以利用极大似然估计建立生成器对应的似然函数为:

L(θ)=PG(xi,θ)
已知真实分布为Pdata,故可以建立KL散度对应的积分公式:
arg minθKL(Pdata|PG)=Pdata(x)InPdata(x)PG(x|θ)
求使得这个函数最小的θ,就是我们的优化目标。

3-GAN实现

tensorflow实现
keras实现

reference

GAN之父:nips
零和博弈
独家 | GAN之父NIPS 2016演讲现场直击:全方位解读生成对抗网络的原理及未来(附PPT)
Jensen–Shannon divergence
生成模型、最大化似然、KL散度
从信息论的角度理解极大似然法
欧拉-麦克劳林
机器之心GitHub项目:GAN完整理论推导与实现,Perfect!

展开阅读全文

没有更多推荐了,返回首页