无监督学习-自编码器-补充|深度学习(李宏毅)(二十)

一、最小重构代价之外的方法

  1. Using Discriminator

一个自编码器学习到的隐层向量对于原来的输入来说应该是具有代表性的,就好比三玖的耳机对于三玖来说就是具有代表性的,看到三玖的耳机不会想到一花一样:

example

评估隐层向量的代表性好不好就可以当做评估自编码器效果的指标。具体的方法就是训练一个Discriminator来评估隐层向量是不是具有代表性,在下面的例子中三玖的图片通过一个自编码器可以得到一个蓝色的向量,凉宫春日的图片通过一个自编码器可以得到一个黄色的向量:

example

然后我们可以训练一个Discriminator,其参数为 ϕ \phi ϕ,这个Discriminator可以是一个二分类器,输入一张图片和对应的自编码器的隐层向量,然后判断它们是否匹配:

Discriminator

Discriminator的训练资料中包含positive和negative的样本,一张图片和对应的隐层向量属于positive的训练样本,而将图片与其他图片的隐层向量任意组合得到的样本为negative的样本:

训练资料

然后使用这些资料来训练 ϕ \phi ϕ,损失函数可以选用二分类的交叉熵损失,记作 L D L_D LD,训练以后得到 L D ∗ = m i n ϕ    L D L_{D}^{*}=\underset{\phi }{min}\; L_{D} LD=ϕminLD。如果这个可以得到一个很小的 L D ∗ L_{D}^{*} LD,则说明自编码器的效果较好,训练出来的隐层表示具备一定的代表性,而如果无法得到一个很小的 L D ∗ L_{D}^{*} LD,则说明自编码器学习到的向量表示没有代表性,自编码器的效果不是很好。

我们希望能够训练得到一个好的Encoder(假设它的参数是 θ \theta θ),它能够使得Discriminator的 L D ∗ L_{D}^{*} LD能够越小越好,也就是说:

θ ∗ = a r g    m i n θ    L D ∗ \theta ^{*}=arg\; \underset{\theta }{min}\; L_{D}^{*} θ=argθminLD

代入 L D ∗ = m i n ϕ    L D L_{D}^{*}=\underset{\phi }{min}\; L_{D} LD=ϕminLD可以得到:

θ ∗ = a r g    m i n θ    m i n ϕ    L D \theta ^{*}=arg\; \underset{\theta }{min}\; \underset{\phi }{min}\; L_{D} θ=argθminϕminLD

在实际操作中可以将Encoder和Discriminator一起进行训练,这样的做法类似于在general autoencoder中将Encoder和Decoder一起进行训练一样,事实上经典的自编码器可以看做训练Discriminator的方法的一个特例。

可以将自编码器的Decoder看做是Discriminator,这个Discriminator同样地输入一张图片和对应的Encoder的隐层向量,然后计算Decoder的输出与输入图片的重构代价来评估隐层向量是否具备代表性,这就类似上述Discriminator的做法,只是这里的Discriminator只会输入positive的训练资料,而没有negative的训练资料:

autoencoder

  1. Sequential Data

对于序列化的数据(比如句子),我们也希望能够通过自编码器得到它的表示,实际的做法包括下列方法。

  • Skip Thought

这种方法尝试将句子通过Encoder编码成向量,然后利用这个向量和Decoder来预测前一个和后一个句子。这种方法的思想类似于训练word embedding,类似词汇,两个句子的上下文如果一致,那么这两个句子的含义很可能也一样,同样地其embedding也应该相似:

Skip Thought

参考论文:https://arxiv.org/abs/1506.06726

  • Quick Thought

这种方法的思想是让一个句子和它的下一句的embedding要越接近越好,而和从语料库中采样出来的其他句子要越不相似越好。这种方法与Skip Thought相比不需要训练Decoder而只需要训练一个Encoder就好。

具体的做法是和Encoder同时训练一个分类器,输入当前句子、当前句子的下一句和随机采样的句子的embedding,然后分类预测下一句,而实际中的分类器也就是计算向量内积,这也就保证了一个句子与它的下一句的embedding相似,与随机采样的句子不相似:

Quick Thought

这种方法应该保证一定要有随机采样的句子参与,而不能只让当前句子和下一句的embedding越接近越好,这是因为这样会使所有句子学习到一个一样的embedding。

参考论文:https://arxiv.org/abs/1803.02893

  • Contrastive Predictive Coding

Contrastive Predictive Coding(CPC)是另一种方法,以语音讯号为例,这种方法是要训练一个序列的embedding,要求这个embedding能够预测后面的讯号通过Encoder后的embedding:

Contrastive Predictive Coding

参考论文:https://arxiv.org/abs/1807.03748

二、学习更具解释性表示的自编码器

  1. Feature Disentangle

