从自编码器到变分自编码器(其一)
2018年03月21日 由 yuxiangyu 发表
446208
0
从自编码器到变分自编码器介绍共有两篇文章:
从自编码器到变分自编码器(其一)
从自编码器到变分自编码器(其二)
自编码器是一种无监督学习技术,利用神经网络进行表征学习。也就是说,我们设计一个在网络中施加“瓶颈”,迫使原始输入压缩知识表示的神经网络架构。如果输入特征彼此独立,则该压缩和随后的重构将是非常困难的任务。但是,如果数据中存在某种结构(即输入特征之间存在相关性),则可以学习这种结构,并在强制输入通过网络的瓶颈时使用。
如上图所示,我们可以采取的未标记数据集和框架作为任务监督学习问题,负责输出x帽(原始输入x的重构)。这个网络可以通过最小化重构误差
(原始输入和重构之间差异的度量)训练。瓶颈是我们网络设计的关键属性;如果没有信息瓶颈,我们的网络就会将这些值通过网络传递,并且只学会记住输入值。
瓶颈限制了完整网络可以传递的信息量,从而迫使网络学习压缩输入数据。
注意:事实上,如果我们要构造一个线性网络(即,每层都不使用非线性激活函数),我们会观察到类似PCA中所观察到的降维。
理想的自编码器模型平衡以下几点:
- 对输入敏感足以准确建立重构。
- 这种敏感不能过度,导致模型简单的记住甚至过拟合训练数据。
这种取舍迫使模型在只保留重构输入所需的数据的变化,不保留输入的冗余。一般来说,这涉及构建一个损失函数,其中一项鼓励我们的模型对输入敏感(比如,重构损失
),而第二项防止出现直接记住或过度拟合(如,加个正则化)。
我们通常会在正则化项前面添加一个缩放参数,以便我们可以调整两个目标之间的平衡。
在这篇文章中,我会讨论一些标准的自编码器架构,用于强加这两个约束并调整权衡。下一篇,我将讨论基于这些概念构建的变分自编码器,以构建更强大的模型。
欠完备的自编码器
构建自编码器最简单的架构是限制网络隐藏层中存在的节点数量,进而限制可以通过网络传输的信息量。通过根据重构误差惩罚网络,我们的模型可以学习输入数据的最重要属性,以及从“编码”状态如何最好的重构原始输入。理想情况下,这种编码将学习和描述输入数据的潜在属性。
由于神经网络能够学习非线性关系,因此可以认为这是PCA更有力(非线性)的泛化。而PCA试图发现描述原始数据的低维超平面,自编码器则能够学习非线性流形(流形为连续的非交叉的曲面)。这两种方法之间的区别如下图所示。
对于更高维数据,自编码器能够学习数据(流形)的复杂表示,可用于描述低维度的观测数据,并可以对应地解码成原始输入空间。
欠完备自编码器没有明确的正则化项,只是根据重构损失来训练我们的模型。因此,确保模型不记忆输入数据的唯一方法就是确保我们已经充分限制了隐藏层中的节点数量。
为了深入了解自编码器,我们还必须了解我们的编码器和解码器模型的容量(capacity )。即使“瓶颈层”只有一个隐藏节点,只要编码器和解码器模型有足够的容量来学习一些可以将数据映射到索引的任意函数,我们的模型仍然可以记住训练数据。
因此,我们希望我们的模型能够发现我们数据中的潜在属性,重要的是要确保自编码器模型不仅是学习有效记忆训练数据的方法。像监督学习问题,我们可以对网络采用各种形式的正则化,以鼓励更好的泛化属性。
稀疏自编码器
稀疏自编码器为我们提供了一种不需要减少我们隐藏层的节点数量,就可以引入信息瓶颈的的方法。相反,我们将构造我们的损失函数,以惩罚层中的激活。对于任何给定的观察,我们都会鼓励我们的网络学习只依赖激活少量神经元进行编码和解码。值得注意的是,这是一种比较特殊的正则化实现方法,因为我们通常调整网络的权重,而不是激活。
通用稀疏自编码器的可视化如下,节点的不透明度与激活级别对应。请注意,激活的训练模型的各个节点是数据相关的,不同的输入将导致通过网络不同节点的激活。
这样做的结果是,我们使网络的各个隐藏层节点对输入数据的特定属性敏感。欠完备自编码器使用整个网络进行每次观察,而稀疏自编码器将被迫根据输入数据选择性地激活网络区域。因此,我们限制了网络记忆输入数据的容量,而不限制网络从数据中提取特征的能力。这让我们单独考虑网络的潜在状态的表征和正则化分开,这样我们就可以根据给定数据上下文的意义选择潜在状态表征(即编码维度),同时通过稀疏性约束施加正则化。
我们可以通过两种主要的方式来强加这种稀疏性约束;都涉及到测量每个训练批次的隐藏层激活,并为损失函数添加一些惩罚过度的激活的项。这些条款是:
- L1正则化:我们可以添加一个对损失函数的正则化项,在h层中为观察i惩罚激活a的向量值的绝对值,使用微调参数λ进行缩放。
- KL -散度(相对熵):本质上,KL散度是两个概率分布差异的度量。我们可以定义一个参数ρ稀疏,它表示一个神经元在样本集合上的平均激活。这种期望可以计算为,下标j表示表示层h中特定的神经元,对m个训练观察的表征x的激活求和。本质上,通过限制一个神经元在样本集合上的平均激活,我们鼓励神经元只对观测的一个子集进行激活。我们可以将ρ描述为一个伯努利随机变量分布,我们可以利用KL散度(下展开)来比较理想的分布在所有隐藏层节点上的观察分布。
注意:伯努利分布是“一个随机变量的概率分布,p为概率值1,q = 1−p为概率值0”。这与建立神经元激活的概率吻合。
两个伯内利分布的KL散度可写成
。下面是理想分布p=0.2的损失项可视化,对应于此处的最小(零)惩罚。
降噪自编码器
我们的模型通过某种信息瓶颈,尽可能重构输入。回想一下,前面我提到我们希望我们的自编码器足够敏感以重构原始观察的结果,但又要对训练数据不够敏感,以至于模型学习通用的编码和解码。还有一种开发通用化模型的方法,我们可以略微破坏输入数据,但仍维持未损坏的数据维作为目标输出。
采用这种方法,我们的模型不能简单地开发一个记忆训练数据的映射,因为我们的输入和目标输出不再相同。更确切的说,该模型学习矢量场以将输入数据映射到较低维流形;如果这个流形精确地描述了自然数据,我们就有效地“消除”了多余的噪声。
上图是,对矢量场x与原始值x的可视化描述。黄点表示在添加噪声之前的训练样本。你可以看到,模型已经学会了调整损坏的输入到已学习的流形。
值得注意的是,这个矢量场通常只在模型在训练过程中观察到的区域中表现良好。在远离自然数据分布的区域,重构误差既大又不总是指向真实分布的方向。
压缩自编码器
人们会期望对于非常相似的输入,学习的编码也会非常相似。我们可以为此训练我们的模型,以便通过要求隐藏层激活的导数相对于输入而言很小。换句话说,对于输入比较小的改动,我们仍然应该保持一个非常类似的编码状态。这与降噪自编码器相似,因为输入的小扰动本质上被认为是噪声,并且我们希望我们的模型对噪声具有很强的鲁棒性。“降噪自编码器使重构函数(解码器)抵抗输入有限小的扰动,而压缩自编码器使特征提取函数(编码器)抵抗输入无限小的扰动。“
因为我们明确地鼓励我们的模型学习一种编码,在这种编码中,类似的输入有类似的编码。我们基本上是迫使模型学习如何将输入的临近区域收缩到较小的输出临近区域。注意重构数据的斜率(即微分)对于输入数据的局部邻域来说基本为零。
我们可以通过构造一个损失项来实现这一点,该项对输入训练样例中的大量的衍生进行惩罚,本质上是惩罚那些在输入中有微小变化导致编码空间发生巨大变化的实例。
在更高级的数学术语中,我们可以将我们的正则化损失项设置为雅可比矩阵J的Frobenius范数的平方||A||
F,用于对输入观测的隐含层激活。Frobenius范数本质上是矩阵的L2范数,而雅可比矩阵仅仅代表了一个向量值函数的所有一阶偏导数。
对于m观察和n隐藏层节点,我们可以计算如下的值。
为了写得更简洁,我们可以将我们的完整损失函数定义为:
在这里
定义了我们的隐层激活输入x的梯度场,所有的i训练示例求和。
总结
自编码器是一种神经网络架构,能够发现数据中的结构,以便开发输入的压缩表示。一般自编码器架构的许多不同变种,其目标是确保压缩表征表示原始数据输入的有意义的属性;通常使用自编码器工作时遇到的最大挑战,是让你的模型实际学习一种有意义且可泛化的潜在空间表征。
因为自编码器学习如何根据训练期间从数据中发现的属性(即,输入特征向量之间的相关性)来压缩数据,所以这些模型通常仅能够重构与训练中观察到的模型相似的数据。
自编码器的应用包括:
- 异常检测
- 数据去噪(例如图像,音频)
- 图像修复
- 信息检索
https://www.jeremyjordan.me/autoencoders/