自编码 AutoEncoder 是一种无监督学习的算法,他利用反向传播算法,让目标值等于输入值。什么意思呢,下面举个例子
有一个神经网络,它在做的事情是,输入一张图片,通过一个 Encoder 神经网络,输出一个比较 "浓缩的"feature map。之后将这个 feature map 通过一个 Decoder 网络,结果又将这张图片还原回去了
你也可以这么理解,整个 Encoder+Decoder 是一个神经网络,中间的 code 只是暂存的数据
感觉就像是,现在有一锅红糖水,你不停的煮它,最终水都被煮干了,只剩下红糖,这个红糖就是上图的 "Code"。然后你再向红糖里面注水、加热,结果又还原回了一锅红糖水
假设上面的神经网络展开如下图所示,可以看出,图片经过了一个压缩,再解压的工序。当压缩的时候,原有的图片质量被缩减。解压时,用信息量少却包含所有关键信息的文件恢复出了原本的图片。为什么要这样做呢?
因为有时候神经网络要接受大量的输入信息,比如说输入信息是高清图片时,信息量可能高达上千万,让神经网络直接从上千万个信息中进行学习是很吃力的。所以,为何不压缩一下,提取出原图片中最具代表性的信息,缩减输入信息量,再把缩减后的信息带入进行网络学习。这样学习起来就轻松多了
How to Train?
下图是一个 AutoEncoder 的三层模型,其中 W∗=WT,W∗ 没有什么含义,仅仅是个变量名字而已,用来区分 W,你也可以管 W∗ 叫 W′
Vincent 在 2010 年的论文中做了研究,发现只要单组 W 就可以了,即 W∗=WT。W∗ 和 WT 称为 Tied Weights(绑定的权重),实验证明,W∗ 真的只是在打酱油,完全没有必要去训练
如果是实数作为输入,Loss function 就是
L(f(x))=12∑k(ˆxk−xk)2
如果输入是 binary 的,即 01 值,那么就是
L(f(x))=−∑k(xklog(ˆxk)+(1−xk)log(1−ˆxk))
PCA V.S. AutoEncoder
同样都是降维,PCA 和 AutoEncoder 谁的效果更好呢?
首先从直觉上分析,PCA 本质上是线性的变换,所以它是有局限性的。而 AutoEncoder 是基于 DNN 的,由于有 activation function 的存在,所以可以进行非线性变换,使用范围更广
下图展示了 MNIST 数据集分别经过 PCA 和 AutoEncoder 降维再还原后的效果。第二行是是使用 AutoEncoder 的方法,可以看到几乎没什么太大变化;而第四行的图片很多都变得非常模糊了。说明 PCA 的效果是不如 AutoEncoder 的
Denoising AutoEncoders
Vincent 在 2008 的论文中提出了 AutoEncoder 的改良版 ——dA,论文标题叫 "Extracting and Composing Robust Features",译成中文就是 "提取、编码出具有鲁棒性的特征"
首先我们考虑,为什么会产生这样的变种 AutoEncoder。如果我们仅仅只是在像素级别对一张图片进行 Encode,然后再重建,这样就无法发现更深层次的信息,很有可能会导致网络记住了一些特征。为了防止这种情况产生,我们可以给输入图片加一些噪声,比方说生成和图片同样大小的高斯分布的数据,然后和图像的像素值相加(见下图)。如果这样都能重建原来的图片,意味着这个网络能从这些混乱的信息中发现真正有用的特征,此时的 Code 才能代表输入图片的 "精华"
关键是,这样胡乱给原始图片加噪声真的科学吗?Vincent 从大脑认知角度给了解释。Paper 中说到:
人类具有认识被阻挡的破损图像的能力,源于我们高等的联想记忆感受机能
就是说,我们能以多种形式去记忆(比如图像、声音),所以即便是数据破损丢失,我们也能回想起来
Dropout AutoEncoders
其实这个没什么特别的,平时我们不论是 CNN 还是 RNN 几乎都会用到 Dropout。据说 Dropout 是当时 Hilton 在给学生上课的时候提到的,用来帮助提升神经网路训练效果的小 Trick。具体关于 Dropout 的讲解可以看我的这篇文章
Adversarial AutoEncoders
在 AutoEncoder 中可能存在这样一个问题,图片经过 Encode 之后的 vector 并不符合我们希望的分布(例如高斯分布),他的分布很有可能如下图所示。这其实是令我们不太满意的(虽然我并不知道 Code 满足分布到底有重要,但是既然别人认为很重要那就重要吧),那么有什么解决办法呢?
由 University of Toronto、Google Brain 和 OpenAI 合作的文章 Adversarial Autoencoders(AAE) 提出了一个使用 Autoencoder 进行对抗学习的 idea,某种程度上对上述问题提供了一些新思路
AAE 的核心其实就是利用 GAN 的思想,利用一个生成器 G 和一个判别器 D 进行对抗学习,以区分 Real data 和 Fake data。具体思路是这样的,我现在需要一个满足 p(z) 概率分布的 z 向量,但是 z 实际上满足 q(z) 分布。那么我就首先生成一个满足 p(z) 分布的 z′ 向量,打上 Real data 的标签,然后将 z 向量打上 Fake data 的标签,将它们俩送入判别器 D。判别器 D 通过不断学习,预测输入 input 是来自于 Real data(服从预定义的 p(z) 分布)还是 Fake data(服从 q(z) 分布)。由于这里的 p(z) 可以是我们定义的任何一个概率分布,因此整个对抗学习的过程实际上可以认为是通过调整 Encoder 不断让其产生数据的概率分布 q(z) 接近我们预定义的 p(z)
基本上 AAE 的原理就讲完了,还剩最后一个问题,AAE 的 Loss function 是什么?
L(x,ˆx)+∑jKL(qj(z|x)||p(z))
其中 KL(P||Q)=∫∞−∞p(x)logp(x)q(x)dx,如果 P 和 Q 分布非常接近,那么 KL(P||Q)≈0。回过头看上面的 Loss function 就很好理解了,因为我们需要 minimize loss,而且要求 q(z) 分布趋近于 p(z) 分布,而 KL 散度的作用正好是计算两个分布的相似程度
下面简述 KL 散度的公式推导。假设 p 和 q 均是服从 N(μ1,σ21) 和 N(μ2,σ22) 的随机变量的概率密度函数,则
KL(p,q)=−∫p(x)logq(x)dx+∫p(x)logp(x)dx=12log(2πσ22)+σ21+(μ1−μ2)22σ22−12(1+log2πσ21)=logσ2σ1+σ21+(μ1−μ2)22σ22−12
更加详细的推导过程可以看这篇文章
Variational AutoEncoders
前面的各种 AutoEncoder 都是将输入数据转换为 vector,其中每个维度代表学习到的数据。而 Variational AutoEncoders(VAE)提供了一种概率分布的描述形式,VAE 中 Encoder 描述的是每个潜在属性的概率分布,而不是直接输出一个值
举例来说,假设我们已经在一个 AutoEncoder 上训练了一个 6 维的 vector,这个 6 维的 vector 将学习面部的一些属性,例如肤色、是否戴眼镜等
在上面的示例中,我们使用单个值来描述输入图像的潜在属性。但是,我们可能更喜欢将每个潜在属性表示为一个范围。VAE 就可以实现这个功能,如下图所示
通过这种方法,我们现在将给定输入的每个潜在属性表示为概率分布。从状态解码(Decode)时,我们将从每个潜在状态分布中随机采样以生成向量来作为解码器的输入
现在问题来了,sample()
是不能求导的,那我们如何反向传播?幸运的是,我们可以利用一个聪明的办法 ——"reparameterization trick"。这个办法的具体思想如下图,假设我们要让 z 服从正态分布,我们可以生成一个标准正态 ε,对这个标准正态进行平移以及伸缩变换,生成均值为 μ,方差为 σ 的正态分布 z=μ+σ⊙ε
通过 reparameterization,we can now optimize the parameters of the distribution, while still maintaing ε。就是说,我们保持 ε 不变,因为 ε 不需要学习修正,我们更新的只有 μ 和 σ