深度学习之自编码器AutoEncoder(一)

https://blog.csdn.net/qq_27825451/article/details/84968890

一、从生成模型开始谈起
1、什么是生成模型?

概率统计层面:能够在给丁某一些隐含参数的条件下,随机生成观测数据的这样一种模型,称之为“生成模型”。它给观测值和比周数据系列制定一个连和概率分布

机器学习层面:直接对数据进行建模,比如根据某个变量的概率密度函数进行数据采样。在贝叶斯算法中,直接对连和概率分布P(x,y)进行建模,然后利用贝叶斯公式进行求解P(y|x)。

2、生成模型的两大类型

第一类:完全表示出数据确切的分布函数

第二类:没有办法完全表示出确切的分布函数,但是,能够做到的是新的数据的生成,而具体的分布函数是模糊的。

在机器学习中,不管是自编码器AE、变分自编码器VAE、还是生成对抗网路GAN,都是属于第二类。生成新数据,也是大部分生成模型的核心目标。

二、什么是自编码器
1、自编码器的一般结构

自编码器是一种无监督学习技术,利用神经网络进行表征学习。也就是说,我们设计一个在网络中施加“瓶颈”,迫使原始输入压缩知识表示的神经网络架构。如果输入特征彼此独立,则该压缩和随后的重构将是非常困难的任务。但是,如果数据中存在某种结构(即输入特征之间存在相关性),则可以学习这种结构,并在强制输入通过网络的瓶颈时使用。

通俗理解:即输入的特征X1、X2、Xn之间存在某种特殊的联系,但是这些联系不需要你人为的进行特征提取,而是放到网络里面进行学习,最终浓缩为更精炼、数量更少的特征h1、h2、hm。其中m<n.这里的Xn就是输入数据,hm就是所谓的编码,也就是所谓的“瓶颈数据”。

自编码器的一般结构如下所示:

 

 

如上图所示,我们可以采取的未标记数据集和框架作为任务监督学习问题,负责输出新的X(原始输入x的重构)。这个网络可以通过最小化重构误差(原始输入和重构之间差异的度量)训练。瓶颈是我们网络设计的关键属性;如果没有信息瓶颈,我们的网络就会将这些值通过网络传递,并且只学会记住输入值。如下所示,编码向量和我的最开始的数据输入完全一样,要使得能够对输入数据进行重构,不需要做任何处理,只需要让每一个神经元对输入的数据不做人处理,原样复制,死记硬背即可,这样的编码器没有任何意义。

 

瓶颈限制了完整网络可以传递的信息量,从而迫使网络学习压缩输入数据。

2、自编码器的两个重要特征

(1)压缩编码的数据维度一定要比元时输入数据更少。也就是所谓的要具有一定的“瓶颈限制”,如果压缩编码的数据维度更多,那就到不到数据降维的目的了,那编码还有什么意义呢?

(2)不管是编码器,还是解码器,本质上都是神经网络层,神经网络层一定要具有一定的“容量”。什么是容量,就是一定要不止一个神经网络层才行,为什么?因为我们知道神经网络层数意味着对数据的隐含特征进行提取(虽然我不知道到底是怎么提取的,但是我知道一定是有隐含关联性的),如果向上面的只有一个中间的压缩编码数据层,此时我们的数据输入层与编码输出层是直接相连接的,如果我在神经元节点上不使用非线性激活函数,我们发现,这会得到和PCA类似的降维效果。所以,最好是多添加剂个网络层,来储存输入数据之间的那些隐含关系,存储它们的潜在特征和关联。

总结起来:自编码器需要“瓶颈+容量”

3、编码器的常见应用

异常监测、数据去燥、数据降维、图像修复、信息检索

三、常见的自编码器
1、欠完备的自编码器——普通一般的自编码器

构建自编码器最简单的架构是限制网络隐藏层中存在的节点数量,进而限制可以通过网络传输的信息量。通过根据重构误差惩罚网络,我们的模型可以学习输入数据的最重要属性,以及从“编码”状态如何最好的重构原始输入。理想情况下,这种编码将学习和描述输入数据的潜在属性。

 

由于神经网络能够学习非线性关系,因此可以认为这是PCA更有力(非线性)的泛化。而PCA试图发现描述原始数据的低维超平面,自编码器则能够学习非线性流形(流形为连续的非交叉的曲面)。这两种方法之间的区别如下图所示。

 

对于更高维数据,自编码器能够学习数据(流形)的复杂表示,可用于描述低维度的观测数据,并可以对应地解码成原始输入空间。

 

欠完备自编码器没有明确的正则化项,只是根据重构损失来训练我们的模型。因此,确保模型不记忆输入数据的唯一方法就是确保我们已经充分限制了隐藏层中的节点数量。

总结:

为了深入了解自编码器,我们还必须了解我们的编码器和解码器模型的容量(capacity )。即使“瓶颈层”只有一个隐藏节点,只要编码器和解码器模型有足够的容量来学习一些可以将数据映射到索引的任意函数,我们的模型仍然可以记住训练数据。

因此,我们希望我们的模型能够发现我们数据中的潜在属性,重要的是要确保自编码器模型不仅是学习有效记忆训练数据的方法。像监督学习问题,我们可以对网络采用各种形式的正则化,以鼓励更好的泛化属性。

2、稀疏自编码器——隐藏层选择性的激活