无论是语音、文字还是图像资料,都是由多个部分的讯息组成的,举例来说,语音可能是由语者、内容等讯息组成的,文本可能是由文法、语义等讯息组成的,图像可能是由风格等讯息组成:

资料的组成

我们希望能做到的是使自编码器学习到的表示的不同维度能够表示不同类型的讯息,这项任务就叫做Feature Disentangle。

以语音的处理举例来说,我们期望将语音信号通过自编码器学习到具有一定可解释性的表示,具体来说我们希望表示的一部分维度能够代表语者或者内容的讯息,当然语音信号可能还包含其他类型的讯息,不过这里以语者和内容这两项为例。

如下图所示,我们考虑的方法分为两种,一种是使用一个自编码器,然后使得隐层向量的一部分维度代表语者,一部分维度代表内容;另一种方法是训练两个Encoder,使得一个Encoder的输出对应语者的讯息,另一个Encoder的输出对应内容的讯息:

语音处理

这样的方法可以做到变声(Voice Conversion),举例来说,下图中女生说“how are you”,男生说“hello”,然后通过Encoder获得他们语音的表示:

语音处理

通过组合他们的语者与内容讯息的向量就可以实现用男生的声音说“how are you”这件事:

语音处理

如下图所示,对于上述第一种训练一个Encoder的方法,可以采用生成对抗网络的思路进行处理,我们尝试使用训练一个语者分类器,这个分类器就相当于生成对抗网络中的Discriminator,将自编码器的表示中代表内容信息的部分输入到Discriminator中尝试来骗过Discriminator,这样自编码器就会学会将有关语者的讯息放到另外的维度中去,那么图中表示的绿色的部分就只剩下有关内容的讯息。这个方法采用生成对抗网络的思路来进行训练,也就意味着自编码器和Discriminator是交替迭代训练的:

第一种方法

第二种方法就是训练两个Encoder的方法,对于表示中有关内容的部分,可以采用在第一个Encoder后面添加一个instance normalization的方法,这种特殊的normalization可以移除全局的信息(也就是语者信息),然后就可以使得第一个Encoder仅学习内容的信息:

第二种方法

而对于第二个Encoder,如下图所示,它的输出并不是像上图中那样和第一个Encoder的输出拼接在一起后再输入到Decoder中,而是通过将其输出到Decoder后面的adaptive instance normalization中,这种normalization只会影响全局信息:

第二种方法

有关这一类的方法只介绍大体的方法,不做细节上的介绍。

  1. Discrete and Structured Representation
  • Discrete Representation

自编码器学习到的隐层表示是连续的,我们期望自编码器能学习到一个离散的表示。这样的好处是有利于聚类等任务,对于连续的表示通常还需要使用一些聚类的方法,而如果自编码器学习到的表示是离散的(比如one-hot的表示),这样我们就可以直接得到类别。

在下图中展示了两种离散型的表示,分别是根据表示最大值的维度得到的one-hot表示和根据每个维度是否大于0.5得到的binary表示:

离散表示

通过将连续的隐层表示转换成one-hot表示或者binary表示,使得整个网络是不可微分的,对于这种不可微分的网络也有一些优化的技巧,具体可以参照这篇论文:https://arxiv.org/abs/1611.01144

另外有一个学习离散型表示的方法,叫做Vector Quantised-Variational AutoEncoder (VQ-VAE),这种方法包含一个Codebook,Codebook中有多个向量,这里面的向量是网络的参数,是需要学习出来的。对于Encoder输出的隐层表示,要和Codebook中的向量计算相似度,然后将相似度最高的向量输入到Decoder中,这里通过最高相似度得到第几个向量就代表了自编码器的离散表示:

VQ-VAE

同样的这样的网络结构也是不可微分的,具体的优化方法可以参照论文:https://arxiv.org/abs/1711.00937

  • Structured Representation

我们还可以让自编码器输出结构化的表示,比如下面的seq2seq2seq auto-encoder。我们可以尝试让自编码输出一个序列作为隐层表示,它的输出和输出可以是一篇文章,中间的隐层序列就相当于文章的摘要:

seq2seq2seq auto-encoder

事实上,直接这样训练得到的摘要可能是人类无法理解的,举例来说,很可能文档中的“台湾大学”会被摘要成“湾学”这样的词汇,因此我们需要对Encoder的输出做一些限制,做法是使用生成对抗网络的思路,添加一个Discriminator来判断Encoder的输出是不是人类可以理解的句子,然后按照迭代的方法进行训练:

seq2seq2seq auto-encoder

这个方法也是不可微分的,实际上是按照强化学习的方式来训练的,具体方法参照论文:https://arxiv.org/abs/1810.02851

下面是一些用这种方法的一些例子。几个比较好的例子如下,机器会学习到直接复制原文或者进行一些词汇的缩写:

例子

例子

以下是一些不好的例子:

例子

例子

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值