• 通俗易懂生成对抗网络GAN原理


    生成对抗网络(Generative Adversarial Network, GAN

    学习李宏毅机器学习课程总结。

    前言

    生成式网络有什么特别的地方呢?
    之前我们学到的神经网络就是一个函数,输入一个向量x(序列,图片,文本…),输出一个y(数值,类别,序列…)现在特别的地方就是,不仅输入x,还得输入一个随机变量z,z是从某一个分布中取样出来的,所以每次取样出来的z都是随机的。但要求这个z的分布够简单,就是你知道它的概率分布的公式是什么,比如高斯分布。

    为什么输入要额外有个z呢?
    随着你每次输入的z不同,这时候网络的输出就不再是一个单一的固定的东西,而是变成一个复杂的分布,这种能够输出一个复杂分布的网络,就叫做生成器generater。

    那网络Network怎么同时处理x和z呢?
    有很多不同做法,就看你怎么设计Network,比如可以把x和z向量接起来,变成一个比较长的向量输入;再比如你的x和z的长度正好一样,把他们相加起来当作输入。
    在这里插入图片描述

    常见的生成式模型:
    VAE, Flow-based model,GAN…
    (目前GAN的效果最好)

    概述

    1. 为什么要训练一个生成器generater?

    输入x,输出y,这样固定的输入输出不好吗?为什么要输出一个分布?
    下面看一个例子:
    预测小精灵游戏接下来的游戏画面什么样,知道过去的游戏画面的视频,比如知道前三帧图片,预测第四帧的画面。
    那怎么输出这张图片?一张图片可以看作是一个很长的向量,把这个向量整理成图片后,与目标图片越接近越好。

    在这里插入图片描述
    用监督式学习的方法来训练的话,会有什么问题?
    就是在分岔路口,小精灵会分裂成两个,一个向左一个向右转,为什么会这样呢?因为我们的训练集数据中,向左向右的图片都有,机器学的是,他要有个输出,满足同时距离向左转和向右转最近,所以机器只能同时向左向右,就导致了错误。
    在这里插入图片描述

    那怎么解决上面这个问题呢?
    就是让机器不是输出一个固定的值,而是输出是有机率的,即输出一个分布。这样就可以解决这个世界很多不可预测的东西。
    这样的话,比如机器就会学到,z=0,向左转的概率大,z=1向右转概率大。
    在这里插入图片描述

    什么任务我们需要用到这样的生成器网络呢?
    当任务需要创造力的时候。
    当同样的输入会有不同种可能的输出,这些输出都是对的。

    例子1:画一个红眼睛的人
    在这里插入图片描述
    例子2:聊天机器人
    在这里插入图片描述

    2. GAN的简要介绍

    GAN的种类:

    在这里插入图片描述

    GAN简介

    首先看一个简单例子,用GAN生成一个二次元图像。
    这里用到的是:
    非条件GAN,Unconditional generation

    假设图片大小64✖64,要输出64✖64✖3这么长的高维向量,输入的z是从正太分布中采样的一个低维向量,比如50或100维自己定的。
    为什么z是正态分布?也可以是别的,只要是个简单分布就行,生成器会把它变成一个复杂的分布。

    生成器(Generator, G):
    在这里插入图片描述

    判别器(Discriminitor, D):

    在这里插入图片描述
    生成器和判别器都是个架构,至于用什么模型,如CNN还是trasformer,根据自己任务自己决定。

    GAN的基本思想:
    博弈,对抗(adversarial)。
    枯叶蝶(生成器)防止被吃掉,不断进化;比比鸟(判别器)为了生存,要抓蝴蝶吃,不断进化。
    在这里插入图片描述
    那怎么让生成器学习画出二次元人物呢?
    第一代的生成器G,参数很随机就,画出来的就是很杂很模糊的图,第一代的判别器D判断是不是真实的二次元,可能就根据有没有眼睛判断;第二代G就产生眼睛出来,骗过第一代D,但第二代D会继续试图找差异,看有没头发嘴巴;第三代G又进化,加上了头发嘴巴…
    在这里插入图片描述
    G和D可以看作亦敌亦友的合作关系。写作敌人,念作朋友。

    GAN的训练

    G和D就是两个神经网络。
    训练前,先初始化参数。
    在这里插入图片描述
    第一步:
    固定G,更新D。网络上爬一些二次元人物图片作为Database,随机从高斯分布的数据中取样一些数据输入G,出来很模糊的图片。

    在这里插入图片描述

    把G输出结果和真正的二次元图片输入给D,让D判断。D做分类,真实的输出1,生成的输出0。若看作回归问题,就让D做预测,预测是1还是0,都可以。

    在这里插入图片描述
    第二步:
    固定D,训练G。调整G的参数,让D打分的值越高越好。越高分意味着输出的图片越来越真实。

    在这里插入图片描述
    具体操作其实是这样,把G和D直接连接起来,看成一个大网络,其中的一个隐层的输出很大(等于图片的像素点数),也就是原来的输出图片。但不调后面D的几层,只调前面。可以用梯度下降等。

    在这里插入图片描述

    第三步:
    反复训练G和D。

    在这里插入图片描述

    注:当我们不断调整G的内插值,比如最后一行,随着值的增大,机器学到让严肃变微笑,男人变女人;倒数第二行,机器学到左右转向等等。

    在这里插入图片描述

    然,机器也会产生一些不知道的东西,如网球和狗。

    在这里插入图片描述

    GAN的理论

    训练目标

    对于生成式模型,我们的训练目标是什么?
    在训判别式模型时,我们是定义一个损失函数,然后梯度下降去最小这个损失函数就可以了,那生成式模型中呢?我们希望找一个G,这个G输出的分布PG与目标分布Pdata越接近越好。那用什么度量分布函数相似度,用散度Divergence,让散度最小。

    在这里插入图片描述

    找一个G,本质就是找一组G里的参数,一大堆weight和bias,让分布PG与目标分布Pdata的散度越小越好。L就是损失函数。
    在这里插入图片描述
    那怎么计算这个散度呢?
    我们知道一些常见的散度,如KL散度,JS散度等,这种散度用在这些连续分布上面,实做上很复杂很复杂的积分如何计算?这个就是G要解决的问题。
    在这里插入图片描述
    虽然不知道PG与Pdata具体概率分布,但只要能从PG与目标分布Pdata中采样数据出来,生成器G就有办法最小化他们的散度。
    在这里插入图片描述
    最小化散度还要靠判别器D:
    D看到来自Pdata(蓝星)的数据,就打高分;来自PG(黄星)的数据,就打低分。分辨真的图和生成的图。

    在这里插入图片描述
    也可以当作优化问题:
    在这里插入图片描述
    D的目标函数:
    如果y是从Pdata采样出来的,则期望越大越好;如果y是从PG采样出来的,则期望越小越好。
    找一个D,能让V函数最大
    在这里插入图片描述
    当然,目标函数也可以有其他写法,但最早年写成这个样子,是有个明确的理由:是为了把D和分类扯上关系。等同于训练一个二元分类器。
    在这里插入图片描述
    早期人们只是按分类器的思想设计D,神奇的是,最大化V(D, G)通过一系列推导,发现和JS散度有关联。
    详细推导看:paper

    在这里插入图片描述
    原始目标就是最小化散度,但难在不知道这个散度如何计算。但是,当我们知道最大化V(D, G)和JS散度是有关联的,那么,最小散度Div(PG, Pdata)就相当于最大V(D, G),那是不是就可以替换呢?
    在这里插入图片描述
    替换后,得到:
    在这里插入图片描述

    这个式子就可以根据如下算法求解

    在这里插入图片描述

    为什么是和JS散度相关?而不是别的散度?
    当然也可以是别的散度,不同的散度只要对应不同的目标函数就可以。这篇文章有详细说明:散度paper
    在这里插入图片描述
    在这里插入图片描述

    但是,GAN很不好train…

    训练技巧

    GAN的训练小技巧,有很多,我们挑一个最知名的WGAN

    首先考虑一下,用JS散度有什么问题吗?

    PG和Pdata最主要的特性是什么?PG和Pdata重叠的部分非常少。
    理由1:数据的本身的属性。图片是高维空间的一个点,是高维空间里低维空间的manifold(一个簇,流行)。比如在高维空间随便采样一个点,它通常都不是二次元人物,所以高维空间中二次元人物图的分布是非常狭窄的,非常小的范围。
    以二维空间为例,PG和Pdata可以看作两条线,除非刚好重合,不然它们重合的部分很少,可以忽略不计。

    在这里插入图片描述

    理由2:采样。哪怕就假设PG和Pdata有重叠,但如果采样的点不够多,对D来说,他仍可以完全分开。

    在这里插入图片描述

    PG和Pdata重叠的部分非常少,和JS散度有什么关系?
    如果两个分布不重叠,它们的JS散度就等于log2。即使两个分布很接近,也是log2,所以无法度量两个分布的相距程度。

    比如下图第2种情况明明比第一种好,分布更接近,但JS度量出来都是log2。所以用二分类D准确率很容易是100%,这是没有意义的,因为不知道什么时候G越来越好,无法提升G。

    在这里插入图片描述

    那JS散度在GAN种的问题,怎么解决?
    有人提出Wassertein distance。

    如下图,有两个分布P和Q,想让P的分布变成Q的一样。
    在这里插入图片描述

    有无穷多种方法,但是有个用的平均距离最小的方法。选最短的距离作为Wassertein distance(W)。
    在这里插入图片描述

    那么随着PG和Pdata越来越接近,W的值会越来越小,d1 在这里插入图片描述

    Wassertein distance的计算:
    在这里插入图片描述

    最关键的一点:其中D必须是个足够平滑的函数,不能是变动很剧烈的函数。
    为什么呢?没有这个约束,real的值就会正无穷,generated的值就会负无穷,这条红色曲线就完全把左右分类,这又和JS散度的问题一样了,当保证红线必须平滑,就不会出现这种极端情况。
    在这里插入图片描述

    怎么实现 D必须是个足够平滑的函数 这个约束?
    举例如下三篇论文的方法。

    在这里插入图片描述

    虽然有了WGAN,但GAN仍然很难train,因为只要G或D其中一个没训好,另一个也会失败。G和D互动的过程是自动的,希望D的loss一直在下降,如果没有下降,就说明训练失败了。

    网上还有很多训练GAN的技巧Tips:
    在这里插入图片描述

    GAN在序列生成上的应用

    训GAN最难的,就是让GAN生成一段文字。
    因为无法做梯度下降(某个参数变化的时候,对目标造成了多大的影响),因为无法微分,当Decoder参数有一点变化的时候,输出的分布改变一点,但对分数最大的max token没有影响,所以对D的输出没有改变。

    在这里插入图片描述

    怎么办?
    可以用强化学习(Reinforce learning, RL)强制训练,但RL也很难训,GAN也难训,难到一块了,非常难训。
    很长一段时间没人能解决。

    GAN的评估

    早年的时候,就是用人眼看,看生成的数据怎么样。
    但成本很高,且太主观。

    客观评价:
    把结果输入一个图片分类器。
    在这里插入图片描述
    这种评估方法存在什么问题?
    生成资料的多样性问题。

    • Model Collapse问题。模型崩塌。
      生成的总是那几张图片,如下图右面,生成的同一张脸越来越多。
      在这里插入图片描述

    • Model Dropping问题。
      生成的资料多样性貌似也够,但可能只是真实资料多样性的一部分。这种很难侦测到。
      看着人脸种类挺多,但不同迭代次时,人脸还是类似,只是肤色变了。

    在这里插入图片描述

    那怎么评判G产生图片的多样性够不够?
    比如生成1000张图片,输入多个分类器,求分类平均值。

    如果平均后的分布非常集中,说明很多图片之间都挺像的,说明多样性不够。
    在这里插入图片描述

    但如果平均后的分布也很平均很平坦,说明每种类型都涉及了,多样性够了。
    在这里插入图片描述

    有个常用的分数Inceptioan Score(IS):
    输出图片质量越好,多样性多,IS值就大。

    但有时候不适合IS,比如生成二元人脸,都是人脸,多样性算出来其实是小的。

    还有个评估参数FID:
    拿进入softmax之前的向量,最后一层隐藏层的输出。假设它们是高斯分布,计算其相似性FID,越小越好。
    在这里插入图片描述
    但假设是高斯分布也是有问题的。所以要结合FID和生成图像一起看效果。

    但还有一种情况,生成的图片和训练资料里的一模一样。
    这时候就很难侦测。
    在这里插入图片描述
    当然你说可以计算图片相似度,但要是只是学了把脸转向了一下,看着还以为生成的新图片,其实不是,相似度也测不出来。
    在这里插入图片描述

    还有很多评估的方法:
    在这里插入图片描述

    条件GAN(Conditional Generation)

    上面的学习关注点都是从一个简单的分布如高斯中随机sample数据输入,现在重点考虑如何操控输入的x。

    条件GAN有什么应用?
    如文字对图片,这是一个监督学习,输入文字描述,输出图片。

    在这里插入图片描述
    输入红头发,绿眼睛,就会生成想要的图片。
    在这里插入图片描述

    怎么给G输入一段文字呢?
    有很多方法,比如你可以用RNN读一段文字,得到输出的向量丢到G里去;要么用transformer的encoder,把输出的向量平均起来输给G。

    基本理论

    按GAN之前的理论,D不需要管G输入什么,反正它的任务就是看图片真不真实,而G的目标是骗过D就行,G只要生成的图片不模糊真实就行,这样导致G也懒得去看输入x,显然这并不是我们想要的。

    在这里插入图片描述

    所以条件GAN要有点改进:
    让x和G的输出y,同时输入给D,让它判断y真不真实,并且还要判断y和x匹不匹配。

    在这里插入图片描述

    注意:训练集还得放些x和y不匹配的数据,即放真实的图片,但文字压根和图片无关。

    在这里插入图片描述

    其他应用

    应用一:
    输入图片,输出图片。这类任务叫作Imagine Translation任务,或pix2pix。

    如输入房屋设计图,产生出完整的房屋图片。
    在这里插入图片描述

    输入轮廓,输出真实。
    在这里插入图片描述

    输入黑白图片,让它上色。
    在这里插入图片描述
    输入素描图,输出实物图。
    在这里插入图片描述

    输入白天或起雾的图片,产生真实的图片。

    在这里插入图片描述

    那这种任务具体怎么做呢?
    输入x就是图片。
    在这里插入图片描述

    这种任务可以用监督式学习,但有文献说这种方式效果不好,如下图,很模糊,可能是因为同样的输入,对应很多不同可能的输出,所以机器会把他平均起来,得到的结果就比较模糊。
    在这里插入图片描述

    如果用GAN去训的话,下面左图,可以看到GAN的想象力太丰富了,自己创造了一张图;但我们想要的是和目标图片越像越好,那就可以GAN+监督式学习,进行联合训练,得到如下右图。
    在这里插入图片描述

    联合训练流程图:
    在这里插入图片描述

    应用二:
    输入一段声音,如狗叫声,输出一张狗的图片。
    在这里插入图片描述

    首先 ,需要声音和图片成对的资料,可以从视频里面爬,视频里有图片,有声音信号,每一帧的画面对应一小段的声音。
    在这里插入图片描述

    为了避免机器没有真正学到东西,只是把训练资料的数据拿出来,所以把声音调大,看图片是否变化。
    在这里插入图片描述
    应用三:
    产生会动的图片Talking Head Generation。
    之前抖音上比较火的,上传一张人脸照片,会让脸动起来。

    GAN从非平行数据中学习

    learning from unpaired data
    GAN 用在非监督学习上。如风格迁移。

    有一堆数据x域,一堆数据y域,但x和y是不成对的。比如风格迁移,把真人头像转成二次元头像。在完全没有成对资料额情况下,机器该怎么学习?

    在这里插入图片描述
    如果只套用一般的GAN模型,把原来从高斯分布采样的数据换成采样真实人像图片就可以了,但这样有什么问题吗?

    在这里插入图片描述
    G发现只要随便生成一张二次元图像就可以骗过D,所以同一个输入测试几次的输出不同,因为G完全不管你输入是什么,没有条件约束G必须学输入的特征,所以它输出的东西就和输入没什么关系。
    在这里插入图片描述
    这个问题是不是和条件GAN里的类似?那这里能否用条件GAN呢?
    不能,因为条件GAN里解决该问题是看输入和输出是否匹配,而这里全是非成对数据,没办法知道哪些匹配。

    那怎么解决呢?cyclegan。

    Cycle GAN

    如下图,输入,经过两个G,两次转换以后输出,希望输入和输出这两张图片越像越好(它们向量的距离越近越好,循环一致性)。这样对输入就有了限制,G就不能随便生成了。

    比如戴眼镜的人,它起码学到二次元人物也有眼镜。

    在这里插入图片描述

    但,会不会第一个G学到把眼睛变成痣,第二个G又把痣变回眼镜?或更极端情况,两个G都是学到把图片反转,这种情况怎么侦察?
    理论上是有这样的情况,但实做中,网络一般很懒,都是先学简单的东西,看到眼镜,它也会转成眼镜,不会专门转成别的像痣这么复杂的过程。

    把这个网络做成双向的,就叫做Cycle GAN。
    在这里插入图片描述

    还有很多其他的GAN,也能做风格迁移。在同一时间,很多团队提出了类似的想法,那这些GAN有什么区别呢?除了名字不同,原理都是一样。
    在这里插入图片描述

    StarGAN

    风格迁移更进阶的一种模型。CycleGAN只能在两种风格之间做转换,StarGAN厉害的地方在于它能在多种风格间转换。
    具体原理可以网上搜。
    在这里插入图片描述

    其他应用

    不仅能做图片间风格转换,还可以做文本间转换。

    文字风格转换。如正负面句子转换,也可以用Cycle GAN。seq2seq如可以用transformer模型。
    在这里插入图片描述

    搜集一堆正负面的句子,只是成对的资料没有。
    不是前面说文字输入D会有问题吗?用强化学习RL硬做。
    在这里插入图片描述

    文字风格转换的其他应用:

    • 长文章取摘要。
      在这里插入图片描述

    • 非监督翻译。爬一堆英文文本,爬一堆中文文本,之间不成对不相关。Cycle GAN硬做。
      在这里插入图片描述

    • 非监督ASR。爬一堆声音,爬一堆文字,之间不成对。Cycle GAN硬做。
      在这里插入图片描述

  • 相关阅读:
    Android_Monkey_测试执行策略及标准
    2023.11.16 hivesql高阶函数之json
    基于微信小程序考研知识题库在线学习系统设计与实现-计算机毕业设计源码和lw文档
    Python实现Kmeans文本聚类
    如何看懂SparkUI?
    Java日期格式
    Springboot中认证和授权的实现(使用jwt)
    【c语言】100行代码搞定电子琴
    MySQL-3(9000字详解)
    【开源】SpringBoot框架开发房屋出售出租系统
  • 原文地址:https://blog.csdn.net/qq_36002089/article/details/126471233