生成对抗网络-条件生成|深度学习(李宏毅)(二十五)

简介: 生成对抗网络-条件生成|深度学习(李宏毅)(二十五)

一、Text-to-Image


  1. 概述


对于原来的GAN来说,只能够输入一个随机的向量,然后得到一个产生的对象,但是我们无法控制产生什么样的对象,而我们期待用GAN来做到这件事,也就是条件生成(Conditional Generation)。以Text-to-Image任务来说,我们希望给Generator输入一段文字,然后让它来产生对应的图片:


K1W(YJNSWE)GQGI46V5JEZS.png

                         Conditional Generation


对于这样的一个任务,我们可以考虑用监督学习的方法来做,也就是给神经网络输入一段文字,来让其输出一张图片,并且要让图片与目标图片越接近越好,以此来达到条件生成的目的:


JE%8WNFNV{CFNE}C{S09IJ9.png

                                                  监督学习


然而这样的做法很可能不太好,试想在训练资料中有多张火车的图片,包括正面的火车和侧面的火车,而按照监督学习的方式,模型会希望在输出“train”时输出的图片要和所有的火车的图片尽可能地相似,那么生成的结果可能就是多张图片的平均,效果看起来可能是很模糊的:


GGML`6`{RF_C5U}F[YN7{)7.png

                                          problem


而使用Conditional GAN来完成这个任务就可以避免这个问题,对于Conditional GAN的Generator来说,要同时输入两个对象,一个是从先验分布中采样出来的样本}%76M`Q7UWCX6P(TU}[ZVHO.png,一个是当前的条件$AQQV5XX]YIP2T5BU8`}EQI.png,也就是一段文字,然后Generator输出生成的对象$]MG_FCZ_B0H8XC_ZWXJA90.png

M{LTQCNB8{NRYD]FD9Q8MYN.png

                                                      Generator


而对于Discriminator来说,如果它只根据输入的图片是否是真实的来打分显然是不够的,这样会造成Generator在学习的过程中逐渐忽略条件XO1832(5$YN4F0)`VEKX9UO.png,举例来说,如果Discriminator只关注图片是否真实那么Generator输入“train”时产生一张清晰的猫的图片也能从Discriminator处得到高分。因此,我们同样需要对Discriminator做一些改造,Conditional GAN中Discriminator要有两个输入,一个是条件XO1832(5$YN4F0)`VEKX9UO.png,另一个是图片GA4VI16DWBRNKT$@7XX)HLE.png,仍然输出一个标量代表得分,不过现在这个得分评估两件事,一个是图片GA4VI16DWBRNKT$@7XX)HLE.png是否真实,另一个是GA4VI16DWBRNKT$@7XX)HLE.pngXO1832(5$YN4F0)`VEKX9UO.png是否匹配:

5ZJ}2D{RI1{6S1UY8A67J~V.png

                                                   Discriminator


这样的Discriminator的训练样本也要有所变化,对于正样本,必须是正确的文字描述和对应的真实的图片,而负样本分两种,分别是文字描述配上不真实的图片和真实的图片随机匹配错误的文字描述:


@UHU2(HQ8PP5{LGNAUVXYEO.png

                                    训练样本

下图展示了用Conditional GAN做的二次元人物头像生成的效果:


E8RJ`C{%H`@MQ08{}57]JTL.png

                                                            效果


  1. 算法

UQ0@5L~OFEB}FHGVBAVRL8E.png

上面算法中的Step1和Step2也是交替迭代进行的。对于Generator也可以使用梯度上上来极大化48Z)YPOV0}NBZJ3`(O{HUC3.png这个目标函数。


  1. Discriminator的两种架构


在Conditional GAN的中Discriminator的架构一般比较常见的是下图中的模式,这里的条件XO1832(5$YN4F0)`VEKX9UO.pngGA4VI16DWBRNKT$@7XX)HLE.png对象都经过各自的一个network得到各自的embedding,然后将这两个embedding输入到另一个network中得到一个得分来衡量GA4VI16DWBRNKT$@7XX)HLE.png是否真实以及GA4VI16DWBRNKT$@7XX)HLE.pngXO1832(5$YN4F0)`VEKX9UO.png是否匹配:


N8J0]ZH)}QL89R0O}{(CVVF.png

                                                       常见的架构


另一种不太常见的架构如下图所示,这里的GA4VI16DWBRNKT$@7XX)HLE.png首先通过一个network,这个network输出两个东西,一个是衡量GA4VI16DWBRNKT$@7XX)HLE.png是否真实的得分,另一个则是GA4VI16DWBRNKT$@7XX)HLE.png的embedding,然后这个GA4VI16DWBRNKT$@7XX)HLE.png的embedding以及条件XO1832(5$YN4F0)`VEKX9UO.png要同时被输入到另一个network中,这个network输出一个得分来衡量GA4VI16DWBRNKT$@7XX)HLE.pngXO1832(5$YN4F0)`VEKX9UO.png是否匹配:

