本博文主要讲解和总结生成对抗神经网络,也即是耳熟能详的GAN神经网络原理,将从数学层面详细的进行总结和分析。
GAN神经网络大致原理
整体learn过程
我们可以这样理解上图:首先随机初始化第一代的
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
的。
初代生成器
generator v1
通过
Randomly sample a vector
生成一些样本标记为0,将
real sample
标记为1,由此构建出了正负样本数据集,可以训练出第一代的生成器
Discriminator v1
,以后每代的生成器都是如此
learn
出来的。
GAN - Generator
那么
generator
具体是如何
learn
迭代更新的呢?
第一代的生成器
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;θ)
并且计算
θ∗
使得上式子取最大。
可以对上式进行简单的推导如下:
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)
最大:
继续推导:
由此可见,求得的
D∗
能衡量
Pdata
与
PG
相似程度。再将
D∗
代入到
V
中得:
需要注意的是KL散度是非对称的,这里需要介绍下
Jensen−Shannon divergence
(对称性):
由此可见,
maxV(D,G)
可以表示 PG和PD之间的差异程度,在求得
D∗
和
V(G,D∗)
后,剩下的问题就是求
G∗
了。
也就是求下式:
我们可以
user gradient descent
求
G∗
:
G、D更新流程
算法整体目标就是:
- 给定
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
出来的。
上式可等价于:
可以将
D
看着一个二分类器,那么
xi
是从
Pdata
中
sample
出来的,为正类样本;
x˜i
是从
PG
中
sample
出来的,为负类样本。也即是:
那么其损失函数为:
注意下:
L
为损失函数,其两项之前应有负号。
整体算法流程
需要注意:在
learn D
时,需要
train
多次,就是训练多个
epoch
,而在
learn G
时,只需要一次。