绿色健康小清新

耐得住寂寞,守得住繁华

李宏毅机器学习-39-GAN-04-Unsupervised Condition GAN

Unsupervised Condition GAN

之前讲的那篇CGAN都是有监督学习,那能不能无监督学习呢?当然可以啦,大多数情况我们很难弄到一个个对应匹配的数据,比如做图片风格转换,你很难弄到同一个图片的不同种风格,里面东西还是一模一样的,再比如,你很难把一个人的声音风格转换到另外一个人声音上,因为可能你说的是中文,另外一个人说英文,找不到一模一样的发音,所以我们需要研究无监督学习,只需要两堆数据,可将某种特征从一堆转到另一堆。

Unsupervised Conditional Generation

从文献上看有两大类的做法:

  1. 直接转:直接学习一个生成器,可以将domainX转换为domainY的东西(主要用于小改)
  2. 投影到公共空间:你先学习一个domain X的encoder,将特征抽出来;之后输入domain Y的decoder,将特征转换为想要的东西;(适用于输入与输出差距很大)

Direct Transformation(直接转)

我们要learn一个生成器,他可以将X domain的东西转换为 Y domain的东西;现在我们X domain的东西有一堆,Y domain的东西有一堆,但是合起来的pair没有。那生成器怎么知道给定X domain的东西输出Y domain的东西呢?

  • 这个时候就需要一个Y domain的判别器,这个判别器他看过很多Y domian的图片,所以给它一张image,他可以鉴别这个image是不是Y domian的image
  • 生成器要做的就是想办法去骗过判别器,这样就生成Y domain的东西
  • 但是还要注意生成器生成的东西要与输入有关

因此生成器不仅要骗过判别器,还要让输出的东西与输入有关

如何做到输出与输入有关呢?

利用判别网络

这种方法利用一个判别器,判断生成器输出的图片属于 x domain 或者 y domain,从而训练 生成器使得其输出的图片尽可能贴近于 y domain。

但这样的问题是生成器可能输出和输入不相关的图像。

有很多种方法可以解决这个问题,最简单粗暴的方法就是直接无视,因为直接转换下,生成器的深度不足以产生和输入图像相差过大的输出结果。也就是说如果你的生成器网络很浅,输入和输出会特别像,这时候就不需要额外的处理;如果你的生成器网络很深,输入和输出会真的很不一样,这时候就需要额外的处理;

利用预训练网络

用一个已训练好的网络,如VGG;把生成器的输入和输出image,统统丢给这个pre-train好的网络,就会输出两个embedding vector;接下来在训练的时候,一方面生成器要骗过判别器,同时希望两个embedding的vector不要差太多。

Cycle GAN

  • 如果你想train一个X domain到Y domain的生成器,你需要同时train一个Y domain到X domain的生成器;第一个生成器用于将风景画变成复古画,第二个用于将复古画还原为原来一模一样的图;然后目标是两次转换以后的图越接近越好。(这个路径叫做cycle consistency)
  • 同时训练Y domain的判别器;
  • 重复上面的X domain转换为Y domain;我们再训练一个Y domain到X domain同样的结构;

注意:cycle-GAN中存在的问题:cycle-GAN会把输入的东西藏起来,然后再output的时候再呈现出来;例子:输入和输出很像屋顶上都有黑点,但是中间image屋顶的黑点却没有。中间产物没有黑点,那你是怎么只通过中间层image得到有黑点的屋顶,一个解释是生成器有很大的能力将信息藏在中间image里面,如很小的数值让你看不出来。既然cycle-GAN是藏信息的,是不是失去了cycle-GAN的意义了呢?因为就是这种结构就是为了让第一个生成器的输出和输入不要差太多,但是你现在这种结构是藏信息的,会不会中间层就会和输出差距很大。这种结果,机器可能自己会学习隐藏东西,结构失去了意义…

下面看Cycle GAN的实例:

👉 https://github.com/Aixile/chainer-cyclegan

全部转为白毛:

其它

除了 cycle GAN外,还有其他类似的方法,如Disco GAN、Dual GAN 等,它们和 Cycle GAN 都比较相似。

starGAN(多domain间的转化)

还有一种叫做star-GAN,用于多个domain之间的转换

理论上如果是4个domain之间的互转,你应该学12个生成器;而star-GAN是只学习了一个生成器就可以在多个domain之间互转;

具体怎么做的呢?

  • 在star-GAN中,要学习一个判别器,这个判别器要做两件事:首先对于一张image,它要鉴别它的真假;还要判断这个image来自于哪一个domain;
  • 只需要学习一个生成器,它的输入是一张image,以及目标domain;就生成出目标domain的image;
  • 然后再将生成的图片丢给同一个生成器,输入是原始图片的domian以及这张image然后通过这个生成器重建出新的image,希望input的image和重建的image越接近越好。
  • 然后判别器要做两件事:首先对于一张image,它要鉴别它的真假;还要判断这个image来是不是我们要的目标domain;

