• lecture15-自动编码器、语义哈希、图像检索


    Hinton第15课,本节有课外读物《Semantic Hashing》和《Using Very Deep Autoencoders for Content-Based Image Retrieval》这两篇论文


    一、从PCA到AE

    这部分中,首先介绍下PCA,这个方法被广泛的应用在信号处理上。PCA的idea就是高维数据可以用更低维度的编码来表示,当数据位于高维空间中的线性流形(linear manifold)附近时就会发生这种情况。所以如果我们可以找到这个线性流形,我们就能将数据投影到这个流形上,然后只要表现它在流形上的位置就行了。因为在这个方向上是正交于这个流形的,所以并没有损失多少信息,所以数据中也没有很多变化。正如我们看到的,我们使用标准的PCA来有效的完成这个操作,或者使用有着一层隐藏层的NN来低效的完成,这个NN中隐藏层单元和输出层单元都是线性的。使用NN的优势在于我们可以将它推广到那些使用非线性函数编码的DNN来实现。从这个编码中得到的数据的重构同样是这个编码的非线性函数。这可以让我们处理输入空间中的曲线流形。所以我们通过将数据映射到这个曲线流形上来表现数据,这是一个更有力的表征。


    在PCA中,我们有N维的数据,然后想要使用少于N维数据来表示他们。所以我们找到了数据的从大到小前M个方差的正交方向,然后忽略那些方差不是很大的方向。这M个主维度来自于更低维度子空间,然后通过映射到更低维度空间的M维上来表示N维的数据点。所以我们损失所有的信息是关于数据在剩下的正交方向上的点。不过因为这些地方都没什么方差,所以也没损失多少信息。如果我们想要从这M个维度上重构这些数据点,首先在那些没有表示出来的N-M方向上减去均值,然后重构中的区域就是那些未表现出来的方向上介于数据点的值与其均值之间的平方差的和,可以在下图中看到。


    所以先考虑2维的数据,这个分布是按照拉长高斯得到的。这个椭圆意思就是有着标准差轮廓的高斯。考虑向上图中那个红点的数据点。如果我们使用只有一个主成分的PCA,这个成分将会是数据有着最大方差的方向。所以为了表现这个红点,我们需要表现沿着这个方向上数据偏移多远。换句话说,我们需要表现红点在那条线上的投影,也就是那个绿点。当我们需要重构这个红点的时候,我们需要用到忽略的那个方向上所有的数据点的均值,换句话说需要在那个黑线上表现出这个点,所以重构上损失的就是介于红点和绿点之间的平方差。也就是会损失之前忽略方向上所有数据点和均值之间的差。所以我们显而易见的在最小化损失,如果我们选择忽略的方向是最小方差的。


    现在我们可以执行PCA或者使用BP的版本,不过这不是很有效的。所以我们要做的就是在做一个网络,他的输出就是数据的重构。然后我们试着最小化这个平方误差。这个网络有一个中心瓶颈,它只有M个隐藏单元。这些都是对应着主成分,或者一些类似于主成分的东西。所以看上图左边的那个模型,有一个输入向量,然后将输入投影到编码向量上,然后从这个编码向量上构建一个输出向量,目的就是让这个输出向量尽可能的相似于输入向量。编码向量的隐藏单元的激活值来自于这个瓶颈。所以这个编码向量是一个输入向量的压缩表示。如果这个隐藏单元和这个输出单元都是线性的,那么输出的编码就像这样,我们学到的编码是最小化平方重构误差的。这就是PCA所作的。它得到的重构误差与PCA所作的一样。不过他不需要一定有隐藏单元来表示主成分。他们会跨越同样的空间作为前面M个主成分,不过他们也许是这些轴的旋转或者歪斜。所以引入编码单元的权重向量是表示主成分的方向,不过也许不是正交的。而且不像PCA,他们通常有相同的方差,不过这个用这些编码单元引入的权重向量跨越的空间是完全与这M个主成分跨越的空间一致的。所以以这种角度来看,这个网络做的就是与PCA做的一样的事情,只是如果我们使用降序来学习这个网络,它通常会比用于主成分的算法少得多就足够了。尽管如果有着大量的数据,他也许会更有效。


    在NN中使用BP来执行PCA的重点是它允许我们生成主成分分析。如果我们使用在编码层前后都有非线性层的NN,就可以表示位于一个曲线流形上的数据而不是高维空间中的线性流形,相比来说,这更通用。所以我们的网络看上去就如上图右边的模型。一个底层输入层,然后一层或者多层非线性隐藏单元,这里通常使用逻辑单元。然后就是一个编码层,这一层也许是线性单元,然后在编码层后面是一层或多层非线性隐藏单元,然后就是一个输出向量,这部分与输入向量上的训练很相似。所以这是一个奇怪的网络,这里使用有监督学习来做无监督学习的事情,这个网络的底层部分是一个编码器,将输入向量使用非线性方法转换成编码,顶层部分是一个解码器,这里使用非线性编码然后将它映射回输入的重构,所以在学习之后,我们有两个方向上的映射。

    二、深度AE

    在这部分,我们来看看训练DAE的问题。早在1980年代中期,人们就开始想这个问题了。不过他们没法将其训练的结果比PCA还好。有各种关于它的论文被发,不过没有那些里程碑的论文,都是水文。在我们提出通过预训练来一次训练一层深层网络的方法之后,Russ Salakhutdinov 和Hinton将这个方法用来预训练DAE,第一次就通过DAE得到了比PCA更好的表征。


    DAE总是看上去是一个很好的方法来做维度约间,因为他看上去应该比PCA更好。他们在两个方向上提供弹性的映射,而且这个映射可以是非线性的。他们的训练时间应该是以训练样本呈线性增长(或者更少时间)。在学习好之后,这个网络的编码部分是相当快的,因为这只是逐层的矩阵相乘罢了。不幸的是,使用BP算法来优化DAE是很困难的。通常人们使用很小的初始化权重,然后BP的梯度会死掉,所以对于深度网络来说,他们没法走出这个怪圈。不过现在我们有更好的方法来优化他们了。我们可以使用无监督的逐层预训练,或者我们可以简单的有意识的初始化这些权重,就像一个echo-state网络一样。


    第一个真正意义上成功的DAE由Russ Salakhutdinov和Hinton在2006年完成。他们将这个网络用来N维的数字。所以开始以784个像素的图片开始,然后通过三层隐藏层来对他们进行编码,在中心的编码层有30个实值激活值。然后接着解码这30个实值激活值,返回到784个重构像素上。这里先使用一个堆叠RBM来初始化用于编码的权重,然后用这些权重的转置来初始化解码器部分。所以在开始,这784个像素是使用一个用于编码器的权重的转置矩阵作为解码器的权重矩阵来重构的。不过在这4个RBM训练好之后,然后解开他们得到解码的转置,然后用BP来最小化这784个像素的重构误差。在这个情况中,是使用交叉熵误差的,因为像素是用逻辑单元来表示的,所以这个误差可以回向传播过整个深度网络,一旦我们开始回向传播这个误差,用来重构像素的权重就变得不同于编码这个像素的权重了。


    虽然使用BP和之后值都差不多,不过这却很work。所以如果先看上图第一行,是从这些数字类中随机挑的数字。如果观察第二行,这就是这些随机挑选的样本通过这个DAE的重构结果,这个DAE在中间层上有30个线性隐藏单元。所以数据已经被压缩成30个实值,然后接着重构。如果看看这个8,你可以发现重构的事实上比8还好。它在8中摆脱了一些小缺陷,因为他并没有编码的能力。如果将它与线性PCA相比较你会发现它更好,一个线性映射到20个实值数字没法很好的用来表示数据。

    三、DAE用在文档检索和可视化上

    在这部分中,会介绍使用DAAE来做文档检索,之前有个方法被称之为潜在语义分析,相当于使用PCA来从文档中提取计数向量。由潜在语义分析生成的编码可以随后用在判别文档的相似性,所以他们可以用来做文档检索。显然,如果DAE比PCA做的更好,我们期望就能够通过使用一个DAE提取出比使用潜在语义分析更好的编码。RUss-lan 和Hinton的工作显示的确是这样的。使用一个大的文档数据库,我们现实使用DAE提取的10个成分就能比使用像潜在语义分析这样的线性方法提取的50个成分更好。我们同样显示如果使用的编码非常小,例如只有2个成分,你可以使用这两个成分用来将文档视为2维映射中的一个点来进行可视化。而且,这效果还是比使用PCA提取前两个成分的效果要好。


    为了找到相似于询问文档的文档,首要做的就是转换每个文档到一个词袋中。换句话说,我们有一个词计数向量,而且是忽略了词之间的顺序,很明显这丢掉了相当多的信息。不过他同样保留了有关文档主题的许多信息。我们忽略了例如“the”或者“over”这样的停止单词,因为他们没有关于主题的信息。所以如果看上图的右边,是已经对一些单词计数好的结果,所以如果看到有的单词是计数为非0,那么就是文中出现过的,也就是vector、count、query、reduce...等等。这可以告诉你许多这个文档关于什么的信息。现在我们可以将这个询问文档的单词计数与其他上百万的文档的单词计数进行比较。不过这会涉及到相当大的向量。事实上,我们使用2000大小的向量,所以这会很慢。或者,我们可以将每个询问向量压缩到更小的向量中,而且仍然保留了大部分关于内容的信息。


    所以这里介绍如何约间的,我们先得到DAE然后将这2000个单词计数压缩到10个实值,从这10个实值上,我们可以重构出这2000个单词计数,虽然没法重构的非常好。通过训练这个NN来尽可能的复制他的输入向量作为他的输出向量,这可以尽可能的将信息压缩到这10个实值上。我们然后可以使用这10个数值来比较文档,这可以让过程更快。


    所以这里的一个问题就是单词计数没法和像素或者实值一样。也就是通过将所有的非停止单词来将这个计数划分成到一个词袋中,这样可以将计数向量转换到一个概率向量中,这个向量的所有元素加起来等于1。你可以认为这是从文档中随机挑选一个具体的非停止单词的概率,所以这个AE的输出部分,使用一个大的2000-way的softmax,我们的目标值就是当我们将计数向量约间到一个概率因子的时候单词的概率。

    另一个我们可以使用的技巧就是当重构他们的时候将这个单词计数视为概率。不过当我们使用他们去激活第一层隐藏层的时候,我们用N乘以所有的权重,这是因为从这个概率分布中有N个不同的观察值,如果我们将他们作为概率,输入单元将会有非常小的激活值,而且没法提供很多的输入给第一个隐藏层。所以我们有一个关于第一个RBM的很有趣的特性,自底向上的权重是N倍于自顶向下的权重。


    所以如何实现呢?我们在Reuters数据集中的4000个商业文档上使用2000个单词的词袋来训练,这些文档已经被手动标记了100个不同的类别。我们首先训练一个堆叠RBM,然后用BP来微调,并使用2000-way的softmax作为输出,然后在另一个有着4000文档的数据集上进行测试,为了测试,就是在这些测试文档中针对询问文档挑出一个文档,然后将所有的其他测试文档使用介于编码之间的角度的cos值进行排序,这里的编码就是那个10维的向量。对于这4000个可能的测试文档来说,每个都要试一遍,然后将检索到的文档的数量画出来,也就是对于那些与询问文档标记的相同的类的文档,在结果列表上有多少结果。这对于检索的质量来说不是一个非常好的测量方法。不过我们还是使用一样的测量方法来与LSA做比较。所以这也算是一个相当公平的比较了。


    所以这里就是检索的精度,作为检索到文档数量的函数。当你看到一个AE像这样使用一个有着10个实值数值的编码而且效果比使用50个实值数值潜在语义分析要好。当然,在得到编码之后,所要做的就是少于1/5的工作了。有着10个实值数值的潜在语义分析是更糟糕的。


    我们同样可以约间到两个实值数值来做一样的事情,然后不用来检索,而是将所有的文档画在一个图上,不过使用颜色进行标记这些2维的点,是的对应于由PCA对文档类生成的两个数字。所以我们看文档的主要的类。我们给这些主要类不同的颜色,然后在log(1+count)上使用PCA,点也就是用很大的数字压缩而成的计数,这就是得到的分布,正如看到的,这是有着许多分散的类。绿色类在一个地方,红色类在另一个稍微不同的地方,不过他们都混合起来了。所以我们使用DAE约间文档到2个数字来做相同的事情,然后将这些文档画出来,画在2维空间中。

    这就是我们得到的结果,这是一个更好的布局,它告诉我们更多关于数据集的结构。你可以发现不同的类别,你可以发现他们相当的分开,我们假设在中间的文档没有包含许多单词,所以它很难被区分开。像这样的一个可视化显示是非常有帮助的,例如,如果你看到其中的一个绿点是来自Enron的Accounts和earning报告,你可能不会想要在那种附近有个绿点的公司里面购买股票(buy shares)。

    四、语义哈希

    在这部分中,将会介绍一种被称之为语义哈希的技术,它提供了一个极端高效的方法来寻找针对询问文档的相似性文档。idea就是将文档转换到一个内存地址上。在这个内存上识别东西,所以如果你得到了一个具体的地址,然后观察附近的地址,你会发现都是相似的文档。这特别像在超级市场上,如果你想要去一个放着具体东西的地方,然后环顾四周,你会发现都是差不多的东西。人们在很长一段时间就知道如果你得到了图像的二值描述子,你就有了一个非常好的方法去快速的检索图像。许多二值描述子都是很容易得到的,例如是否在室内场景还是室外场景?是黑色图片还是白色图片?不过却很难得到一个有关30个二值描述子的列表,他们或多或少是相互正交的,而这些就是我们真正需要的。不过这个问题机器学习能够帮助我们,我们先观察这个与文档一样的问题,不过我们用的是图片。


    所以不通过使用文档的实值编码,通过从单词文档中得到二值编码。我们通过训练一个DAE,在他的编码层是一个逻辑单元,不过这还不够,因为逻辑单元会被用在他们的中间部分,这里他们有着实值用来传达尽可能多的2000个单词计数的信息。为了防止这样的事情发生,我们在微调的时候在输入和编码单元部分增加了噪音。所以我们先将它视为堆叠RBM一样训练它。然后将这些玻尔兹曼机通过对解码部分的权重矩阵的转置来解开,然后用BP来对他进行微调。正如我们做的,我们增加额外的高斯噪音到这个输入到编码部分的单元上。为了拒绝这些噪音,编码单元需要保持开或者保持关。所以噪音可以鼓励学习能够避免逻辑的中间区域传达许多信息,不过输入部分却对噪音非常敏感。在测试时间上,我们简单的阈值中间层上的逻辑单元来得到二值数值。所以如果我们能像这样训练一个AE,我们就能转换词袋的计数到一个非常小数量的二值数值。换句话说,我们可以学习一组对于重构词袋来说很好的二值特征。后来,Alex Krizhevsky发现我们事实上不必增加高斯噪音到输入到这30个编码单元上,相反的,我们值需要随机二值单元。所以在前向传播的时候,我们随机挑选一个用逻辑输出得到的二值数值。然后在后向传播中,我们假装我们从逻辑中传送了实数概率,而且得到一个用于BP的平滑梯度。一旦我们得到了这些短的二值编码,我们当然可以做一个连续的研究关于每个所知的文档的位置,然后存储编码。然后当有一个询问文档的时候,我们首先提取他的编码,如果没有我们所知的文档,那么我们将这个编码与存储的所有文档的编码进行对比。这种比较可以非常的快,因为只在传统的CPU上使用了特别的位对比操作,而CPU可以并行的比较许多位。不过我们还是需要通过一个非常长的文档列表,可能是十亿的。不过有可以更快的方法,我们可以将编码视为内存地址。


    所以idea就是在得到一个文档的时候,我们使用DAE作为作为一个哈希函数,然后将这个文档转换成一个30位的地址,现在就有了一个30位的内存地址。在这个内存中,每个地址会有一个指针,指回有这个地址的文档。如果几个文档有一样的地址,我们就可以在这个地方作一个列表。现在如果AE成功的用在让相似文档有着相似地址,就拥有了一个有关查找相似文档的非常快的方法。我们简单的处理这个询问文档,然后在内存的对应他的二值编码这个地址上,然后看看周围的地址。换句话说,你先将那个地址上的位进行翻转,以此来访问附近的地址。你可以想象一个很小的humming球,他的附近的地址都只有相差几位而已。我们期望找到这些附近的地址,因为他们是语义相似的文档。所以我们完全避免了搜寻大列表的麻烦。我们简单的计算一个内存地址,然后翻转几位,然后再去找相似的文档。特别是如果我们有着非常巨大的数据库,例如十亿个文档,这是特别高效的。我们完全避免了在这十亿项目中的连续查找。有时候称这种为超级市场搜寻,因为他特别像你早超级市场干的事情。假设你去一家没去过的超级市场,你想要找到凤尾鱼,你也许会问售货员罐头在哪,然后再去那个罐头的区域,然后环顾四周,幸运的话他们就在相差不多的位置。不过不幸的情况下,这个凤尾鱼可续存储在一个完全不同的地方,比如在匹萨的上面,这就是这种搜索的缺点了(个人:因为不是按顺序查找的,这类似于随机查找,所以一击不中的时候就没办法了)。正如对超级市场的了解,这本质上是一个2d表面。所以这是一个shells(个人:不知道翻译成啥)的1d 字符串,不过它有高度,这会给出一个2d,所以你只能在2维中定位东西,而且这不还不足够将所有你想要的东西放到另一个的附近,。例如,你想要素食的东西在附近,或者犹太人吃的东西在附近,或者过时的东西在附近。在2d中,你没法做所有的事情。不过我们这里有30维的超级市场,这是一个更加复杂的空间,其中很容易的将东西放在许多不同的东西附近,因为在不同的维度上的相似性。


    这是另一个观点关于在语义哈希中发生的事情。第一个检索方法的大部分工作是通过与从询问中提取的线索相关的存储列表相交互得到的。例如google将会给出一个列表关于所有包含某个具体单词的文档。当你在你的询问中使用这个单词的时候,他们会立马访问那个列表。然后交互那个列表和其他列表来找到一个文档能够满足询问中的所有项。现在计算机实际上有特别的硬件,可以在一个单一的机器指令中相交(intersect)32非常长的列表。这个硬件倍叫做内存总线,所以这32位二值地址中的每一位可以在内存中指定一半地址的列表。例如,如果这地址的第一位是开着的,那么就指定了顶层一半的内存了。如果这一位是关闭的,它就指定底层一半的内存了。内存总线做的就是相交32的列表来找到一个位置,这个位置满足在这个二值编码中的所有的32个值。所以我们可以认为语义哈希是作为一个使用机器学习方法将索引问题映射到计算机擅长的列表相交上。只要我们的32位对应于文档或者图像的有意义的特性,那么我们就能在没有任何搜索的情况下快速的找到相似的其他东西。

    五、学习二值编码用以图像检索

    在这部分中,会介绍在图像检索上二值编码的使用。对于检索文档来说,人们喜欢例如google这样的存在的好方法,像语义哈希这样的技术也许没有什么价值。不过检索图像却不同,而且转化一张图片到一个相当大的二值编码(例如有256位)的这种方法看上去可以很work。然而,我们并不想要一个在这256位的向量上有个非常长的连续搜索,所以语义哈希可以被用来先生成短的列表,然后我们通过在一个串行搜索中使用更长的二值编码来得到更好的质量匹配。


    现在我们来看看使用二值编码如何来进行图像检索。当前的图像检索通常是使用标题的,不过为什么不使用图像呢?显然他们包含着比标题还多的信息,基本的问题在于像素不像单词。单独的像素不会告诉我们太多有关图像内容的东西。显然,如果你要识别图像包含的对象,那么我们需要拥有比单词多更多的东西,不过识别对象是很困难的。至少当我们第一次接触这个事情的时候是困难的。现在DNN已经更加的擅长干这个了,所以这也许是一个好方法了。所以如果我们不打算识别对象,也许我们要做的就是提取一个有关图像内容的向量。显然所需要提取的是实值数值向量。不过问题是在真实数据库中匹配实值向量是很慢的,而且实值数值向量需要许多的存储空间。如果我们能提取出一个相对来说很短的二值向量,它包含着许多关于图像的信息,那么存储就变得更简单,而且匹配会变得更快。


    更快是通过一个两阶段的方法完成的。首先,我们提取一个差不多30位的短二值编码,这个短的二值编码是通过语义哈希得到的,用来快速的得到一个有关未来图像的短列表。所以我们简单的使用这个短二值编码,翻转一些位来得到待选图像。这些候选的图随后可以使用那些已知的图像的256位的二值编码来匹配,为了寻找比使用28位二值编码更好的匹配。甚至一个256位的二值编码值来说,每个图像只需要4个词的内存大小。即使我们随后要在这些二值编码上做一个串行搜索,这个搜索也可以完成的很块,因为它只需要很少的操作来对比两个256二值编码来找到他们之间有多少位是一样的。问题就是在检索图片的时候一个二值编码的256的结果有多好。所查找的图片是我们认为的相似吗?


    这里是一个由Alex Krizhevsky训练的网络。它在一个小彩色图像集上效果不错,他们都是32×32像素大小的,而且他将输入分为红色,绿色和蓝色三个通道,所以这些图片有3000多个输入。随后他扩展成一个更大的隐藏单元层,因为我们要从实值输入转换到逻辑隐藏单元,这可能有更少的容量。然后我们逐渐减少每一层的单元数量,直到我们得到的了256位。这个编码器有大约67百万的参数。这相当大,它需要在GPU上好几天才能训练完,而且是在2百万个图像上训练。几乎没有理论来判断这里使用的结构,我们知道我们想要一个相当深的网络,让他像一个箭头一样是有道理的。不过这个具体的结构,每一层的单元数量还是靠猜的。有趣的就是像这样的猜已经表明它可以很好的work。想必,有许多其他的更work的结构。


    第一个问题就是像这样的一个顺序编码器在重构图像上的结果如何?所以上图第一行的左边是一个人脸,它对应的就是重构的结果,你可以看到从这个重构中,你可以判断这个图像属于哪一类。第二行就是另一个例子,这是一个在party上的场景,你没法分辨这是一个什么场景,不过你可以猜这是涉及到许多人或者你猜不到。最后一行是一个户外场景,你可以发现重构的图抓住了很多准确的信息,它抓住了水,天空,和中间的陆地。


    所以让我们看看通过这个顺序编码索引图像的质量。上图上面的部分的红框是一个Michael Jackson的图像,Alex 索引了最相似的图像,在每个图像中,你可以发现有多少位与Michael Jackson身体不一样。你可以发现他们都差不多有数量相当的相似的位。在256位上,如果是随机图像的话,只有61位不同是不太可能发生的。只有如此少的几位不同的话,那么就是一个相当相似的图像。有关什么是检索的一个nice的事情是,有一个例外,他们都是人脸。如果我们看你通过使用欧式距离在原始像素上的索引结果,(上图下面部分)那么他们中一些是人脸,不过大部分都不是。所以显然这个顺序编码器可以理解有关人脸的信息,而这些信息是没法通过欧式距离来包含的。这明显可以得到更好的索引。


    我们来看看另一个例子,这里我们的图像都是party场景的图像,你可以发现差不多一半的图片你可以认为是相似于其他party场景的。其他party场景的有着一些明亮的东西在中间位置,就像最原始的party场景,你同样注意到大多数坏的匹配同样在中间位置上有许多明亮的东西。所以即使我们通过一些隐藏层降低到256位二值编码,它仍然敏感于图像的结构和更亮的块的位置等信息。如果你看上图下半部分,也就是欧式距离做的,结果更糟糕。欧式距离得到的其他场景有一群人的,而且任何东西看上去都那么不相似。你可以发现用欧式距离,它通常得到的是非常平滑的图像,这是因为如果你没法匹配图像中高频率的变化,它更擅长匹配他的均值,然后得到其他有着高频率变化的stuff。所以当你得到了一个复杂的图像,包含的距离通常可以找到平滑的图像来匹配它。这是因为它在像素空间中最小化一个平凡误差。


    所以显然的,我们需要检索的图像可以更敏感于图像的内容,也即是存储的对象是相关的的,少敏感于图像的强度。我们可以先训练一个大网络来识别真实图像中许多不同种类的对象,这个在lecture5中说过了,然后我们得到这个大网络的最后一个隐藏层中的激活向量,然后使用这个作为图像的表征。这在抓取图像中不同类别的信息时会比像素强度更好。所以如果这个方法work的话,我们使用在lecture5中描述的网络,在图像比赛中使用的那个网络。到目前为止,我们只在欧式距离与最后一层隐藏层中的向量的激活值之间对比过(也就是上上图的两个结果,一个AE得到的,一个欧式距离得到的)。不过显然如果他work的话,我们随后可以使用这些激活的向量来建立一个顺序编码来得到很少位数的二值编码。所以先看看它用欧式距离是否work。结果显示它work的很好,我们不知道他是否在二值编码上会work。


    所以在上图左边的列中,你可以发现所需要询问的图像。然后在他们的右边都是检索得到的,如果你看这个大象询问图像,你可以看到检索得到的是其他大象,不过他们有着不同的姿势。所以这些图像在像素空间中没有一个非常好的重叠,经过这个重叠也没那么糟糕。如果你看这个万圣节南瓜,你可以发现所有的这些检索到的都是都是万圣节南瓜,不过他们在像素空间中有一个相当坏的重叠。和航空母舰相似的,我们检索到的其他航空母舰的图片都是非常不同的。所以我们预料如果我们可以将激活的向量约间到短的二值编码。我们就会有一个快速的有效的方法来检索相似的图片,只通过图像的内容。我们会在lecture16中看到我们可以将图像的内容和图像的标题结合起来,来得到一个更好的表征。

    六、浅层AE用来预训练

    在这部分中,会介绍对于DNN来说可代替的预训练方法。会介绍使用CD训练的RBM的预训练方法。之后,人们发现许多其他的方法用来预训练层级特征。确实,在当提供了足够多的标签数据的时候,如果你正确的初始化权重,你也许不需要预训练。


    我们看到了许多巧妙的事情,即可以通过DAE生称的代码来完成。现在这里先考虑只有一层隐藏层的浅层AE。REM可以可浅层ASE一起用,特别是当他们用CD来训练的时候,因为他们试着是重构像原数据。当你使用一个AE呢?一个RBM有非常强的重构能力,因为隐藏单元之允许有二值激活。这约束了他们的能力。如果我们用最大似然来训练RBM,那么他们就完全不像AE了。一个观察是否有一个纯噪音的像素的方法是,一个AE试图重构它有的任何噪音。一个用最大似然训练的RBM会完全忽略这个像素,而且只通过那个输入的偏置来建模。所以既然我们可以将RBM视为一种有着强烈正则化的AE,也许我们就能替换这个用来为堆叠AE做预训练的RBM。结果显示,如果这样做的话,预训练就不那么有效了,至少如果你使用浅层AE的话,这是真的,这些浅层AE都是用惩罚平方权重来正则化的。所以堆叠这些AE并不会和堆叠RBM一样work。


    然而,有一种完全不同AE,它可以很work,这就是消噪AE。它被Montreal小组研究透了。DAE通过将许多成分设置成0来在每个输入向量上增加噪音来工作,不过不同的输入向量有不同的成分。这很像dropout,不过他是针对输入而不是针对隐藏单元。这个DAE仍然需要重构被设置成0的输入.所以他没法简单的复制她的输入。使用浅层AE的一个危险在于如果你给他足够的隐藏单元,它也许只复制每个像素到一个隐藏单元,然后从这个隐藏单元中重构这个像素。一个DAE明显没法做这样的事情,所以他使用隐藏单元来抓取输入之间的相关性,所以他可以使用一些输入的值来帮助重构那些被0出的输入。

    如果我们使用堆叠DAE,预训练就是非常有效的。在一些情况下RBM仍然更好,不过在大部分情况下DAE却更有效。评估使用DAE来预训练是更简单的,因为我们可以轻松的计算目标函数的值。当我们使用CD来预训练一个RBM,我们没法计算我们试图最小化的真正的目标函数的值,所以我们通常只使用平方重构误差,这实际上不是什么最小化。在DAE中,我们可以打印出我们试图最小化的值,而且这非常有帮助。一个DAE的缺点是它缺少可RBM一样很好的可变约束。不过这只是理论部分,因为他只会在当RBM用最大似然来学习的时候适用。


    另一种AE就是搜索AE,这也是Montreal小组提出的。它work的方式是我们试图让隐藏激活值尽可能的对输入迟钝(就是不敏感)。当然隐藏单元不能只忽略输入,因为他们需要重构他们。达到不敏感的方法就是通过惩罚的每个隐藏单元关于每个输入的平方梯度。所以我们试图让每个隐藏当我们改变一个输入值的时候不会改变太多。CAE同样可以很好的用在预训练。他们的编码倾向于有这样的特性,在他们的敏感范围内只有很小隐藏单元的子集。对于空间的不同部分上,他是一个不同的自己,所以这个激活的集合的行为就像是一个稀疏编码。其他的隐藏单元是未饱和,也还是不敏感的。RBM实际上也有着一个非常相似的行为。在他们被训练之后,许多的隐藏单元已经饱和,而且未饱和的部分的工作的集合将会不同于不同的训练样本。


    这里进行总结当前有关预训练的观点。现在有许多非常不同的方法来做逐层预训练来发掘好的特征。当我们的数据集没有很多的标签的时候,这种在你使用标签之前的发掘特征的方法是对于后续的判别式微调来说非常有帮助的。它在没有使用标签中的信息的时候发掘标签,然后标签中的信息用来微调类之间的决策超平面。当我们有许多无标签数据的时候,它特别的有用,所以这个预训练可以是在使用许多数据的基础上一个非常好的发掘有趣的特征的工作。对于有着超多标签数据的情况下,初始化权重可以用于有监督学习,通过使用无监督预训练就不是那么必须了,即使当这个网络很深的时候。预训练是首要的用于初始化DNN的权重的好方法,不过现在我们有许多其他的方法了。然而,如果我们有许多标签,如果我们让网络变得更大,我们再次需要预训练。所以一个Hinton与google的人们常用的观点就是,他们得到了许多许多的有标签数据,所以我们根本不需要正则化方法,我们的网络完全不会过拟合,因为我们有这么多的数据。不过一个反对的观点是,这是因为你使用的网络太小了,你应该在更多更多的计算机上使用很大很大的网络。然后你会开始再次过拟合,你会需要这些正则化的,例如dropout和预训练。如果你要问那个regime存在于大脑中,大脑很明显对于这些数据来说有着巨多的参数,所以对于大脑来说,至少正则化是非常重要的。


  • 相关阅读:
    获取网站IP地址(Linux,C)
    linux_c_udp_example
    linux_c_tcp_example
    golang-sort
    docker_jenkins
    依赖抽象,而不要依赖具体实现
    网络杂记
    游戏开发中遇到的问题
    随手杂记
    go多态
  • 原文地址:https://www.cnblogs.com/shouhuxianjian/p/4529167.html
Copyright © 2020-2023  润新知