1NAC~`16)UHV}QK}5FY%7_6.png

                                            不常见的架构


这里的第二种架构的设计相对于第一种来说应该是更加合理的,对于第一种来说,如果Discriminator得出一个低分,那它无法知道为什么给一个低分,不知道是因为不够真实还是不够匹配,而第二种架构显然就可以明显地看出得分的分布。不过在文献中第一种架构是比较常见的,也没有实验来对比这两种架构设计,在实践中可以作为两种不同的方案以供选择。


  1. Stack GAN


在产生比较大的图片时,可能会需要Discriminator拥有更大的capacity,并且生成的效果也可能不会太好,Stack GAN是一种Conditional GAN,它的思路是先产生较小的图,然后再用小图去产生大图。它的架构图如下:


3UTKUL4RR2E2XOAQ16(@X5Q.png

                                               Stack GAN


感兴趣的话可以参照它的原论文:https://arxiv.org/abs/1612.03242


二、Image-to-Image


还可以使用Conditional GAN来做Image-to-Image的生成,比如将轮廓图转换成真实图,黑白图转换成彩图,白天转换成黑夜等:


0VE1$4)}PYF}MB_U[J614QE.png

                                           Image-to-Image


以将轮廓图转换成真实图片为例,如果采用监督学习的方法进行Image-to-Image的生成,做法也就是给神经网络输入一张图片,然后输出生成图片来让它和目标图片尽可能地接近:


]PDC0`ZD`A7I@23IFVTIN4L.png

                                                   监督学习


这样的做法很可能产生和前面Text-to-Image中监督学习方法同样的问题,也就是生成的图片是训练资料的平均,看起来很模糊:


ZTH[7_KY@2EUA[JDEXJ}@19.png

                                   监督学习


因此我们尝试用Conditional GAN的方法来完成这个任务,对于Generator来说会输入轮廓图和一个随机噪声}%76M`Q7UWCX6P(TU}[ZVHO.png,输出生成的真实的图片,然后Discriminator会关注Generator的输入和输出,也就是会给Discriminator输入轮廓图和生成图并对其真实度和匹配程度打分,该架构如下:


QO6([WP3%]LOR}M$9XB]FUK.png

                                            Conditional GAN


这样的做法其实也可能会遇到一些问题,比如在下图生成的图片中,虽然很清晰但是左上角多了个多余的烟囱,这可能是因为Discriminator会认为左上角加个烟囱好像也没什么不对:


2LH3`3M3XZ0UQ8A]WHNE~J9.png

                               Conditional GAN


我们可以尝试为生成的图片加一些约束来使得生成的图片更加地可控,具体的做法就是将监督学习的做法与Conditional GAN结合起来,也就是在训练Generator时不仅要让Discriminator的得分越高越好,也要让生成的图片与目标图片越接近越好:


_ZVW~CJKT@]X[}9@T5KJ6{H.png

                                          结合的方法  


这样的话就会产生比较好的效果:


VKH44`MFPD$%MURK$E}GZM5.png

                                  结合的方法


在Image-to-Image的论文里它的Discriminator有经过特别的设计,也就是每次并不是将整张图片输入到Discriminator中,而是只输入图片的一部分:


@BB56`F]1LN[4FW%8_I8J}K.png

                                           Patch GAN


Image-to-Image的原论文链接:https://arxiv.org/abs/1611.07004


三、Conditional GAN的其他应用


  1. Speech Enhancement


Conditional GAN也可以用来做语音的增强,也就是将有噪声的语音讯号转换成清晰的信号:


`SLUV`A9JAFSN5Q$Y05F8UY.png

                                 Speech Enhancement


对于传统的监督学习方法,训练数据是清晰的和加噪的声音讯号的pair,做法就是向神经网络中输入加噪的声音讯号,然后让输出的声音讯号与清晰的讯号越接近越好,另外要说的是,声音讯号跟图片差不多也是个矩阵,因此可以套用一些图像处理的方法:


5XB5{`EQAK_]EPL34`DN6X8.png

                                                  监督学习


而使用Conditional GAN和监督学习相结合的方法就是除了要让Discriminator得分越高越好还让Generator的输出和清晰的讯号尽可能地接近,这是为了避免模型只学习到去噪却会使得讯号的信息改变。而Discriminator会分辨Generator的输入和输出是不是匹配的,也会看Generator的输出是不是clean的:


$IWU5CKPF[N_$}[1X`28_U6.png

                                                      结合的方法


  1. Video Generation


使用Conditional GAN来做Video Generation的具体做法就是给Generator输入一段影片,然后让它产生接下来影片中要发生的事情,然后把原来的影片和产生的帧接起来输入到Discriminator中让它来区分最后一帧是不是真实的,同时也要让生成的帧与真实的下一帧越接近越好:


N_7%%B@57JWH1BAROVRKUG0.png


Video Generation


四、无监督条件生成


  1. 概述


前面介绍的Conditional GAN的方法全部都是有监督的方法,事实上也可以用GAN来做无监督的条件生成,也就是我们能够实现让一些数据从一个domain转换到另外一个domain,比如我们可以尝试让一张真实的图片转换成梵高画作的风格(风格转换),其实这样的任务也是无法收集到有标签的训练数据的:


_(SKYPH%H0)~4{UMMZMM2WH.png

                                              风格转换


另外这类无监督条件生成的例子也并非仅限于图像处理,在其他领域也可以应用得到,比如音频性别的转换、文本情感的转换等等:


9ZZK`~{2H}[C%]70LD$GY98.png

                                    其他领域应用


  1. 方法的分类


能够做到domain的转换的方法大体上可以分为两类:


  • Approach 1: Direct Transformation


这种方法的Generator的输入和输出没有办法差太多,只能够改变图片的颜色、质地、色调一类浅层的东西,对于将真实的图片转换成梵高画作的风格这样的风格转换的任务是比较适合的:


0JXVMM[WSP[@XV(1]W3BT}T.png

                                       Direct Transformation


  • Approach 2: Projection to Common Space


第二种方法适用于转换前后差距很大的任务,比如把真人的脸转换成动漫人物的脸,这样的任务不是改改颜色一类浅层的特征就可以办到的。这种方法会首先将输入通过一个Encoder变成一个特征向量,然后用这个特征向量解析得到一个转换后的图像:


GI[O9K9{]50RDWL{Y`T9Y%5.png

                                   Projection to Common Space


  1. 第一种方法


以风格转换的任务为例,现在我们期待要将真实的图片转换成梵高画作的风格,我们有的数据是没有标签的两个domain的大量图片:


6}XO}Z9T1YVBKCSX~C6JR_4.png

                              训练数据


虽然没有标注数据,但是我们可以通过Discriminator在两个domain之间建立联系,具体的做法是训练一个Discriminator来分辨输入的图片是否是梵高的画作,而Generator的训练目标就是让它输出的图片被Discriminator认为是梵高的画作:


B(V45HFX6@JP~5$`BZ_%CMV.png

                                                      架构


不过这么做可能会遇到一个问题,也就是由于Generator没有受到任何限制,所以可能会直接无视输入而产生一个与输入完全不同的图片来尝试骗过Discriminator


PUCD21D`4}GFU6TQ1}Q5@BL.png

                                                 issue


  • 采用浅层网络


为了解决上述问题,第一种方法就是采用较渐层的Generator,只要采用比较浅的Generator就可以直接无视这个问题,因为对于比较简单的Generator来说,它的输出不会对输入改变太多。然而如果Generator是深层的就有可能使输入受到很大的改变从而产生上述问题。


  • 采用两个Encoder


第二种解决方案就是让Generator的输入和输出都通过一个训练好的Encoder变成相应的code,在训练的时候要让这两个code尽可能地接近,这样就可以保证Generator不会让输入和输出相差太多:

T)ALB7WJI~RY513~A9QQJQ7.png

                                                Encoder


  • CycleGAN