下面是实际的例子: 判别器做的事是首先判断它是real的还是fake;然后还有判断它是不是目标的domain;domain的表示是很多属性编码的,目标domain中:第一个10011黑色头发男性年轻、00000表示没有情绪、10表示只表示前面没有情绪;原始domian中:00101表示棕色女性年轻,00000表示没有情绪,10表示不显示情绪;

  • 首先让生成器将棕色女和目标domain转成黑色男,然后黑色男和原始domain通过同样的生成器转换为棕色女然后你希望输入和输出的棕色女越接近越好;(cycle consistency的loss)
  • 接下来你要确保输出的黑色男image是real的并且是和目标domain是一样的

下面同样的原理用于情绪:


Projection to Common Space(投影到公共空间)

我们想要做到:
真人图片丢到ENxEN_x,可以抽出真人的特征到latent vector(橙色),然后经过二次元的DEyDE_y得到对应的二次元图片
二次元图片丢到ENyEN_y,可以抽出二次元的特征到latent vector(橙色),然后经过真人的DExDE_x得到对应的二次元图片

一般的结构为,分别训练两个编码器以编码实际图片和风格图片,再训练两个解码器以解码实际图片和风格图片,最终即可得到一条路径,可以将实际图片转换为风格图片。

由于两个auto-encoder是分开train的,所以两者之间是没有关联的;例如当你丢个X domain的人脸进去,变成一个vector,当输如Y domain的encoder中时,可能出现一个截然不同的卡通人物。因为是分开训练的,所以在latent space中每个维度的表示属性是不一样的,如上面的auto-encoder用第一维代表性别,而下面一组则用其他代表性别;

怎么解决关联?

共享参数

让不同domain的decoder的最后几个hidden layer和encoder的最前面几个hidden layer的参数是共用的;通过共享参数,可能会是不同domain的image压缩到同一个latent space(潜在的空间),即同样的dimension 表示同样的属性。这样的技术被用在couple GAN 和UNIT里面。

极端的现象,公用同一个encoder和decoder,只不过在输入的时候给定1表示domain X的图片 -1表示Y domain的图片。

增加判别网络

原来X domain和Y domain都是自己搞自己的东西,现在,用一个domain 判别器来判断这个vector是来自于X domain的image还是来自于Y domain的image。两个encoder的作用是骗过这个domain 判别器。当无法判断的时候,就是说明两者被encode到同一个空间

Combo GAN(Cycle Consistency)

将一张image经过X encoder变成code;再经过Y docoder把它解回来;然后再丢给Y domain的encoder,再透过X domain的decoder把它解回来;然后希望input和output越接近越好。

Combo GAN(semantic consistency)

与之相似的,还有使用 semantic consistency 的方法。它让原始图像通过 ENX 输出 code,再让这个 code 通过 DEY 和 ENY 生成另一个 code,最后将两个 code 进行比较,使得其越接近越好。这种技术常用在 DTN 和 SGAN 里面。

这也就是在latent space看consistency!!!

例子

👉 https://github.com/Hi-king/kawaii_creator


Voice Conversion(声音转换)

声音转换,大家对这一项技术的起源应该都是柯南了,柯南拿着变声器然后发出毛利小五郎的声音。

声音转换注意两点,声音转换的输入端长度与输出段长度不一定是一致相等的,甚至在很多时候不相等更加好能会更好。第二点,声音转换都是基于图像形式的音频特征进行转换,也就是我们先将音频转化成为图像,然后对图像在进行端到端训练,所以我们输出的结果也是图像。 所以需要用Vocode的方式将输出的图像还原成为声音。

Vocode传统方法就是Griffin-Lim algorithm,深度学习的方法这里主要介绍WaveNet.

声音转换的方法,我们根据数据的分布可以分为2大类,一类是Parallel Data,另一类是Unparallel Data。 对于parallel data很直觉的做法就是端到端训练一个模型在进行测试。但是他会面对数据集难收集的问题。所以在实作中Unparallel Data是我们面临的比较多的。

面对不平衡音频数据,进行处理的方法可以分为2类。第一类是特征分离(Feature Disentangle),第二类是直接转换( Direct Transformation)。特征分离很好理解就是我们要将声音进转化,我们将音频的特征先进行分离一种只保留语者说话腔调的讯息,一种只保留声音的语义的信息,然后我们如果要将A的声音转化成为B的声音我们只要把A的腔调改为B的腔调语义部分进保留。(当然也可以进行情绪的转化)最后通过解码器输出结果。

过去,用的监督学习的方法,要有一堆对应的声音:

然后训练一个seq2seq的模型就可以了,但是这个模型是有缺陷的,例如我想要变声为张学友,那很难请到张学友跟我一起念同样的句子,然后来训练,很麻烦。那如果我想要变声为尼古拉斯凯奇,那就很难搞了,因为他不会中文,就算请到他也讲不来相同的句子。

如今,我们只要收集两组声音,不用讲一样的内容就可以进行训练。

具体的效果,老师的ppt里有,可以自行查看

-------------本文结束感谢您的阅读-------------
六经蕴籍胸中久,一剑十年磨在手

欢迎关注我的其它发布渠道