GAN介绍(李宏毅GAN课程学习笔记)
Generative Adversarial Network
GAN由Ian Goodfellow于2014年提出,并迅速成为了非常火热的研究话题,GAN的变种更是有上千种,深度学习先驱之一的Yann LeCun就曾说, "GAN及其变种是数十年来机器学习领域最有趣的 idea"。
听起来很厉害的样子,那么什么是GAN呢?
生成式对抗网络(GAN, Generative Adversarial Networks )是一种深度学习模型,是近年来复杂分布上无监督学习最具前景的方法之一。模型通过(至少)两个模块:生成模型(Generative Model)和判别模型(Discriminative Model)的零和博弈进行学习,即通过两个网络的互相对抗来达到最好的生成效果。
这一段看完了,所以,什么是GAN?看懂了吗?感觉充满了问号。。。接下来跟着李宏毅老师的节奏好好梳理一下。
1、生成模型、判别模型
概念里说,模型通过框架中(至少)两个模块:生成模型G(Generative Model)和判别模型D(Discriminative Model),那么什么是生成模型?什么是判别模型?
生成模型G是指能够随机生成观测数据的模型,尤其是在给定某些隐含参数的条件下。在GAN中,可以理解为输入一个vector,生成一个图片、语音、文本等有结构的输出。
生成模型 / 生成器判别模型D是一种对未知数据与已知数据之间关系进行建模的方法,在GAN中,可以理解为判别器建立了训练数据与生成器输出的数据的关系,按训练数据的标准为生成的数据打分。
判别模型 / 判别器以图像的生成为例:
- G负责生成图片。接收一个随机的噪声z,通过z生成图片G(z);
- D负责判别一张图片是不是“真实的”。输入是一张图片x,输出D(x)表示x为真实图片的概率,如果为1,代表是真实图片的概率为100%,而输出为0,代表不可能是真实的图片。
知道了生成器和判别器是什么,那么他们是怎么配合工作来推动GAN的学习的呢?
以学习画二次元人物头像为例:
- 第一步:我们最开始画人物头像只知道有一个头的大致形状,用笔也不行,画出来的一片糊,老师搭眼一看,垃圾!噼里啪啦给我们10个大嘴巴子,老师的快乐+10,我们的快乐-10;
- 第二步:我们痛定思痛,努力学习,画出的头像好多了,甚至还能看到水灵灵的大眼睛,老师参考一下二次元美图:鼻子呢!噼里啪啦给我们9个大嘴巴子,老师的快乐+9,我们的快乐-9;
- 第三步:我们进步了!老师又学习了一会二次元美图说:“我觉得不行”,噼里啪啦给我们8个大嘴巴子,老师的快乐+8,我们的快乐-8;
就这样一步一步,老师觉得我们画的头像和真正的二次元美图一样美的时候,就不再抽我们大嘴巴子,我们终于出师了,是一个合格的生成器了!(这里的老师就是判别器,判别器也是需要学习的,虽然老师水平高,但他不学习也不一定知道什么是美丽的二次元头像)
2、零和博弈
生成器和判别器通过零和博弈来学习,什么是零和博弈呢?
零和博弈(zero-sum game),又称零和游戏,是博弈论的一个概念,属非合作博弈。
它是指参与博弈的各方,在严格竞争下,一方的收益必然意味着另一方的损失,博弈各方的收益和损失相加总和永远为“零”,可以说自己的幸福是建立在他人的痛苦之上的,二者的大小完全相等,因而双方都想尽一切办法以实现“损人利己”。
在上面的例子中,老师(判别器)抽我们(生成器)大嘴巴子,抽的越多他的快乐越多,我们的快乐越少,我们通过和老师博弈改变双方的快乐,但快乐数值的总和一直都是零,这就是判别器和生成器的零和博弈,这种博弈的关系也是GAN中“Adversarial”的由来。
3、GAN算法流程
了解了GAN中的几个关键词的含义后,我们来看看GAN是怎样运行的:
- 初始化generator G 和discriminator D;
- 每一次迭代过程中:
- 固定 G, 只更新 D 的参数。从你准备的数据集中随机选择一些,再从 G 的output中选择一些,现在等于 D 有两种input。接下来,D 的学习目标是, 如果输入是来自于真实数据集,则给高分;如果是 G 产生的数据,则给低分,可以把它当做一个回归问题或分类问题。
- 接下来,固定住 D 的参数, 更新 G 。将一个向量输入 G, 得到一个output, 将output扔进 D , 然后会得到一个分数,这一阶段 D 的参数已经固定住了,G 需要调整自己的参数使得这个output的分数越大越好,希望能骗过判别器。
过程听起来不是很复杂,不过问题是生成器和判别器两个NN网络是用什么结构组合在一起的呢?
其实,generator和discriminator是同一个大的网络,像上图,整个大的网络的前半部分是generator,后半部分是discriminator,所以其输入是vector,输出就是得分,而图片就在中间hidden层,即两个网络的衔接处。所谓的生成是指:网络中间的一层hidden-layer的输出是一个图片,判别是指:对这个生成的图片,网络的后半部分会训练出一个得分(或者说概率)。
用稍微数学化一些的语言来表示上述过程:
GAN 算法流程1、结构化学习(Structured Learning)
什么是结构化学习?
在机器学习过程中,对数据的拟合其实就是在找一个拟合函数:
对于回归问题(Regression)来说,这个函数输出一个标量(scalar)
对于分类问题(Classification)来说,这个函数输出一个类别(one-hot 向量)
如果输出的是一个序列,一个矩阵,一个图,一颗树...
其输出由具有依赖关系的组件组成的,这就叫做结构化学习。
2、结构化学习的难点
首先,对于一般的分类问题,每个类别会对应多个样本,而结构化学习如果把每一个output当做一个类别来看的话,输出空间就非常大,因为其输出是多种多样的,很可能是One-shot learning甚至Zero-shot learning。
One-shot learning:对某一/某些类别只提供一个或者少量的训练样本;
Zero-shot learning:对某一/某些类别完全不提供训练样本。
以文本为例,输入“吃了吗?”,输出“吃过了”、“吃了”、“吃啦”等等都可以看做不同的类,所以用普通的分类是难以解决的。
再者,结构化学习的输出是由具有依赖关系的组件组成的,需要考虑整体。
GAN的生成器可以生成各种输出,判别器可以判断输出的好坏,似乎这两个模块都有很强的学习能力,那么他们能独立工作吗?为什么一定要进行博弈呢?
首先来看看生成器能不能自己学习。
生成器当然可以自己学习,在GAN之前就有自编码器AE、变分自编码器VAE。
1、自编码器AE
自编码器是一个如下图所示结构的神经网络,其输入和输出的维度相同,中间的隐含层维度最小,作为编码的结果,其前半部分encoder会尽可能的保留原始输入的信息,以便在后半部分decoder还原输入。
自编码器网络结构其实自编码器AE得到的decoder就是一个生成器,不过AE的缺点是无法处理没有训练过的数据,当给code加上噪声后,就不知道会输出什么了,可能是一个完全的乱码或者是噪声,我们希望的是“生成模型”能够对任意的输入编码产生有相关意义的数据,这就是我们后面的“变分自编码器VAE”所要做的事情。
2、变分自编码器VAE
变分自编码器直接编码成高斯分布,可以对各种随机输入产生有意义的输出。
3、这一类生成器到底存在什么缺点
编码器的目标是让输出与输入尽可能的相似,怎么评价相似呢?实际上是计算输入向量与输出向量的距离,拿图片来说,向量距离表示两个图片有多少像素不同,但没法表达更多的东西,比如位置等。
如下图所示,编码器会认为上面只差1个像素的图更好,但实际上上面两个在奇怪的地方多/少一个像素点,更容易看出不是人的手写数字,而下面两个虽然像素差的多,但其实只是笔画长一点而已,更像是手写的数字。
编码器的缺点1组间之间的关系非常重要,在编码器中,尽管两个组间高度相关,但却无法相互影响,我们需要structure 来约束这个事情。就是在后面在加几个隐藏层,就可以调整第L层的神经元输出。也就是说理论上,VAE要想获得GAN的效果,它的网络要比GAN要深才行。
编码器的缺点1而且由于VAE算法采用的分布采样,因此做一些离得比较散的目标效果不好:
下图中绿色是目标,蓝色是VAE学习的结果
编码器的缺点2总结一下,不依靠判别器,生成器独立去学习是可以的,不过生成器是一个一个component来生成,每个component之间的关系不好控制,存在一定的缺点,不能从全局把握结果的好坏。
那么,判别器能不能独立学习来生成好的结果呢?
判别器也是可以独立学习的。
判别器也就是Evaluation function, Potential Function, Energy Function …其特点是top-down evaluation,所以很容易控制component之间的关系,能更好的判断一个结果的好坏,以手写数字为例,判别器能轻松的捕捉到元素之间的相关性,这可是生成器很难解决的问题啊。
例如上面提到的问题,图中所示的CNN Filter就可以轻松识别是不是有孤立的的像素点。
那么应该怎么做才能让判别器得到好的输出呢?
只需要穷举所有可能的x,再挑一个使得判别器得分最好的那个即可:
1、判别器独立训练
判别器训练的一个难点是缺失负向样本,比如我们想要生成手写字体或者二次元头像,那么我们的训练数据其实只有正向样本,或许我们可以通过给正向样本增加噪声来得到负向样本,但我们制作的负向样本的质量及分布是很难把握的,怎么解决这个问题呢?
可以采用让判别器自己来生成负向样本的方法,算法流程如下:
判别器独立训练流程- 首先拿出正样本,并根据正样本随机生成负样本,正负样本一起送入判别器进行训练;
- 在每次迭代中,训练出一个能区分正负样本的判别器;使用此判别器通过 argmax 生成最好的负样本(假设我们能做到);
- 再与真样本一起送入鉴别器进行训练,如此循环。
看起来似乎和GAN训练差不多,但其实还存在着问题。如下图可以帮助我们理解判别器训练的过程,可以理解为判别器在为真实样本打高分,同时压制其他样本的得分,并在每次迭代中修复自己的漏洞,最终希望训练到除了真实样本其他全是低分:
其缺点是什么呢?
在高维空间中,负样本采样过程其实是很难进行的,再者判别器生成样本的过程,即argmax过程,要枚举大量样本,效率很低。
判别器的生成既然这么麻烦的话,真的有用判别器来做生成任务的吗?实际上,概率图模型就是一类典型的判别器做生成的例子。
思考一下,概率图模型我们会有一个图,根据图还会有一个Potential Function(势函数,详细马尔科夫随机场、CRF),这不就形成了一个可以打分的判别器吗!计算出来的概率不就是打的分吗?想一下CRF的训练,就是通过给正向样本和负样本打分,不过迭代过程是不是有我不确定,HMM应该就没有吧?总之这个角度的思路是非常棒的!
2、判别器 VS 生成器
总结一下,判别器和生成器的区别:生成器 VS 判别器
生成器 VS 判别器3、生成器 + 判别器
综合以上所述的生成器和判别器的优缺点,我们发现两者是互补的,因此将其组合起来使用,充分利用两者的优势:
生成器+判别器的训练流程Benefit of GAN
(1) From Discriminator’s point of view
• Using generator to generate negative samples
(2)From Generator’s point of view
• Still generate the object component-bycomponent
• But it is learned from the discriminator with global view. (跟discriminator 学习大局观)
GAN 的数学理论及推导在下一篇详述,李宏毅老师在第一节介绍课程中也没有讲这部分。
主要参考
对抗生成网络(GAN)教程(2018) 李宏毅
网友评论