[转]从头开始 GAN

1 前言

GAN的火爆想必大家都很清楚了,各种GAN像雨后春笋一样冒出来,大家也都可以名正言顺的说脏话了[微笑脸]。虽然目前GAN的酷炫应用还集中在图像生成上,但是GAN也已经拓展到NLP,Robot Learning上了。与此同时,在与NLP的结合过程中,我们很惊讶的发现,GAN和增强学习的Actor-Critic有曲艺同工之妙呀!Deepmind 的大神Oriol Vinyals也特地写了篇文章Connecting Generative Adversarial Networks and Actor-Critic Methods 来倡议大家研究一下两者的结合。这大大引起了我对GAN的兴趣,感觉条条大路通AI呀。GAN和RL有点像当年的量子力学和相对论,那么是不是会有一个GAN和RL的统一场论呢?这显然值得期待。

因此,好好从头分析一下GAN还是很有必要的。

2 Generative Adversarial Nets

既然是从头开始GAN,那么要说的第一篇文章必须是GAN的开篇,也就是2014年Ian Goodfellow的这篇开山之作。

在这篇paper,我们发现其实Ian Goodfellow仅用一段话就说完了GAN:

 

简单的说GAN就是以下三点:

(1)构建两个网络,一个G生成网络,一个D区分网络。两个网络的网络结构随意就好.

