听课(李宏毅老师的)笔记,方便梳理框架,以作复习之用。本节课主要讲了生成式对抗网络(GNN)。
目录
Generation
Network as Generator
到目前为止,我们学习到的是类似于函数的network,给定一个x,经过network输出一个y。比如输入为图片,sequence等,输出为数值,类别,sequence等。
而作为generator的network,输入要加上一个z,这个z是由某个已知的简单分布中采样得到的。比如x是一个向量,z也是一个向量,拼接起来或者加起来都可以。
由于z是采样得到,每一次的z都不一样,那么得到的y也不一样。
z的分布可以是高斯分布(Gaussian Distribution),均匀分布(Uniform Distribution)等简单的分布。
此时,输出y就是一个复杂的分布。像这样能输出复杂分布的network,我们称之为generator。
Why Distribution?
通过输入过去的frames,训练network,预测小精灵下一步的游戏画面。
但是会发现预测出来的小精灵走着走着分裂了。这是因为训练集中可能同时存在向左转和向右转的数据。所以network会得出这样的输出。这样的问题可以用generator来解决。
如果在输入的时候加入z,那么输出变成了distribution。比如z服从二项分布,当抽到的z为0时,就向左转;当抽到的z为1时,就向右转。
当需要创造力时,就可以使用generator。同样的输入可以有不同的输出。典型的GNN应用如下:
- drawing
- chatbot
Generative Adversarial Network(GAN)
All kinds of GAN
用GAN前面加字母来命名后面的GAN模型,但是有太多GAN模型,所以会有重合的,甚至有用希腊字母α来做前缀的。
Anime Face Generation
在unconditional generation中,没有x,输入是低维度的z,输出是高维度的y。
以下z的分布都以Normal distribution为例。
Q:为什么是normal distribution,这里可以是别的分布吗?
A:可以是别的分布,不同的分布差异不大,只要选一个简单的分布就行,因为generator会想办法把简单的z向量映射到高维度的输出向量,所以将选择分布的事情交给generator就可以了。
Discriminator
输入是一张图片,输出是一个数字。这个数字越大,则表示图像越真实,越接近目标值。
Discriminator的架构由自己决定,可以使用CNN的架构来进行图像处理。
Basic Idea of GAN
GAN的基本思想来源于鸟和蝴蝶相互促进彼此的进化。
最开始鸟会根据颜色来捕食鸟,蝴蝶随之进化成不那么显眼的颜色,鸟由于需要生存,也进化成能识别不显眼颜色的蝴蝶,所以蝴蝶又进化出了纹路,伪装成枯叶,有了叶脉,那么鸟也会随之进化。
互相促进进化就是GAN的基本思想。第一代的generator产生出一些图片,让第一代的discriminator尝试分辨这是真的图片还是假的。discriminator的分辨结果促进产生第二代的generator,生成的图片更加真实,而第二代的discriminator也会进化,依次往复,互相促进进化。这就是"对抗"的由来。
Algorithm
Step 1: Fix generator G, and update discriminator D
首先初始化generator 和 discriminator。
其次,固定generator的参数值,随机采样一些向量输入generator, 生成出来的图片其实没有下图所示的那么好,可能就像电视机雪花一样杂乱。
然后,从真实的数据库中采样得到真实图片,在训练过程中,让discriminator分辨真实和generator产生出的图片。可以当做回归或者分类的问题。
最后更新discriminator的参数。
Step 2: Fix discriminator D, and update generator G
训练generator的过程可以拟人化地说为欺骗discriminator。
input: one vector
output: score
goal: discriminator生成的score 越大越好
可以将generator和discriminator看成是一个整体,一个大的network,在这个network中间的某层,会出现一个维度和图片的pixel×3一样的向量,那就是generator生成的图片。
在训练这个大模型的过程中,discriminator的参数是固定不变的,只更新generator的参数。
与传统的loss function相比,该network的目标是让discriminator生成的score 越大越好,所以是采用gradient ascent,而非gradient descent。
Circulate
Results of Generation
在现有的研究中,GAN已经能做到:往左看的人脸和往右看的人脸做内插法,会得到一个向正面看的人,而不是简单地将两张图片进行叠加。
Theory behind GAN
Objective for Generator
在训练generator时,我们的目标应该是让generator生成的分布与数据尽可能相似。以下图下半部分的一维数据为例,假设原始的一维数据是成正态分布的,经过generator之后变成了绿色的一维数据,数据点的分布已经与原来的正态分布不一样了,但是与目标数据的分布更相近了。
那么理想的generator就是generator产生的数据分布(P_G)和真实数据分布(P_data)尽可能相似的generator。P_G和P_data的divergence越小,则二者越相似,generator越好。然而两个分布的divergence该如何计算?
Sampling is Good Enough
在计算divergence时,不需要用完整的分布来计算,只需要从P_G和P_data采样即可。sampling from P_data:从图库里随机挑选几张图片。
sampling from P_G:从normal distribution中采样几个vector输入进generator后产生图片。
然而如何计算采样的数据的divergence呢?先看如何训练discriminator。
Objective for Discriminator
在训练discriminator时,我们的目标是让真实数据的得分更高,而generator产生的数据得分更低。目标函数为V(G,D),由两部分组成,分别为:
- 从真实数据P_data采样得到的数据的得分取log;
- (1-采样generator产生的数据P_G的得分)取log
真实数据得分越高,generator产生的数据得分越低,则两者差距越大, 目标函数V(G,D)越大。当目标函数V(G,D)最大时,有最好的discriminator。这里的目标函数V(G,D)其实是-cross entropy。而这个值与JS散度有关。
目标函数与JS散度有关可以很直观地从下图中感受到。如果真实数据和产生的数据分布相似(即JS散度小),两者得分也相似,那么目标函数就不会很高。
讲完discriminator的目标函数之后,再回到generator的目标函数,也就是下图。
既然discriminator的目标函数与divergence有关,那么是否可以直接用discriminator的目标函数替换掉generator中的计算divergence部分?但是如果要先得到最好的G是不行的,因为目标函数里包含了G本身。所以这就解释了之前的generator和discriminator的训练顺序,是先固定G,更新D,这样得到最好的D之后固定D,才能用argmin max V(G,D)来计算出最好的G。
那既然目标函数都和JS divergence相关了,为什么不直接用JS divergence呢?
Other Divergence?
其实可以用JS divergence,但是目标函数需要更改。详见下图。
GAN is Difficult to Train
就算能直接用JS divergence,GAN依然很难train。所以需要一些训练GAN的技巧。
Tips for GAN
Problems of JS Divergence
P_G和P_data的重合部分很少。
原因1:数据本身的特性。图片本身是高维数据嵌入的低位结构,假如说图片是二维的,那么P_G和P_Data就是两条线,重合的部分可以忽略不计。
原因2:采样。即使P_G和P_Data有重合部分,也有可能因为采样点不够多或者不够密,被认为没有重叠。
只要P_G和P_Data没有重叠,JS散度算出来就是log2。下图中,第二种情况明显比第一种情况两个数据更相似,JS散度却是一样的。
Wasserstein Distance
这是为了解决JS散度提出的新的距离计算方法。想象有一台挖土机,要把Q的这堆土推成跟P一样的土堆,要经过的距离就叫做Wasserstein Distance.
比如下图,要将P土堆搞成和Q一样的土堆,有多种推法。在这么多种推法中,有最小距离的就是Wasserstein Distance.
Advantages of Wasserstein Distance
Wasserstein Distance更能体现两个分布的距离。
对于WDistance而言,训练演化的过程类似于人类压球的进化过程(下图所示),不像JS散度从最左边的图片一下子变到最右边的图片,使用WDistance的训练更加循序渐进。
WGAN
Wasserstein Distance的计算:解决下图中的obejective function,得到的值就是Wasserstein Distance.
y:指network的输出,一张图片
E:期望
D:必须是平滑的
D(y):discriminator的输出
如果对D没有限制,那么discriminator会给real极大的正值,给generated极小的负值,training就无法收敛,算出来的值就是无限大的。
平滑的Discriminator可以让real和generated的值变化没有那么剧烈。
如何计算这个objective function呢?很直接的想法就是再训练一个model, Original WGAN中的处理,是将parameter限制在-c~c,Improved WGAN是在真实数据和采样数据中取一点,使其gradient接近1。(这部分详见论文)
这一段都不知道老师在说啥。听不懂一点。
GAN is Still Challenging
由于GAN的训练过程是分为Generator和Discriminator的训练,他们两个是一个整体,只要有一方失败了,另外一方也会停止进化。
GAN for Sequence Generation
如果要将GAN用于产生句子,那么transformer里的decoder就相当于GAN里的generator,再训练一个discriminator,将decoder产生的句子输入进discriminator,输出分数,判断这句话是机器生成的还是真的句子。
在做梯度下降的时候,参数会更新,所以decoder有很小的改变,导致decoder的输出也会有很小的改变。在经过max之后得到token,分数最大的token是没有改变的,所以score也不会改变。所以不能做梯度下降,这就是GAN难训练的原因。
思考:decoder产生输出之后会进行max得到最终token,CNN里面也有max pooling,为什么CNN能训练起来而GAN却不能训练起来呢?原因是,这里经过max的输出之后得到的是一种分类,最大的max是多少都不会影响输出(这里看不懂的建议再去看看transformer那一节),pooling那里输出的就是最大值,所以会随参数变化而变化。
可以用强化学习来训练discriminator,但是强化学习也很难训练,GAN也很难训练,这俩加在一起更难训练。
ScarchGAN这个论文可以将GAN训练起来。
Possible Solution
可以用传统的supervised learning。给训练的资料分配相应的向量,让network进行学习。
Evaluation of Generation
Quality of Image
评判图像的好坏,早年是用人类肉眼评价。但是这样不客观不稳定。
所以现在用影像辨识系统,将图片输入进辨识系统,如果输出的分布特别集中,表示识别到了具体的物品。如果特别分散,表示没有识别出来。
Diversity-Mode Collapse
generated data中出现很多张相似的图片。要解决Mode Collapse,可以多保存checkpoint,在mode collapse之后恢复到前一个checkpoint继续训练即可。
Diversity-Mode Dropping
Mode Dropping比Mode Collapse更难发现。
比如下方在t iteration的时候,产生的图像看似没有任何问题,实际上肤色都偏白,多样性不如真实数据。
Diversity
要确保生成图像的多样性,可以将生成的图片丢入分类系统,再将这些输出进行平均,如果平均下来,分布仍然很集中,则说明原来生成的图片缺少diversity,大部分图片都是一样的。
如果平均后的分布非常平坦,则说明有充足的多样性。
Diversity vs Quality of Images
从评判分布的方法来看,似乎评价生成图片的diversity和quality是完全相反的,一个要分布平坦,另一个要分布集中。实际上diversity和quality评价的对象是不一样的,diversity是针对很多生成图片的平均分布,而quality单考虑一张图片的分布。
Frechet Inception Distance(FID)
在上张图片中,提到了一个衡量图片quality和diversity的指标叫做Inception Score. 如果quality好,diversity大,则有好的IS. 然而在生成人脸的任务中,这个指标不合适,因为对于人脸来说,即使是不同的肤色或者发色,类别都是归为人脸,所以diversity不会很高。
所以引进了一种新的指标FID. 在计算diversity的时候,需要将图片输入CNN进行分类。在输出分类的前一步softmax之前,就将向量取出来,虽然最后的分类都是人,但如果肤色或发色不一致,那么这时的向量还是不同的。
橙色的点:真实数据在softmax之前的向量
蓝色的点:生成数据在softmax之前的向量
这些点会组成各自的分布,两个分布越接近,则frechet inception distance越小,说明生成图片更加真实。
但是如果要模拟这样的分布,就需要采样大量的点,所以计算量也会很大。这是一个不可避免的问题。
We Don't Want Memory GAN
上述讲的方法没有完全解决GAN的评估问题,现在还有一个问题就是,有可能会产生和真实数据一样的图片,或者只是简单翻转了一下。这样评估出来效果特别好,但是不是我们真正想要的。
Conditional Generation
之前讲的都是unconditional generator,即输入只有随机分布的一个向量,如下图所示
Generator
如果想要操控generator的输出,可以在输入里加入一个条件x,让generator根据我们的要求生成特定的图片。conditional generator可以应用在文字生成图片上,这是一个监督学习的问题,需要有标签的数据,所以要收集一些数据才能训练conditional generator。x的处理可以使用RNN或者transformer的decoder,对文字进行编码,转为向量输入generator.
Discriminator
在Conditional GAN中,generator的输入与Unconditional GAN不同,discriminator也不能和Unconditional GAN一样。如果和Unconditional GAN中的discriminator一样的话,那么discriminator只会关注图片是否真实,而忽略输入中指定的条件。只要generator生成的图片够真实就能骗过discriminator.
所以discriminator也需要输入condition, 只有文字和图片相匹配,discriminator才会给高分。因此,训练资料是文字和图片配套的,还需要有相应的标签。
训练的资料可以包括这三种:
红眼,红眼的图片,标签为1
红眼,乱七八糟的图,标签为0
红眼,不是红眼的人,标签为0(文字叙述与图片不匹配)
光有前两类的训练资料是不足的!
Application
Text to Image
Conditional GAN可以应用在文字生成图片上,前文已讲过。
Image to Image
图片生成图片的一些例子:
给出房屋设计图,生成房屋照片
给黑白图片,让GAN着色
给素描图,生成实物
给白天的图片,生成夜晚的图片
给起雾的图片,把生成的雾除掉
要做到图片生成图片,只需要将text to image的模型稍加修改即可。
将输入的文字替换成图片即可。
如果不用GAN,只用监督学习的话,生成的结果是模糊的,这就回到了这节课最开始的引入例子,让监督学习模拟小精灵的走向,而模型既学到了向左走,也学到了向右走,最后小精灵分裂了。
如果只用GAN,虽然产生的图片非常真实,但会多出来一些输入图片没有的东西。
所以要同时使用GAN和监督学习。
Voice to Image
比如,输入一段狗叫的声音,输出一张狗的图片。
这样的资料也不难收集,可以从影片中爬取。
要检查GAN是否真的学到了知识,而非简单地输出保存的图片,可以尝试把音量调大。比如水流的声音越来越大,结果生成更大的瀑布,说明GAN真的学到了知识。最后一排的生成结果不太好,前面两排是比较好的。
Talking Head
Conditional GAN还可以生成会说话会动的头像。
Learining from Unpaired Data
之前的训练资料都是有标注的成对资料,如果没有这样的资料应该如何训练GAN呢?
比如要将真实人物的照片转化成二次元人物的头像,这样的任务,成套的训练资料是很少的,不可能给几千几万张照片画出对应的二次元人物头像。这时就需要Unsupervised Conditional Generation,
将之前Unconditional GAN中Generator的输入从高斯分布,换成domain x里图片的分布,输出是domain y的分布。就能完成生成对应二次元头像的任务。
Cycle GAN
Unconditional GAN中采用高斯分布,是因为高斯分布的formulation已知,可以进行采样,那么只要现在domain x能进行采样,也就能替换掉高斯分布。而domain x的采样非常简单,只需要选取一张真实的图片即可。
训练discriminator,尝试分别domain y内的图片和不是domain y内的图片。但是如果generator生成的图片跟domain x的照片没有任何关系,却是二次元头像,那么discriminator将会给这个头像很高的分数,但这不是我们想要的。
比如输入一个戴眼镜的男士(原来是李老师。)却输出四宫辉夜,这样的问题与在Conditional GAN里遇到的问题很相似。但是在无监督的GAN里,是不能通过带有标签的成对资料解决的。
要解决这样的问题,需要训练两个generator.
generator 1:真人图片生成二次元头像
generator 2:二次元头像生成真人图片
然后让真人图片和generator 2生成的图片进行比较,越接近越好。比较两张图片的方式也很简单,两张图片就是两个向量,所以计算两个向量的距离即可。
像这样x生成y,y又生成x',比较x与x',就像一个循环,所以叫Cycle GAN
而判断Generator_y->x生成的图片是否像真人,需要训练配套的discriminator. 该discriminator仍然可能被欺骗(与之前判别二次元头像的discriminator一样),如果generator生成的图片很像真人,却跟输入的二次元头像毫无关系,Discriminator_y->x仍然会给高分。所以还需要跟上图一样的两个generator。
more GANs
下面三个GAN基本思想都差不多。
StarGAN
Cycle GAN是在两个风格之间转化,StarGAN是在多个风格之间进行转化。
一些真人照片转二次元头像的例子
Application
Picture Style Transfer
在讲解Cycle GAN的时候已经把图片风格转化当成例子讲过。
Text Style Transfer
这个应用顾名思义,是转化文本风格,比如悲伤的句子转化成开心的句子。
训练数据可以从网络上爬取,点赞的就是积极的,点踩的就是负面的。配套的训练数据很难获取,所以很适合用Unsupervised Unconditional GAN.
输入:只需要将文本用transformer里的decoder进行编码,变成向量
其余架构跟Cycle GAN保持一致。
部分实验结果如下图所示
所以GAN是知道工作和睡觉是完全相反的对吧!
这个发明的应用在于你可以把它装载在你的耳机里面,听到导师或者老板骂你,就会转化成鸟语花香,你就会特别快乐。
Other Applications
提取摘要,翻译,语音识别