稀疏自编码器为我们提供了一种不需要减少我们隐藏层的节点数量,就可以引入信息瓶颈的的方法。相反,我们将构造我们的损失函数,以惩罚层中的激活。对于任何给定的观察,我们都会鼓励我们的网络学习只依赖激活少量神经元进行编码和解码。值得注意的是,这是一种比较特殊的正则化实现方法,因为我们通常调整网络的权重,而不是激活。

通用稀疏自编码器的可视化如下,节点的不透明度与激活级别对应。请注意,激活的训练模型的各个节点是数据相关的,不同的输入将导致通过网络不同节点的激活。

 

这样做的结果是,我们使网络的各个隐藏层节点对输入数据的特定属性敏感。欠完备自编码器使用整个网络进行每次观察,而稀疏自编码器将*根据输入数据选择性地激活网络区域。因此,我们限制了网络记忆输入数据的容量,而不限制网络从数据中提取特征的能力。这让我们单独考虑网络的潜在状态的表征和正则化分开,这样我们就可以根据给定数据上下文的意义选择潜在状态表征(即编码维度),同时通过稀疏性约束施加正则化。

我们可以通过两种主要的方式来强加这种稀疏性约束;都涉及到测量每个训练批次的隐藏层激活,并为损失函数添加一些惩罚过度的激活的项。这些条款是:

L1正则化:我们可以添加一个对损失函数的正则化项,在h层中为观察i惩罚激活a的向量值的绝对值,使用微调参数λ进行缩放。


KL -散度(相对熵):本质上,KL散度是两个概率分布差异的度量。我们可以定义一个参数ρ稀疏,它表示一个神经元在样本集合上的平均激活。这种期望可以计算为,下标j表示表示层h中特定的神经元,对m个训练观察的表征x的激活求和。本质上,通过限制一个神经元在样本集合上的平均激活,我们鼓励神经元只对观测的一个子集进行激活。我们可以将ρ描述为一个伯努利随机变量分布,我们可以利用KL散度(下展开)来比较理想的分布在所有隐藏层节点上的观察分布。


注意:伯努利分布是“一个随机变量的概率分布,p为概率值1,q = 1−p为概率值0”。这与建立神经元激活的概率吻合。

两个伯内利分布的KL散度可写成。下面是理想分布p=0.2的损失项可视化,对应于此处的最小(零)惩罚。

 

3、降噪自编码器——给输入数据添加噪声

我们的模型通过某种信息瓶颈,尽可能重构输入。回想一下,前面我提到我们希望我们的自编码器足够敏感以重构原始观察的结果,但又要对训练数据不够敏感,以至于模型学习通用的编码和解码。还有一种开发通用化模型的方法,我们可以略微破坏输入数据,但仍维持未损坏的数据维作为目标输出。

 

 

采用这种方法,我们的模型不能简单地开发一个记忆训练数据的映射,因为我们的输入和目标输出不再相同。更确切的说,该模型学习矢量场以将输入数据映射到较低维流形;如果这个流形精确地描述了自然数据,我们就有效地“消除”了多余的噪声。

 

上图是,对矢量场x与原始值x的可视化描述。黄点表示在添加噪声之前的训练样本。你可以看到,模型已经学会了调整损坏的输入到已学习的流形。

值得注意的是,这个矢量场通常只在模型在训练过程中观察到的区域中表现良好。在远离自然数据分布的区域,重构误差既大又不总是指向真实分布的方向。

 

4、压缩自编码器

人们会期望对于非常相似的输入,学习的编码也会非常相似。我们可以为此训练我们的模型,以便通过要求隐藏层激活的导数相对于输入而言很小。换句话说,对于输入比较小的改动,我们仍然应该保持一个非常类似的编码状态。这与降噪自编码器相似,因为输入的小扰动本质上被认为是噪声,并且我们希望我们的模型对噪声具有很强的鲁棒性。“降噪自编码器使重构函数(解码器)抵抗输入有限小的扰动,而压缩自编码器使特征提取函数(编码器)抵抗输入无限小的扰动。“

因为我们明确地鼓励我们的模型学习一种编码,在这种编码中,类似的输入有类似的编码。我们基本上是迫使模型学习如何将输入的临近区域收缩到较小的输出临近区域。注意重构数据的斜率(即微分)对于输入数据的局部邻域来说基本为零。

 

我们可以通过构造一个损失项来实现这一点,该项对输入训练样例中的大量的衍生进行惩罚,本质上是惩罚那些在输入中有微小变化导致编码空间发生巨大变化的实例。

在更高级的数学术语中,我们可以将我们的正则化损失项设置为雅可比矩阵J的Frobenius范数的平方||A||F,用于对输入观测的隐含层激活。Frobenius范数本质上是矩阵的L2范数,而雅可比矩阵仅仅代表了一个向量值函数的所有一阶偏导数。

对于m观察和n隐藏层节点,我们可以计算如下的值。

 

为了写得更简洁,我们可以将我们的完整损失函数定义为:

 

在这里定义了我们的隐层激活输入x的梯度场,所有的i训练示例求和。

5、变分自编码器——VAE——后面会讨论

四、自编码器的缺点
以一个手写数字的图片编码-解码为例。

当我们对解码器输入一个训练集中从未出现的编码的时候,我们得到的重构的输出可能是一个完全的乱码或者是噪声,也就是说与手写数字数据毫无关系,很显然,这并不是我们所希望的。我们希望的是“生成模型”能够对任意的输入编码产生有相关意义的数据,这就是我们后面的“变分自编码器VAE”所要做的事情。

所以,自编码器其实并不是一个真正意义上“生成模型”。

上一篇:(2)如何使用AutoEncoder预测客流量


下一篇:PyTorch实现简单的自动编码器autoencoder