(2)训练方式。G网络的loss是log(1-D(G(z)),而D的loss是-(log(D(x)) + log(1-D(G(z)))注意这里并不是Cross Entropy。

(3)数据输入。G网络的输入是noise。而D的输入则混合G的输出数据及样本数据。

那么我们来分析一下这样的训练会产生什么情况?G网络的训练是希望D(G(z))趋近于1,这样G的loss就会最小。而D网络的训练就是一个2分类,目标是分清楚真实数据和生成数据,也就是希望真实数据的D输出趋近于1,而生成数据的输出即D(G(z))趋近于0。OK,这就是GAN两个网络相互对抗的本质。

那么,这样相互对抗会产生怎样的效果呢?Ian Goodfellow用一个简单的图来描述:

我们也好好说一下上面这几个图。第一个图是一开始的情况,黑色的线表示数据x的实际分布,绿色的线表示数据的生成分布,我们希望绿色的线能够趋近于黑色的线,也就是让生成的数据分布与实际分布相同。然后蓝色的线表示生成的数据x对应于D的分布。在a图中,D还刚开始训练,本身分类的能力还有限,因此有波动,但是初步区分实际数据和生成数据还是可以的。到b图,D训练得比较好了,可以很明显的区分出生成数据,大家可以看到,随着绿色的线与黑色的线的偏移,蓝色的线下降了,也就是生成数据的概率下降了。那么,由于绿色的线的目标是提升概率,因此就会往蓝色线高的方向移动,也就是c图。那么随着训练的持续,由于G网络的提升,G也反过来影响D的分布。假设固定G网络不动,训练D,那么训练到最优,D^*_g(x) = p_{data}(x)/(p_{data}(x)+p_{g}(x))

因此,随着p_g(x)趋近于p_{data}(x),D^*_g(x)会趋近于0.5,也就是到图d,是最终的训练结果。到这里,G网络和D网络就处于平衡状态,无法再进一步更新了。

作者在文章中花了很大的篇幅证明整个网络的训练最终会收敛到 p_g(x)=p_{data}(x),我们这里就不探讨了,还是看看具体的算法及实现。

 

这里面包含了一些重要的trick及训练方法:

(1)G和D是同步训练的,但是两者的训练次数不一样,G训练一次,D训练k次。这主要还是因为初代的GAN训练不稳定。

(2)注意D的训练是同时输入生成的数据和样本数据计算loss,而不是cross entropy分开计算。实际上为什么GAN不用cross entropy是因为,使用cross entropy会使D(G(z))变为0,导致没有梯度,无法更新G,而GAN这里的做法D(G(z))最终是收敛到0.5。

(3)在实际训练中,文章中G网络使用了RELU和sigmoid,而D网络使用了Maxout和dropout。并且文章中作者实际使用-log(D(G(z))来代替log(1-D(G(z)),从而在训练的开始使可以加大梯度信息,但是改变后的loss将使整个GAN不是一个完美的零和博弈。

在这篇开山之作的最后,作者就分析了GAN的优缺点。GAN可以任意采样,可以使用任意的可微模型(也就是任意神经网络都可以)。GAN生成的图像更加sharp,也就是work更好,这个是最关键的,意味着它值得推广。当然了,作者也直接说了GAN不好训练这一bug。在Future work中,作者也提到了使用GAN的各种可能性,包括conditional GAN,半监督学习等等。也许Ian Goodfellow在发表这篇文章的时候就已经意识到这将开创一个新的领域了。

3 DCGAN ( Unsupervised Representation Learning with Deep Convolutional Generative Adversarial Networks)

GAN开始出名恐怕是因为DCGAN这篇文章。该文章做出了让人难以置信的效果如上图所示。这是GAN在图像生成上的第一次非常成功的应用,也从此开始,一大堆和图像生成相关的paper就出来了。

那么这篇paper对GAN做了什么改造呢?核心可以说就一点,就是使用卷积神经网络,并且实现有效训练:

 

GAN在开山之作中就提出了,不好训练。那么DCGAN不但训练成功了,还拓展了维度,这就比较厉害了。DCGAN一共做了一下几点改造:

(1)去掉了G网络和D网络中的pooling layer。

(2)在G网络和D网络中都使用Batch Normalization

(3)去掉全连接的隐藏层

(4)在G网络中除最后一层使用RELU,最后一层使用Tanh

(5)在D网络中每一层使用LeakyRELU。

文章中作者也没有说为什么就这么做,只是因为看起来效果好。就是纯粹工程调出来了一个不错的效果。

那么具体说一下DCGAN的网络模型:

(1)G网络:100 z->fc layer->reshape ->deconv+batchNorm+RELU(4) ->tanh 64x64

(2)D网络(版本1):conv+batchNorm+leakyRELU (4) ->reshape -> fc layer 1-> sigmoid

D网络(版本2):conv+batchNorm+leakyRELU (4) ->reshape -> fc layer 2-> softmax

G网络使用4层反卷积,而D网络使用了4层卷积。基本上G网络和D网络的结构正好是反过来的。那么D网络最终的输出有两种做法,一种就是使用sigmoid输出一个0到1之间的单值作为概率,另一种则使用softmax输出两个值,一个是真的概率,一个是假的概率。两种方法本质上是一样的。

网上最出名的复现当属 carpedm20/DCGAN-tensorflow,而另一个极简版本是sugyan/tf-dcgan

下面我们来说说经过GAN训练后的网络学到了怎样的特征表达。

首先是用DCGAN+SVM做cifar-10的分类实验,从D网络的每一层卷积中通过4x4 grid的max pooling获取特征并连起来得到28672的向量然后SVM,效果比K-means好。然后将DCGAN用在SVHN门牌号识别中,同样取得不错的效果。这说明D网络确实无监督的学到了很多有效特征信息。

然后就是比较有意思的了,看G可以通过改变z向量,生成怎样不同的图片。不同的z向量可以生成不同的图像,那么,z向量可以线性加减,然后就可以输出新的图像,前面的图就是这种演示。非常神奇,说明z向量确实对应了一些特别的特征,比如眼镜,性别等等。这也说明了G网络通过无监督学习自动学到了很多特征表达。

总的来说,DCGAN开创了图像生成的先河,让大家看到了一条崭新的做深度学习的路子,如何更好的生成更逼真的图像成为大家争相研究的方向,而这一路到BEGAN,已经可以生成超级逼真的图像了,真是难以置信。

4 CGAN(Conditional Generative Adversarial Nets)

GAN中输入是随机的数据,没有太多意义,那么我们很自然的会想到能否用输入改成一个有意义的数据,最简单的就是数字字体生成,能否输入一个数字,然后输出对应的字体。这就是CGAN要做的事。

做法是非常的简单的:

就是在G网络的输入在z的基础上连接一个输入y,然后在D网络的输入在x的基础上也连接一个y:

 

改变之后,整个GAN的目标变成:

 

训练方式几乎就是不变的,但是从GAN的无监督变成了有监督。只是大家可以看到,这里和传统的图像分类这样的任务正好反过来了,图像分类是输入图片,然后对图像进行分类,而这里是输入分类,要反过来输出图像。显然后者要比前者难。

基于这样的算法,作者做了两个任务:一个是MNIST的字体生成任务,另一个是图像多标签任务。这里就谈MNIST字体生成任务,要求输入数字,输入对应字体。那么这里的数字是处理成one hot的形式,也就是如果是5,那么对应one hot就是[0,0,0,0,0,1,0,0,0,0]。然后和100维的z向量串联输入。

然后大家可以发现,这样的训练通过调整z向量,可以改变输出。这样就解决了多种输出问题:

 

可以看到可以生成不同形状的字体,只是生成质量还是有待改进,但是这已经足够验证CGAN的有效性了。

5 InfoGAN

有了CGAN,我们可以有一个单一输入y,然后通过调整z输出不同的图像。但是CGAN是有监督的,我们需要指定y。那么有没有可能实现无监督的CGAN?这个想法本身就比较疯狂,要实现无监督的CGAN,意味着需要让神经网络不但通过学习提取了特征,还需要把特征表达出来。对于MNIST,如何通过无监督学习让神经网络知道你输入y=2时就输出2的字体?或者用一个连续的值来调整字的粗细,方向?感觉确实是一个非常困难的问题,但是InfoGAN就这么神奇的做到了。

怎么做呢?作者引入了信息论的知识,也就是mutual information互信息。作者的思路就是G网络的输入除了z之外同样类似CGAN输入一个c变量,这个变量一开始神经网络并不知道是什么含义,但是没关系,我们希望c与G网络输出的x之间的互信息最大化,也就是让神经网络自己去训练c与输出之间的关系。mutual information在文章中定义如下:

I(c, G(z, c)) = \mathbb{E}_{c \sim P(c), x \sim G(z, c)} \left[ \log Q(c \vert X) \right] + H(c)

其中的H为c的entropy熵,也就是log(c)*c,Q网络则是反过来基于X输出c。基于I,整个GAN的训练目标变成:

\min_{G} \max_{D} \, V(D, G) - \lambda I(c, G(z, c))

有了这样的理论之后,就具体如何训练的问题了。

相比CGAN,InfoGAN在网络上做了一定改变:

(1)D网络的输入只有x,不加c。

(2)Q网络和D网络共享同一个网络,只是到最后一层独立输出。

6 说明

这是很早之前写的,因为觉得写的1w字貌似也还有点用,还是发出来吧。由于时间有限加上知乎上也已经有大量GAN的分析解读,本来打算把GAN最新的文章也拿来分析分析,决定还是算了,望见谅。

 

posted @ 2018-06-27 17:24  luofeel  阅读(615)  评论(0编辑  收藏  举报