CPJZU@)VQPYLN7UG@RRW2%I.png

                                        CycleGAN  


{2]1BYNA9P%ES04UKGG3PS2.png

                                                CycleGAN


总结一下,也就是说CycleGAN需要训练两个Generator和两个Discriminator,他们之间相互支持训练能够保证Generator的输入和输出不会千差万别并且风格也能得到转换。


CycleGAN论文链接:https://arxiv.org/abs/1703.10593


另外研究表明CycleGAN有一个有趣的现象,比如在下图中,两个Generator会将原图转换成中间风格的图然后再转回来,然而中间的图的房顶上没有黑点,但是经过N}V]4}@EMM[~5EK7QD1}}(I.png后又产生了黑点,这说明CycleGAN把原图中的信息隐藏起来了:


YAEV6EIOTA5)_13FZF2VK37.png

参考论文链接:https://arxiv.org/abs/1712.02950


  • StarGAN


刚才CycleGAN讨论的是两个domain互相转换的情况,而如果我们期待能够在多个domain之间都能互相转换,那我们就需要在两两个domain之间训练各自的Generator:


)CH2H255SXB{@NL`MYHKL_C.png

              cross-domain models


而StarGAN这种方法可以只训练一个Generator就完成多个domain之间的互相转换。在StarGAN中,它的Discriminator会输入一张真实的图片或者生成的图片,然后会判定这张图片是real的还是fake的,并且判断这张图片属于哪一个domain:


 WSCEIK)POM5C7M[$B2F]Z5R.png

        Discriminator


它的Generator会输入来自某个domain的原始的图片和想要转换到的domain,然后输出转换后的图片,得到的这张图片既要输入给Discriminator来尝试骗过他,也要与原始图片的domain标签结合在一起重新输入给同一个Generator,然后Generator输出的重构的图片要和原始图片尽可能地接近,这个其实类似上面的cycle consistency:


AOF5${`2C8{4W}([{@BQS]1.png

                                                Generator


StarGAN的domain的标签其实不是一个数字而是一个0-1向量,下图展示了对人脸特征的转换效果:


@2E%01`E[1RRCKI}3)V30TF.png

                                                 特征转换


下面是对人脸表情的转换效果:


R}KNZIGK8DZ(C6RR$ZFISUT.png

                                               表情转换


StarGAN论文链接:https://arxiv.org/abs/1711.09020


  1. 第二种方法


对于二次元人脸转换的问题,我们手里只有无监督的两个domain的数据:


1~]Y8})5`137FN[ES1C}X_1.png

                                                  数据


第二种方法是期望能够通过Encoder来提取两个domain的输入图片的特征并且投影成一个隐层向量,然后Decoder能够通过这个隐层的向量来生成一张某个domain的图片。通过这种方式,我们期望能够做到将真实的人脸通过真实图片的Encoder编码成向量,然后使用这个向量和二次元人脸的Decoder来生成转换后的图片:


[FOCLBXCLXV5]}5N~S1YT_Q.png

                                                 第二种方法


首先我们想到的做法是按照自编码器的方法分别训练两对Encoder和Decoder,同时也要为每个Decoder输出的图片训练一个Discriminator来鉴别是否属于这个domain:


K~[V_Q(}PI~_AU}0TNW941S.png

                                                  架构


事实上这种做法显然是有问题的,因为两个自编码器是单独训练的,他们的隐层向量的构建没有任何联系,很有可能隐层向量的每一维度对于两个domain来说表示完全不相同的特征,这可能造成真实人脸通过Encoder得到的隐层向量通过二次元人脸的Decoder后生成的图片跟原始图片完全不相干:


`F@)5G%Q(6LZ6FNN@5(8I(F.png

                                             问题  


我们有许多不同的方法来解决上述问题:


  • 共享参数


我们可以尝试将两个Encoder的最后几层以及Decoder的前几层的参数共享,通过这种方法我们就可以期待隐层向量的每一维度对于两个domain来说都表示相同的特征:


P4M[UUSREVJJN~LY1}V]70L.png

                                                 共享参数


对于Encoder来说,这种共享参数最极端的状况就是Encoder的参数是完全共享的,也就是只使用一个Encoder,不过这个Encoder也要输入一个flag来表明输入的图片来自哪一个domain。


  • Domain Discriminator


另一种方法就是加一个Domain Discriminator,这个Discriminator输入Encoder的隐层向量并且判断这个隐层向量来自哪一个domain,如果现在Encoder产生的隐层向量可以骗过Discriminator的话,那我们就可以期待隐层向量的每一维度对于两个domain来说都表示相同的特征:


A9UNGB`XMBP(VBFS2JGG2QW.png

                                         Domain Discriminator


  • Cycle Consistency


这里也可以应用Cycle Consistency的方法,具体也就是将原始图片输入Encoder后得到隐层向量,然后用二次元人脸的Decoder把这个向量解析成图片,然后这个图片再通过二次元人脸的Encoder得到隐层向量,这个隐层向量再通过真实人脸的Decoder解析成图片,然后使得这个图片与原始图片越接近越好:


%N%6SEPM$(O)BTNAR@HN@2D.png

                                     Cycle Consistency


这个技术用在ComboGAN里,论文链接:https://arxiv.org/abs/1712.06909


  • Semantic Consistency


Semantic Consistency的方法与Cycle Consistency不同的是,Cycle Consistency计算的是图片与图片像素级别的相似度,而Semantic Consistency计算的是两个Encoder获得的隐层向量之间的相似度:


_~Z94_2UUC(56FLQWD}~Q1L.png

                                         Semantic Consistency


这种方法的好处就是可以考虑Semantic上的相似度而不是Cycle Consistency只考虑表象上的相似度。


这个技术用在XGAN里,论文链接:https://arxiv.org/abs/1711.05139


  1. Voice Conversion


对于声音转换这个任务,在过去的方法中就是收集两个人的声音,让他们说一些一样的话然后按照监督学习的方法去实现:


_KKGD~Y6@_U[1KZX6(Y0[NL.png

                                                   过去的方法


而如果使用GAN的方法,就可以让两个人说不一样的话甚至不同的语言,然后用上述无监督的方法来完成这个任务:


~NIB$@(7SWIXG1~HWUVL(~R.png

                                                         GAN的方法


这方面的内容就不再赘述。

相关文章
|
3天前
|
机器学习/深度学习 数据挖掘 C语言
深度学习500问——Chapter04:经典网络解读(2)
深度学习500问——Chapter04:经典网络解读(2)
14 2
|
2天前
|
机器学习/深度学习 数据可视化 PyTorch
使用Python实现深度学习模型:生成对抗网络(GAN)
使用Python实现深度学习模型:生成对抗网络(GAN)
18 3
|
3天前
|
机器学习/深度学习
深度学习网络训练,Loss出现Nan的解决办法
深度学习网络训练,Loss出现Nan的解决办法
8 0
|
3天前
|
机器学习/深度学习 编解码 自然语言处理
深度学习500问——Chapter07:生成对抗网络(GAN)(3)
深度学习500问——Chapter07:生成对抗网络(GAN)(3)
12 0
|
3天前
|
机器学习/深度学习 JavaScript Linux
深度学习500问——Chapter07:生成对抗网络(GAN)(2)
深度学习500问——Chapter07:生成对抗网络(GAN)(2)
14 0
|
3天前
|
机器学习/深度学习 JavaScript 算法
深度学习500问——Chapter07:生成对抗网络(GAN)(1)
深度学习500问——Chapter07:生成对抗网络(GAN)(1)
20 3
|
3天前
|
机器学习/深度学习 算法 数据挖掘
深度学习500问——Chapter05: 卷积神经网络(CNN)(4)
深度学习500问——Chapter05: 卷积神经网络(CNN)(4)
8 1
|
3天前
|
机器学习/深度学习 自然语言处理 计算机视觉
深度学习500问——Chapter05: 卷积神经网络(CNN)(3)
深度学习500问——Chapter05: 卷积神经网络(CNN)(3)
10 1
|
3天前
|
机器学习/深度学习 自然语言处理 计算机视觉
深度学习500问——Chapter05: 卷积神经网络(CNN)(2)
深度学习500问——Chapter05: 卷积神经网络(CNN)(2)
11 2
|
3天前
|
机器学习/深度学习 存储 自然语言处理
深度学习500问——Chapter05: 卷积神经网络(CNN)(1)
深度学习500问——Chapter05: 卷积神经网络(CNN)(1)
15 1

热门文章

最新文章