第十八周周报
- 摘要
- Abstratc
- 一、机器学习------生成式对抗网络(GAN)------(下)
-
- [1. 训练 GAN 的难点与技巧](#1. 训练 GAN 的难点与技巧)
- [2. GAN 的性能评估方法](#2. GAN 的性能评估方法)
- [3. 条件型生成(conditional generation)](#3. 条件型生成(conditional generation))
- [4.Cycle GAN(循环对抗生成网络)](#4.Cycle GAN(循环对抗生成网络))
- 总结
摘要
本周周报主要对GAN剩下的知识进行了补充学习。周报详细描述了训练GAN存在的难点和训练GAN时的一些技巧,然后还介绍了如何去评估一个GAN的性能的好坏。此外,周报还补充了之前提到的条件型GAN(conditional GAN)。最后,周报通过头像风格迁移引出了Cycle GAN(循环对抗生成网络),并详细描述了其概念原理、应用场景以及其拓展。
Abstratc
This weekly report primarily supplements the remaining knowledge of Generative Adversarial Networks (GANs). It provides a detailed description of the challenges associated with training GANs and various techniques used during the training process. The report also introduces methods for evaluating the performance of a GAN. Additionally, it elaborates on Conditional GANs, which were mentioned previously. Finally, the report introduces Cycle GAN (Cyclical Adversarial Network) through the example of avatar style transfer, and thoroughly describes its conceptual principles, application scenarios, and extensions.
一、机器学习------生成式对抗网络(GAN)------(下)
1. 训练 GAN 的难点与技巧
GAN是以难以训练而闻名的,就像我们之前学习的RNN一样如果用常规的方法去训练,是很难train出一个好的模型。
我们先复习一下,GAN在训练的时候 Generator 和 Discriminator 要做些什么,如下图所示:
Generator:负责生成图片,这些图片要住够逼真,这样才可以"欺骗"Discriminator。
Discriminator:负责判断图片是Generator生成的还是真实的data。
Generator和Discriminator都是一个神经网络,它们是之间是互相"卷"而成长的
因为如果Discriminator太强了,那么Generator就会很难骗过它,Generator就会很难产生出真的图片。但是如果Generator太强了,那么Discriminator就会很难分辨真图片和假图片。
如果其中有一方摆烂了,那么另一方也会摆烂。
只要其中一者发生什么问题停止训练,另外一个就会跟着停下训练就会跟着变差。假设在训练Discriminator的时候一下子没有训练好,那么Discriminator没有办法分辨真的跟产生出来的图片的差异,同时Generator就失去了可以进步的目标,GAN 训练的难点Generator就没有办法再进步了。
GAN 很难训练是因为这两个网络必须要同时训练,而且必须要同时训练到一个比较好的状态
GAN 本质上它的训练是一个非常重要的前瞻技术。
有一些训练 GAN 的小技巧,例如 Soumith、DCGAN、BigGAN 等等
相关文章的链接如下,后续会作为补充学习
-
Tips from Soumith
https://github.com/soumith/ganhacks -
Tips in DCGAN: Guideline for network architecture design for image generation
https://arxiv.org/abs/1511.06434 -
Improved techniques for training GANs
https://arxiv.org/abs/1606.03498 -
Tips from BigGAN
https://arxiv.org/abs/1809.11096
训练 GAN 最难的一个领域是 GAN 来生成文字
要生成一段文字,可以使用一种序列到序列的模型,这种模型包含一个解码器,负责生成所需的文字。
如下图所示:
这种序列到序列模型就是我们所说的Generator。
例如,Transformer模型就是一个解码器,它在生成对抗网络(GAN)中扮演Generator的角色,负责生成我们指定的内容,比如一段文字。
生成文字的序列到序列的GAN与用于图像的GAN有何不同呢?
本质上,两者都是训练一个Discriminator,Discriminator的任务是判断输入的文字是真实存在的还是由机器生成的。而Generator的目标则是欺骗Discriminator,让它认为生成的文字是真实的。我们通过调整Generator的参数,使其生成的内容能够骗过Discriminator,让它认为是真实的文字。
因此,从算法的角度来看,用于文字的序列到序列GAN和用于图像的GAN在本质上并没有太大的不同。
对于Seq2Seq的模型其真正的难的是要用梯度下降去训练解码器,去让Discriminator输出得分越大越好,这很难做到。
如下如图所示 :
我们来思考下,假设我们改变了Decoder的参数,这个Generator,也就是Decoder的参数,有一点小小的变化的时候,到底对Discriminator的输出有什么样的影响。
如果Decoder的参数有一点小小的变化,那它现在输出的分布也会有小小的变化,因为这个变化很小,所以它对于输出的token序列生成的GAN不会有很大的影响。
其中token就是现在在处理产生这个序列的单位。
假设我们今天,在产生一个中文的句子的时候,我们是每次产生一个汉字,那这每一个汉字就是我们的token。在处理英文的时候,每次产生一个英文的字母,那字母就是你的token。
所以token就是你产生一个序列的单位,单位是你自己定义的。
假设你一次是产生一个英文的词,英文的词和词之间是以空白分开的,那就是词就是你的token。
假设输出的分布只有小小的变化,并且在取最大值的时候,或者说在找分数最大那个token的时候,你会发现分数最大的那个token是没有改变的。输出的分布只有小小的变化,所以分数最大的那个token是同一个。
那对于Discriminator来说,它输出的分数是没有改变的。
Discriminator输出也不会改变,所以你根本就没有办法算微分,也根本就没有办法做梯度下降 。
当然就算是不能做梯度下降,我们还是可以用强化学习的方法来训练Generator。但是强化学习本身是以难训练而闻名,GAN 也是以难训练而闻名,这样的东西加在一起,就会非常非常地难训练。
所以要用 GAN 产生一段文字,在过去一直被认为是一个非常大的难题。
直到有一篇文章叫做 ScratchGAN
ScratchGAN不需要预训练(pre-training),可以直接从随机的初始化参数开始,训练Generator,然后让Generator可以产生文字。
它的方法是调节hyper parameter(超参数),并且加上一些训练技巧,就可以从零开始训练Generator 。
里面的技巧,如下图所示:
使用 SeqGAN-Step 的技术,并且将训练批大小设置的很大(起码1000+),然后要用Reinforce Learing(加强学习)的方法,要改一下强化学习的参数,同时加一些正则化等等技巧,可以将GAN 训练起来,然后让它来产生Sequence。
SeqGAN-Step的具体解释如下:
此外,其实有关生成式的模型不是只有 GAN 而已,还有其他的比如 VAE,比如流模型等等,这些模型都有各自的优缺点。
变分自编码器(VAE)的解释:
流模型的解释:
在不同的情境下我们可以使用不同的方法:
- 如果我们想要产生一些图片,那就最好用 GAN,因为 GAN 是目前为止比较好的生成式的模型,它可以产生最好的图片。
- 但是如果想要产生一些文字,那就只有用 VAE 或者流模型 ,因为 GAN 在产生文字的时候,还是有一些问题。
从训练角度上看:
- GAN 从式子上看起来有一个Generator和Discriminator,它们要互动。
- 流模型和 VAE 它们都比较像是直接训练一个一般的模型,有一个很明确的目标,不过实际上训练时它们也没有那么容易成功地被训练起来。因为它们的分类里面有很多项,它们的损失函数里面有很多项,然后把每一项都平衡才能够有好的结果,但要达成平衡也非常地困难。
如果输入一个高斯分布的变量,然后使用采样出来的向量,直接输出一张照片,能不能直接用监督学习的方式来实现呢?
如下图所示:
有一堆图片,每一个图片都去配一个向量,这个向量来源于从高斯分布中采样得到的向量 ,然后我就可以用监督学习的方式来训练一个网络,这个网络的输入是这个向量,输出是这个图片。
但是难点在于,如果纯粹放随机的向量,那训练起来结果会很差。所以需要有一些特殊的方法例如生成式潜在优化等方法
2. GAN 的性能评估方法
要评估一个Generator的好坏,最直觉的做法也许是找人来看Generator产生出来的图片到底像不像真实的图片。
所以刚开始研究生成式技术的时候,很长一段时间没有好的评估方法。那时候要评估Generator的好坏,都是人眼看,直接在论文最后放几张图片,然后说这个Generator产生出来的图片是不是比较好。
所以我们可以发现比较早年 GAN 的论文,它没有数字结果,整篇论文里面没有准确度等等的数字结果,它只有一些图片,然后说这个Generator产生出来的图片是不是比较好,接着就结束了。这种方法过于主观,而且不科学。
所以有没有比较客观而且自动的方法来度量一个Generator的好坏呢?
针对特定的一些任务,是有办法设计一些特定方法的。
比如说我们要产生一些动画人物的头像,那可以设计一个专门用于动画人物面部的识别系统,然后看看我们的Generator产生出来的图片里面,有没有可以被识别的动画人物的人脸。如果有的话,那就代表说这个Generator产生出来的图片是比较好的。还可以用这个系统来比较Generator的好坏 ,比如两个Generator都是生成1000张动漫人脸,有999个可以被系统识别到。但另外一个只有99张可以被识别出来。显然第一个Generator比较好。
但是这个方法只能针对特定的任务 ,如果我们要产生的东西不是动画人物的头像,而是别的东西,那这个方法就不行了。比如它不一定是产生动画人物的,它专门产生猫、专门产生狗、专门产生斑马等等,那我们怎么知道它做得好不好呢?
实际上,有一种方法可以用来评估生成对抗网络(GAN)生成的图像质量。
这种方法涉及将GAN生成的图像输入到一个预先训练好的图像分类系统中,然后观察分类系统的反应。
如下图所示
这个分类系统的输入是一张图像,输出是一个概率分布 ,这个分布反映了图像被识别为猫、狗、斑马等不同类别的概率。如果这个概率分布非常集中,说明生成的图像在视觉上可能更接近某个特定类别,因此质量较高。相反,如果生成的图像特征不明显,导致分类系统难以判断,那么输出的概率分布就会相对均匀,表明生成的图像可能缺乏清晰和明确的类别特征 。这种方法可以作为评估GAN生成图像质量的一个参考。
这个做法会被一个叫做 模式崩塌(mode collapse) 的欺骗。
模式崩溃是训练生成对抗网络(GAN)时可能遇到的问题。如下图所示
蓝色星星代表真实数据的分布,而红色星星代表GAN模型的分布。
在这种情况下,生成模型输出的图片往往非常有限,比如在右边的动漫头像中,可能单看某一张图片觉得效果还不错,但一旦生成多张图片,就漏出马脚了。
当生成多张图片时其生成的图片种类非常单一,而且伴随着图片怪异的问题。
从直观上理解,模式崩溃可以看作是Discriminator的盲点。
一旦Generator学会了生成能够欺骗Discriminator的图片,它就总是能够成功,而Discriminator则无法识别出这些图片是伪造的。
至于如何避免mode collapse,目前还没有一个完美的解决方案。
有一种避免mode collapse方法是:
在训练Generator时持续保存训练的中间结果。在模式崩溃发生之前停止训练,然后使用之前的模型 。这样,我们可以在模式崩溃之前捕捉到较好的模型表现,从而避免崩溃带来的问题。
然而,模式崩溃这个问题至少是我们可以识别出来的。当Generator总是重复生成同一张脸时,我们不会认为这是一个好的Generator。
但有些问题更加隐蔽,那就是我们无法确定Generator产出的图片是否真的具有多样性 。这种隐性的问题可能不会立即显现,但它们对于评估Generator的性能和输出质量同样至关重要。
这个问题叫做------模式丢失(model dropping)
model dropping指 GAN 能很好地生成训练集中的数据,但难以生成非训练集的数据,"缺乏想象力"。(有点像过拟合)。其生成的数据可能仅代表了真实数据的一部分。
如下图所示:
这红色和蓝色的星星的分布乍一看,这些生成的数据可能看起来还不错,甚至在分布的多样性上也似乎足够,然而,我们并不知道真实数据的多样性实际上要大得多。
事实上,即使是目前一些表现出色的GAN,如BGAN、ProgressGAN等,在生成非常逼真的人脸图像时,仍然或多或少存在模式丢失的问题。
如下图中的生成人脸所示:
其人脸除了变换了肤色,样貌几乎都是一模一样的 。如果您观察GAN生成的人脸图像足够多,您会发现尽管这些图像非常逼真,但似乎总是那么几张脸,而且有一个非常独特的特征是,看得越多,您就越觉得这些脸似乎是被生成出来的。
至今,模式丢失的问题在本质上仍未得到根本解决。
虽然存在以上模式坍塌、模式丢失等等的问题,但是 我们需要去度量Generator产生出来的图片到底多样性够不够。
有一个做法是借助我们之前介绍过的图像分类,把一系列图片都丢到图像分类器里,看它被判断成哪一个类别。
如图下所示:
每张图片都会给我们一个分布,我们将所有的分布平均起来,接下来看看平均的分布长什么样子。
如果平均的分布非常集中 ,就代表现在多样性不够 。
如果平均的分布非常平坦 ,就代表现在多样性够了 。
具体来讲,如果什么图片输入到图像分类系统中的输出都是第二种类别,那代表说每一张图片也许都很像,也就代表输出的多样性是不够的,那如果另外一个案例不同张图片丢进去,它的输出分布都不一样,那就代表说多样性是够的。并且平均完以后发现结果是非常平坦的,那这个时候代表多样性是足够的。
当我们用这个图像分类器来做评估的时候,对于结果的多样性和质量好像是有点互斥的。
因为我们刚才在讲质量的时候说,分布越集中代表质量越高,多样性的分布越平均。但是如果分布越平均,那质量就会越低,因为分布越平均,代表图片都不太像,所以质量就会越低。
这里要强调一下质量和多样性的评估范围不一样
质量是只看一张图片 ,一张图片丢到分类器的时候,分布有没有非常地集中。
多样性看的是一堆图片分布的平均 ,一堆图片中图像分类器输出的越平均,那就代表现在的多样性越大。
所以很好的Generator其实是对于当单张图片分布特别突出(质量高),但是多个分布平均下来又特别平坦(多样性够)
过去有一个非常常被使用的分数,叫做 Inception score(初始评分) 。
其顾名思义就是用 Inception 网络来做评估,用 Inception 网络度量质量和多样性。
Inception 网络的解释如下:
其即考虑了图像的质量也考虑了图像的多样性。如果质量高并且多样性又大,那 Inception
分数就会比较大。
目前研究人员通常会采取另外一个评估方式,叫 Fréchet Inception distance(FID)。
具体的运行步骤如下:
先把Generator产生出来的人脸图片,丢到 InceptionNet 里面,让 Inception 网络输出它的类别。
(这里我们需要的不是最终的类别,而是进入 Softmax 之前的隐藏层的输出向量,这个向量的维度是上千维的,代表这个图片)
如下图所示:
- 图中所有红色点代表把真正的图片丢到 Inception 网络以后,拿出来的向量。这个向量其实非常高维度,甚至是上千维的,我们就把它降维后画在二维的平面上。
- 蓝色点是 GAN 的Generator产生出来的图片(即丢到 Inception 网络以后进入 Softmax 之前的向量。)
- 接下来,我们假设真实的图片和生成的图片都服从高斯分布,然后去计算这两个分布之间的 Fréchet 的距离。
- 两个分布间的距离越小越好,距离越小越代表这两组图片越接近,也就是产生出来的品质越高。
这里还有几个细节问题:
- 假设为高斯分布,这个假设可能不总是完美的,特别是当分布的形状明显偏离高斯分布时。
- 另外一个问题是如果要准确的得到网络的分布,那需要产生大量的采样样本才能做到,这需要一点运算量,也是做 FID 不可避免的问题。
FID 算是目前比较常用的一种度量方式,那有一篇文章叫做"Are GANs Created Equal?A Large-Scale Study",这个 Google 完成的论文里面尝试了不同的 GAN。
如下图所示:
每一个 GAN 的训练的分类,训练的损失都有点不太一样,并且每一种 GAN,它都用不同的随机种子,去跑过很多次以后,取结果的平均值等等。
从文章的结果来看所有的 GAN 都差不多
那所以与 GAN有关的研究都是白忙活吗?
事实上也未必是如此,这篇文章做实验的时候不同的 GAN 用的网络架构都是同一个,只是疯狂调参而已,调随机种子和学习率而已。网络架构还是同一个。
是不是有某些网络架构,某些种类的 GAN 会不会在不同的网络架构上表现得比较稳定,这些都有待研究。
此外,还有一个状况。
假设 GAN 产生出来的图片,跟真实的图片长得一模一样,那此时 FID 会是零,因为两个分布是一模一样的。
如果你不知道真实数据长什么样子,光看这个Generator的输出可能会觉得太棒了,那 FID 算出来一定是非常小的,但是如果它产生出来的图片都跟数据库里面的训练数据的一模一样的话,那干脆直接从训练数据集里面采样一些图像出来不是更好,也就不需要训练Generator了。
我们训练Generator其实是希望它产生新的图片,也就是训练集里面没有的人脸。
对于这种问题,就不是普通的度量标准可以侦测的。那怎么解决呢?
其实有一些方法:
- 可以用一个分类器,这个分类器是用来判断这张图片是不是真实的,是不是来自于你的训练集的。
这个分类器的输入是一张图片,输出是一个概率,这个概率代表说这张图片是不是来自于你的训练集。
如果这个概率是 1,那就代表说这张图片是来自于你的训练集。
如果这个概率是 0,那就代表说这张图片不是来自于你的训练集。
但是存在另外一个问题:
如下图示,假设Generator学到的是把所有训练数据里面的图片都左右反转
但是分类器会觉得这张图片是来自于你的训练集 ,因为它是来自于你的训练集的图片,只不过是左右反转而已。进行分类时或者进行相似度的比较时就失效了。
所以 GAN 的评估是非常地困难的,还甚至如何评估一个Generator做得好不好都是一个可以研究的题目。
3. 条件型生成(conditional generation)
在之前讨论的生成对抗网络(GAN)中,Generator通常是无条件的,它仅从随机噪声中生成图像。
然而,现在希望能够控制Generator的输出,使其能够根据给定的条件生成特定的图像。
为此,我们引入一个条件变量 x ,Generator将根据这个条件 x 和一个随机噪声向量 z 来生成图像 y
这种Conditional Generator有哪些应用呢?
一个典型的例子是文本到图像的生成。
要实现文本到图像的生成,我们需要处理一个监督学习问题,这要求我们收集一批带有标签的数据。
例如,我们需要搜集一些人脸图片,并且每张图片都有相应的文本描述,如"红眼睛"、"黑头发"或"黄头发、黑眼圈"等。
在这种任务中,条件 x 就是一段描述性的文本 。我们的目标是,当输入一段文本时,Generator能够产生一张与文本描述相匹配的图像。
如何将文本输入到Generator中呢?
- 传统上,我们可能会使用一个循环神经网络(RNN)来处理文本,将其转换为一个向量,然后将这个向量输入到Generator中。
- 在现代,我们可能会使用一个Transformer编码器来处理文本,得到一个向量,再将其输入到Generator中。关键在于找到一种方法,让Generator能够理解文本的含义。
我们期望的模型是这样的,如下图所示:
当输入文本"红眼睛"时,模型能够生成一个红眼睛的角色图像 ,而且每次生成的角色都有所不同。
生成的角色的具体特征将取决于采样到的随机采样得到的向量 z 。不同的 z 将导致生成不同的角色,但这些角色都会具有红眼睛这一共同特征。
这就是Conditional Generator的应用之一------根据文本描述生成图像。
具体怎么做conditional GAN 呢?
现在Generator有两个输入:
一个是正态分布中采样出来的 z
另一个是条件 x 也就是一段文字
然后它会产生出来一个 y,也就是一张图片。
同时,我们需要一个Discriminator。
如果按照我们过去介绍的知识,Discriminator就是使用一张图片 y 当作输入,输出一个数值,这个数值代表输入的图片多像真实的图片。训练Discriminator的方法就是,如果看到真实的图片就输出 1,如果看到生成的图片就输出 0。这样就可以训练Discriminator,然后Discriminator跟Generator反复训练。
但是这样的方法没办法真的解条件型的 GAN 的问题!!
如果我们仅训练Discriminator以图片 y 作为输入,那么Generator可能会学会忽略输入的条件 x ,因为它只需要产生看起来清晰的图片就能欺骗Discriminator 。
所以Generator没有动机去关注输入的文字描述是什么,它只需要产生能够骗过Discriminator的图片即可。
因此,在条件型生成对抗网络(Conditional GAN)中,我们需要对设计做一些调整。
在条件型GAN中,Discriminator不仅接收图片 y 作为输入,还需要接收条件 x (即Discriminator的输出不仅要评估图片的质量,还要评估图片是否与给定的条件相匹配)
1.如果图片 y 与条件 x 不符,Discriminator应该给出低分;
2.如果图片与条件相符,Discriminator则应给出高分。
我们需要文字和图像成对的数据来训练Discriminator,所以条件型的 GAN,一般的训练是需要这个pair data(成对的标注数据)。
如下图所示:
1.在训练过程中,我们会对真实的且匹配的数据给1分 ,例如,如果文字描述和图片特征一致,我们就给1分(高分)
2.相反,如果存在不匹配 ,比如文字描述是"红眼睛"但图片显示的是"黑头发",或者文字描述是"黑头发"但图片显示的是"红眼睛",就打0分(即低分)。
通过这种方式,我们可以训练Discriminator去识别图片是否与相应的文字描述相匹配。这样的训练方法有助于确保Generator不仅产生高质量的图片,而且这些图片还要与给定的条件相符合。
那其实在实际操作中,只是拿这样的负样本对和正样本对来训练Discriminator,得到的结果往往不够好。
往往还需要加上一种不好的情况:将训练集的图片和文字估计认为的弄成不匹配。
所以通常会把我们的训练数据拿出来,然后故意把文字跟图片乱配,或者故意配一些错的,然后告诉Discriminator看到这种状况,也是要输出不匹配。用这样子的数据,才有办法把Discriminator训练好。然后Generator跟Discriminator反复的训练,最后才会得到好的结果,这个就是条件型的 GAN。
条件型的 GAN 的应用不只看一段文字产生图片,比如也可以看一张图片产生其他图片。
比如:
1.给 GAN 房屋的设计图,然后让Generator直接把房屋产生出来
2.或者给它黑白的图片然后让它把颜色着上,或者给它素描的图,让它把它变成实景实物
3.再或者给它白天的图片,让它变成晚上的图片
4.给它起雾的图片,让它变成没有雾的图片等等。
这些叫做图像翻译,也就是输入一张图片,然后产生出来另外一张图片,也叫做 Pix2pix。
相比与刚才的文字条件,现在只是从图像产生图像,把文字的部分用图像取代掉而已。
所以其中同样要产生Generator,产生一张图片,然后要产生Discriminator,Discriminator要输入两张图片,然后输出一个数值。其中可以用监督学习的方法,训练一个图片生成图片的Generator
但是可能生成的结果图片非常地模糊。原因在于同样的输入可能对应到不一样的输出。
Generator学到的就是把不同的可能平均起来,结果变成一个模糊的结果
如下图:
所以这个时候我们的Discriminator它是输入是一张照片和输入条件,同时看图片和条件看有没有匹配来决定它的输出。
另外,如果单纯用 GAN 的话它有一个小问题,它产生出来的图片比较真实,但是与此同时它的创造力、想像力过度丰富,会产生一些输入没有的东西。
所以如果要做到最好往往就是 GAN 跟监督学习同时使用,就是说你的Generator不只要骗过Discriminator,同时你的Generator还要产生出来的图片跟标准答案越像越好。
条件型 GAN 还有很多应用,比如给 GAN 听一段声音,然后产生一个对应的图片。
比如说给它听一段狗叫声,GAN 可以画出一只狗。
这个应用的原理跟刚才讲的文字变图像是一样的,只是输入的条件变成声音而已。
对于标签的成对数据就是声音和图像成对的数据,这个并没有很难搜集,因为可以爬到大量的影片,影片里面有图像有画面也有声音,并且每一帧是一一对应的,所以可以用这样的数据来训练。
另外条件型 GAN 还可以产生会动的图片,如下图:
给GAN 一张蒙娜丽莎的画像,然后就可以让蒙娜丽莎开始讲话等等。
4.Cycle GAN(循环对抗生成网络)
到目前为止呢,我们介绍的几乎都是监督学习,即我们要训练一个网络,其输入是 x,输出为 y,并且我们需要成对的数据才有办法训练网络。
所以这一小节要介绍一个 GAN 的另一个有趣的应用,就是把 GAN 用在无监督学习上。
但是我们可能会遇到一个状况是,我们有一系列的输入和输出,但是 x 和 y 之间并没有成对的关系 (即没有成对的数据)
图像风格迁移,如下图:
有一系列真实的照片,然后有一些动漫的头像,我们希望可以把真实的照片转换成动漫的头像。
在这个例子里面就没有任何的成对的数据 ,因为有一堆真人的照片,但是我们没有这些真人的动漫头像。除非我们将动漫的头像先自己画出来,我们才有办法训练网络,不过这个做法成本太高了
对于图像风格转换,我们可能一点成对的数据都没有。那么没有办法训练一个网络输入一个 x 产生一个 y 呢?
下图是之前non-conditional generate(无条件生成) 的时候所使用的Generator架构,输入是一个高斯的分布,输出可能是一个复杂的分布。
让我们稍微转变一下思路,将输入视为x域中的图像分布,而y域则是图像的目标分布。
我们可以完全借鉴传统的生成对抗网络(GAN)的概念,即在传统的GAN中,从高斯分布中采样一个向量并输入到Generator中。如果之前输入的是x域的分布,我们只需调整为从x域中采样即可。
实际上,我们并不一定要从高斯分布中采样,只要存在一个分布,我们就可以从该分布中采样一个向量并输入到Generator中 。我们选择高斯分布的原因仅仅是因为我们了解其公式。
这个采样过程可以类比为从真实的人脸图像库中随机选取一张图片,然后将这张图片输入到Generator中,让它生成另一张图片(即分布)。
此时,我们的Discriminator需要进行一些调整,Discriminator不再仅仅输入y域的图片,而是同时输入x域的图片和y域的图片,然后输出一个数值,这个数值表示这两张图片是否为一对匹配的图像。
这个过程在表面上与之前的生成对抗网络(GAN)相似,但如果我们深入思考,仅仅沿用传统的GAN训练方法可能是不够好的。
因为我们的目标是让Generator产生一张与输入有关的y域图像。
然而,目前我们并没有对Generator的input与output之间的关系添加任何限制。
这可能导致Generator将输入图像视为高斯分布的噪声,而忽视输入内容,只要Discriminator认为其生成的图像足够好即可(即图片是个动漫人物就好了,与输入的图片的信息无关)。
因此,这样训练出来的Generator可能产生的人物头像与输入的真实照片之间并没有特别的关系,这并不是我们所期望的结果。
那怎么解决这个问题呢?怎么强化输入与输出的关系呢?
我们在介绍条件型 GAN 的时候,提到假设判别器只看 y,那它可能会无视生成器的输入,所以产生出来的结果不是我们要的。
所以要让判别器看 x 和 y,这样才可以让生成器学到 x 和 y 之间的关系。
但是目前如果我们要从没有样本对的数据中学习,我们也没有办法直接套用条件型 GAN 的想法 ,因为在条件型 GAN 里面我们是有成对的数据的,可以用这些成对的数据来训练的判别器。
但目前我们没有成对的数据来告诉判别器,怎么样的 x 和 y 的组合才是对的。
为了解决这个问题,我们可以使用循环生成对抗网络(Cycle GAN)。
Cycle GAN ,会训练两个Generator
- 第一个Generator是把 x 域的图变成 y 域的图,第二个生成器它的工作是看到一张 y 域的图,把它还原回 x 域的图。
- 第二个Generator是把 y 域的图变成 x 域的图。在训练的时候,我们会增加一个额外的目标,就是我们希望输入一张图片,其从 x 域转成 y 域以后,要从 y 域转回原来一模一样的 x 域的图片。
就这样经过两次转换以后,输入跟输出要越接近越好,或者说两张图片对应的两个向量之间的距离越接近越好。
因为这边有一个循环,从 x 到 y 再从 y 回到 x,所以它是一个循环,所以被称为 Cycle GAN。
因为输入经过两次转换以后变成输出,并且需要保证输入跟输出越接近越好,所以这个过程也被称为 Cycle GAN 的一致性。
所以在 Cycle GAN 中我们有三个网络,如下图所示:
1.第一个Generator的工作是把 x 转成 y;
2.第二个Generator的工作是要把 y 还原回原来的 x;
3.另一个Discriminator的工作仍然是要看第一个生成器的输出像不像是 y 域的图;
所以加入了第二个Generator以后,对于前面这个第一个的Generator来说,它就不能够随便产生与输入没有关系的人脸了。
因为如果它产生出来的人脸跟输入的人脸没有关系,那第二个生成器就无法把它还原回原来的 x 域的图片。所以对第一个Generator来说,为了要让第二个Generator能够成功还原原来的图片,它产生出来的图片就不能跟输入差太多,然后第二个Generator才能够还原回原来的输入。
1.另一个值得考虑的问题是,我们希望确保第一个Generator的输出与输入之间存在一定的关联,但我们如何知道这种关联正是我们所需要的呢?
2.机器是否有可能学习到一些奇怪的转换,同时仍然满足循环一致性的要求?
以一个极端的例子:
如果第一个Generator学到的只是将图片左右翻转,那么只要第二个Generator也学会将图片左右翻转,就可以还原原始图片。在这种情况下,第一个Generator学到的内容与输入图片之间没有任何实际联系,但第二个Generator仍然能够将图片还原到原始状态。
因此,如果我们采用循环生成对抗网络(CycleGAN)并依赖循环一致性,似乎无法保证输入和输出的人脸看起来相似,因为机器可能会学习到一些奇怪的转换,只要第二个Generator能够将其转换回来即可。
但在实际使用CycleGAN时,这种情况并不容易出现。
输入和输出往往真的会看起来非常相似,甚至在实际应用中,即使没有第二个Generator,不使用CycleGAN,而是使用普通的GAN来替代这种图片风格转换任务,效果通常也非常好。
这是因为网络本身非常"懒惰"
在输入一张图片时,它往往倾向于输出与输入非常相似的默认图像,而不太愿意对输入的图片进行过于复杂的转换。因此,在实际应用中,CycleGAN的效果往往非常好,输入和输出通常看起来非常相似,可能只是风格上有所变化。
补充:Cycle GAN 可以是双向的
如图所示:
有一个Generator
输入 y 域的图片
输出 x 域的图片
先把 x 域的图片转成 y,在把 y 转回 x
然而!!在训练 cycle GAN的时候,其实可以同时做另外一个方向的训练
(即把橙色的生成器给它 y 域的图片,让它产生 x 域的图片,然后在让蓝色的生成器把 x 域的图片还原回原来 y 域的图片。) 。
同时我们依然希望输入跟输出越接近越好,所以要训练一个 x 域的Discriminator,它是要看橙色生成器输出的图片像不像是真实人脸的图片 。
这个橙色的Generator它要去骗过这个 D~x~ Discriminator。这个合起来就是 Cycle GAN。
除了 Cycle GAN 以外,还有很多其他的可以做风格转换的 GAN,比如 Disco GAN、DualGAN 等等
如图所示:
这些 GAN 的架构都是类似的,一样的想法。
此外还有另外一个更进阶的可以做图像风格转换的版本,叫做 StarGAN 。
Cycle GAN 只能在两种风格间做转换,那StarGAN 厉害的地方是它可以在多种风格间做转换。
GAN 的应用不仅限于图像风格的转换,你也可以做文字风格的转换。
比如说,把一句负面的句子转成正面的句子,只是输入变成文字,输出也变成文字而已。
也就等于是输入一个序列,输出一个序列 ,这里可能会使用 Transformer 架构 来做这个文字风格转换的问题。
那具体怎么做文字的风格转换呢?
与 Cycle GAN 是一模一样的,如下图:
- 首先收集训练数据 ,收集一些负面的句子和一些正面的句子,可以从网络上直接爬虫
得到。 - 接下来就完全套用 Cycle GAN 的方法,假设我们是要负面的句子转正面的句子,Discriminator就要看现在Generator的输出像不像是真正的正面的句子。
- 然后我们还要有另外一个Generator要学会把正面的句子转回原来负面的句子,用 Cycle 的一致性,让负面的句子转成正面的以后还可以转回原来负面的句子。
注:两个句子的相似度也可以编码为向量来计算
其实像这种文字风格转换还有很多其他的应用
举例来说:
- 无监督文字风格的转换 ,让机器学会把长的文章变成简短的摘要。让它学会怎么精简的写作,让它学会把长的文章变成短的句子。
- 无监督的翻译 ,例如收集一堆英文的句子,同时收集一堆中文的句子,没有任何成对的数据,用Cycle GAN 硬做,机器就可以学会把中文翻成英文了。
- 无监督式的语音识别 ,也就是让机器听一些声音,然后学会把声音转成文字。这个也是可以用 Cycle GAN 来做的,只是输入变成声音,输出变成文字而已。
总结
临近期末需要处理的事情很多,所进度缓慢,希望期末过后能够加快进度。
在本周的学习中,首先了解了训练GAN的难点与技巧。GAN以其训练难度而闻名,主要挑战在于平衡Generator和Discriminator的训练。如果Discriminator太强,Generator难以产生逼真的图片;如果Generator太强,Discriminator无法区分真假。我们讨论了一些训练技巧,如从 Soumith、DCGAN、BigGAN 等研究中提取的技巧,以及如何使用序列到序列模型来生成文本。
然后还学习了GAN的性能评估方法。评估GAN的性能是一个挑战,因为生成的图像质量高度主观。我们探讨了从早期的人工评估到更客观的自动评估方法,如使用图像分类系统来评估生成图像的质量和多样性。此外,我们还介绍了Inception Score和Fréchet Inception Distance(FID)等评估指标,以及它们在评估生成图像时的局限性。
此外还了解了条件型生成(conditional generation)。条件型GAN允许我们根据给定的条件生成特定的图像。这种类型的GAN在文本到图像的生成、图像翻译(如Pix2pix)以及声音到图像的生成等领域有广泛应用。周报讨论了如何将条件变量整合到GAN中,以及如何训练Discriminator以确保生成的图像与给定条件相匹配。
最后还学习了Cycle GAN(循环对抗生成网络)。Cycle GAN是GAN在无监督学习中的应用,特别是在没有成对数据的情况下进行图像风格迁移。Cycle GAN通过训练两个Generator和一个Discriminator来实现这一目标。第一个Generator将输入域的图像转换为目标域的图像,而第二个Generator则执行相反的操作。我们讨论了Cycle GAN如何通过循环一致性来确保输入和输出之间的相似性,以及它在实际应用中的有效性。
通过本周的学习,我们对GAN的高级概念有了更深入的理解,包括如何克服训练中的挑战、如何评估GAN的性能、如何实现条件型生成,以及如何应用Cycle GAN进行无监督学习。这些知识为我们在机器学习和生成模型领域的进一步研究奠定了坚实的基础。尽管临近期末,我们的学习进度可能会放缓,但我们期待在期末结束后能够加快学习步伐。下周,我们计划继续深入学习这些主题,并探索更多相关的应用和技巧。
下一周计划继续学习新的机器学内容,临近期末,进度缓慢,望理解。