本博文主要讲解和总结生成对抗神经网络,也即是耳熟能详的GAN神经网络原理,将从数学层面详细的进行总结和分析。
GAN神经网络大致原理
整体learn过程
![这里写图片描述](https://img-blog.csdn.net/20180220104634906?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTXJfdHl0aW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
我们可以这样理解上图:首先随机初始化第一代的
generator v1
,利用
generator v1
生成的
sample
作为负样本,真实的
sample
作为正样本,训练出第一代的
Discriminator v1
,这里可以将所有的
Discriminator
视为
Binary classifier
,这样第一代的分类器就能辨别出第一代的生成器所生成的样本;随之我们可以由第一代的分类器,使得
generator v1
能够演化成
generator v2
,也就是第二代的生成器,第二代生成器生成的样本能够够顺利的骗过
Discriminator v1
,也就是
Discriminator v1
可能会将
generator v2
生成的sample错误的判别为正类,由此我们再以
generator v2
生成的sample作为负样本,真实样本作为正样本,再训练出第二代的分类器
Discriminator v2
;由此一直进行下去,我们可以不断的迭代更新分类器,生成器。
GAN - Discriminator
上面简单的总结了下整个的
learn
的过程,这里稍微详细的讲下
Discriminator
是如何
learn
的。
![这里写图片描述](https://img-blog.csdn.net/20180220104740822?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTXJfdHl0aW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
初代生成器
generator v1
通过
Randomly sample a vector
生成一些样本标记为0,将
real sample
标记为1,由此构建出了正负样本数据集,可以训练出第一代的生成器
Discriminator v1
,以后每代的生成器都是如此
learn
出来的。
GAN - Generator
那么
generator
具体是如何
learn
迭代更新的呢?
![这里写图片描述](https://img-blog.csdn.net/20180220104839539?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTXJfdHl0aW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
第一代的生成器
generator v1
生成的样本,肯定比较
fake
,与真实样本差距较大,那么第一代的
Discriminator v1
就会
output
出一个比较低的分数来反映该生成样本的真实程度,接下来要做的就是
update
generator v1
的参数,得到第二代
generator v2
,这个新的生成器产生的样本要很
realistic
,就是要能骗过第一代生成器,那么该
generator v2
是如何
learn
生成呢?
Generator + Discriminator = a network
我们将上一代的
Generator
和
Discriminator
看做一个
network
,并且固定住
Discriminator
,利用
gradientdescent
更新
Generator
参数,使之
Discriminator
的
output
越接近
1
越好。
GAN数学原理
上面只是大致的讲了下其原理,下面将从数学层面详细的进行总结分析。
最大似然估计
- 给出真实样本集的分布:
Pdata(x)
- 由生成器生成的样本集分布:
PG(x;θ) parameterized by θ
如果
PG(x;θ)
是
Gaussian Mixture Model
,则
θ
表示均值和方差。
我们希望
PG(x;θ)
与
Pdata(x)
越相像越好。
我们可以从
Pdata(x)
中随机
sample
出几个样本
{x1,x2,...,xm}
,假定
θ
已经给定,那么我们可以计算出上面
sample
出的
xi
在生成样本集中的机率。
那么我们可以有最大似然函数得到从
Pdata(x)
中随机
sample
出的这几个样本
{x1,x2,...,xm}
在生成样本集中的概率:
L = ∏i=1mPG(xi;θ)
并且计算
θ∗
使得上式子取最大。
可以对上式进行简单的推导如下:
![这里写图片描述](https://img-blog.csdn.net/20180220105157500?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTXJfdHl0aW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
KL散度
这里需要稍微讲下
KL
散度相关知识。
相对熵,又称KL散度( Kullback–Leibler divergence),是描述两个概率分布P和Q差异的一种方法。它是非对称的,这意味着D(P||Q) ≠ D(Q||P)。特别的,在信息论中,D(P||Q)表示当用概率分布Q来拟合真实分布P时,产生的信息损耗,其中P表示真实分布,Q表示P的拟合分布,相对熵越小表示拟合的越好。
设
P(X)
和
Q(X)
是
X
取值的两个离散概率分布,则
P(X)
对
Q(X)
的相对熵为:
D(P||Q)=∑xϵXP(x)logP(x)Q(x)=∫P(x)logP(x)Q(x)
在最开始时,大家把
Gaussian Mixture Model
当做
PG(x;θ)
,可能由于模型过于简单,或者又是
Gaussian Mixture Model
与
Pdata(x)
差太多,没有办法真正的模拟
Pdata(x)
,生成的样本与真实样本差距太大。
那么
PG(x;θ)
可以很复杂,所以现在广泛用
nerual network
当做
PG(x;θ)
,
θ
就是
nerual network
的参数。理论上说单隐层神经网络可以逼近任何连续函数。但是因为
nerual network
很复杂,所以对从
Pdata(x)
中随机
sample
出几个样本
{x1,x2,...,xm}
,比较难的求出其概率,则
difficult to compute the likelihood
。
那么问题来了,怎么样更新G的参数,使其能拟合
Pdata(x)
呢?
Basic Idea of GAN
Generator G (Hard to learn by maximum likelihood)
- G是一种任意的函数,输入Z,输出X
- 计算
PG(x;θ)
Discriminator D
- D是一种函数,输入X,输出标量
-
Evaluate
PG(x;θ)
与
Pdata(x)
的
difference
那么
D
是如何检测
G
与
Pdata(x)
,定义一个函数
V(G,D)
,
G∗=argminGmaxDV(G,D)
那么
V
是如何定义呢?
V = Ex∼Pdata[logD(x)] + Ex∼PG[log(1−D(x))]
x∼Pdata
:表示从
Pdata
的分布中随机抽取样本
x
。
x∼PG
:表示从
PG
的分布中随机抽取样本
x
。
在给定
G
时,
maxV(G,D)
可以表示
PG
和
PD
之间的差异程度(原因看下面),那么要找出
D∗
,使得
V(G,D)
最大:
![这里写图片描述](https://img-blog.csdn.net/20180219215103743?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTXJfdHl0aW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
继续推导:
![这里写图片描述](https://img-blog.csdn.net/20180219220929283?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTXJfdHl0aW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
由此可见,求得的
D∗
能衡量
Pdata
与
PG
相似程度。再将
D∗
代入到
V
中得:
![这里写图片描述](https://img-blog.csdn.net/20180219222528577?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTXJfdHl0aW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
![这里写图片描述](https://img-blog.csdn.net/20180219224927273?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTXJfdHl0aW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
需要注意的是KL散度是非对称的,这里需要介绍下
Jensen−Shannon divergence
(对称性):
![](https://img-blog.csdn.net/20180219230134303?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTXJfdHl0aW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
由此可见,
maxV(D,G)
可以表示 PG和PD之间的差异程度,在求得
D∗
和
V(G,D∗)
后,剩下的问题就是求
G∗
了。
![这里写图片描述](https://img-blog.csdn.net/20180219232920820?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTXJfdHl0aW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
也就是求下式:
![](https://img-blog.csdn.net/2018021923332170?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTXJfdHl0aW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
我们可以
user gradient descent
求
G∗
:
![这里写图片描述](https://img-blog.csdn.net/20180219233557596?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTXJfdHl0aW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
G、D更新流程
算法整体目标就是:
![](https://img-blog.csdn.net/20180219235558629?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTXJfdHl0aW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
- 给定
G0
求出
D∗1
,使得
V(G0,D)
最大。
V(G0,D) is the JS divergence between PG and Pdata
在给定
D∗1
情况下,求
θG←θG−η ∂V(G,D∗1)
,求得
G1
这一步需要注意:在固定
D∗
时,在
use gradient descent
更新
G
时,其V不一定在减小啊,甚至可能会比之前的
V(G0,D)
还要大?
上图中,横坐标表示
D
,纵坐标表示
V
,故在
update G
时,步伐不能太大。
在给定
G1
情况下,求得
D∗1
,使得
V(G1,D)
最大
- 以此类推,不断迭代更新
G,D
实际train流程
V = Ex∼Pdata[logD(x)] + Ex∼PG[log(1−D(x))]
x∼Pdata
:表示从
Pdata
的分布中随机抽取样本
x
。
x∼PG
:表示从
PG
的分布中随机抽取样本
x
。
我们需要
Maximize
上面的
V
,由此上式可以转变成求:
上式中的
xi
是从
Pdata
中
sample
出来的;
x˜i
是从
PG
中
sample
出来的。
上式可等价于:
![这里写图片描述](https://img-blog.csdn.net/20180220002534980?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTXJfdHl0aW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
可以将
D
看着一个二分类器,那么
xi
是从
Pdata
中
sample
出来的,为正类样本;
x˜i
是从
PG
中
sample
出来的,为负类样本。也即是:
那么其损失函数为:
![这里写图片描述](https://img-blog.csdn.net/20180220003403864?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTXJfdHl0aW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
注意下:
L
为损失函数,其两项之前应有负号。
整体算法流程
需要注意:在
learn D
时,需要
train
多次,就是训练多个
epoch
,而在
learn G
时,只需要一次。