栈式自编码算法

From Ufldl

Jump to: navigation, search
(Discussion)
Line 1: Line 1:
 +
==概述==
 +
 +
逐层贪婪训练法依次训练网络的每一层,进而预训练整个深度神经网络。在本节中,我们将会学习如何将自编码器“栈化”到逐层贪婪训练法中,从而预训练(或者说初始化)深度神经网络的权重。
 +
 +
 +
栈式自编码神经网络是一个由多层稀疏自编码器组成的神经网络,其前一层自编码器的输出作为其后一层自编码器的输入。对于一个 <math>\textstyle n</math> 层栈式自编码神经网络,我们沿用自编码器一章的各种符号,假定用 <math>\textstyle W^{(k, 1)}, W^{(k, 2)}, b^{(k, 1)}, b^{(k, 2)}</math> 表示第 <math>\textstyle k</math> 个自编码器对应的 <math>\textstyle W^{(1)}, W^{(2)}, b^{(1)}, b^{(2)}</math> 参数,那么该栈式自编码神经网络的编码过程就是,按照从前向后的顺序执行每一层自编码器的编码步骤:
 +
 +
<math>
 +
\begin{align}
 +
a^{(l)} = f(z^{(l)}) \\
 +
z^{(l + 1)} = W^{(l, 1)}a^{(l)} + b^{(l, 1)}
 +
\end{align}
 +
</math>
 +
 +
同理,栈式神经网络的解码过程就是,按照从后向前的顺序执行每一层自编码器的解码步骤:
 +
 +
<math>
 +
\begin{align}
 +
a^{(n + l)} = f(z^{(n + l)}) \\
 +
z^{(n + l + 1)} = W^{(n - l, 2)}a^{(n + l)} + b^{(n - l, 2)}
 +
\end{align}
 +
</math>
 +
 +
其中,<math>\textstyle a^{(n)}</math> 是最深层隐藏单元的激活值,其包含了我们感兴趣的信息,这个向量也是对输入值的更高阶的表示。
 +
 +
 +
通过将 <math>\textstyle a^{(n)}</math> 作为softmax分类器的输入特征,可以将栈式自编码神经网络中学到的特征用于分类问题。
 +
 +
 +
==训练==
 +
 +
一种比较好的获取栈式自编码神经网络参数的方法是采用逐层贪婪训练法进行训练。即先利用原始输入来训练网络的第一层,得到其参数 <math>\textstyle W^{(1,1)}, W^{(1,2)}, b^{(1,1)}, b^{(1,2)}</math>;然后网络第一层将原始输入转化成为由隐藏单元激活值组成的向量(假设该向量为A),接着把A作为第二层的输入,继续训练得到第二层的参数 <math>\textstyle W^{(2,1)}, W^{(2,2)}, b^{(2,1)}, b^{(2,2)}</math>;最后,对后面的各层同样采用的策略,即将前层的输出作为下一层输入的方式依次训练。
 +
 +
 +
对于上述训练方式,在训练每一层参数的时候,会固定其它各层参数保持不变。所以,如果想得到更好的结果,在上述预训练过程完成之后,可以通过反向传播算法同时调整所有层的参数以改善结果,这个过程一般被称作“微调(fine-tuning)”。
 +
 +
 +
实际上,使用逐层贪婪训练方法将参数训练到快要收敛时,应该使用微调。反之,如果直接在随机化的初始权重上使用微调,那么会得到不好的结果,因为参数会收敛到局部最优。
 +
 +
 +
如果你只对以分类为目的的微调感兴趣,那么惯用的做法是丢掉栈式自编码网络的“解码”层,直接把最后一个隐藏层的 <math>\textstyle a^{(n)}</math> 作为特征输入到softmax分类器进行分类,这样,分类器(softmax)的分类错误的梯度值就可以直接反向传播给编码层了。
 +
 +
 +
==具体实例==
 +
 +
让我们来看个具体的例子,假设你想要训练一个包含两个隐含层的栈式自编码网络,用来进行MNIST手写数字分类(这将会是你的下一个练习)。
 +
首先,你需要用原始输入 <math>\textstyle x^{(k)}</math> 训练第一个自编码器,它能够学习得到原始输入的一阶特征表示<math>\textstyle h^{(1)(k)}</math>(如下图所示)。
 +
 +
 +
[[File:Stacked_SparseAE_Features1.png|400px]]
 +
 +
接着,你需要把原始数据输入到上述训练好的稀疏自编码器中,对于每一个输入<math>\textstyle x^{(k)}</math>,都可以得到它对应的一阶特征表示<math>\textstyle h^{(1)(k)}</math>。然后你再用这些一阶特征作为另一个稀疏自编码器的输入,使用它们来学习二阶特征 <math>\textstyle h^{(2)(k)}</math>。(如下图所示)
 +
 +
[[File:Stacked_SparseAE_Features2.png|400px]]
 +
 +
 +
上图把一阶特征输入到第二层稀疏自编码器中,得到每个<math>\textstyle h^{(1)(k)}</math>对应的二阶特征激活值 <math>\textstyle h^{(2)(k)}</math>。接下来,你可以把这些二阶特征作为softmax分类器的输入,训练得到一个将二阶特征映射到数字标签的模型。
 +
 +
[[File:Stacked_Softmax_Classifier.png|400px]]
 +
 +
 +
如下图所示,最终,你可以将这三层结合起来构建一个包含两个隐藏层和一个最终softmax分类器层的栈式自编码网络,这个网络能够如你所愿地对MNIST数字进行分类。
 +
 +
[[File:Stacked_Combined.png|500px]]
 +
 +
 +
==讨论==
 +
 +
栈式自编码神经网络具有强大的表达能力及深度神经网络的所有优点。
 +
 +
更进一步,它通常能够获取到输入的“层次型分组”或者“部分-整体分解”结构。为了弄清这一点,回顾一下,自编码器倾向于学习得到能更好地表示输入数据的特征。因此,栈式自编码神经网络的第一层会学习得到原始输入的一阶特征(比如图片里的边缘),第二层会学习得到二阶特征,该特征对应一阶特征里包含的一些模式(比如在构成轮廓或者角点时,什么样的边缘会共现)。栈式自编码神经网络的更高层还会学到更高阶的特征。
 +
 +
 +
举个例子,如果网络的输入数据是图像,网络的第一层会学习如何去识别边,第二层一般会学习如何去组合边,从而构成轮廓、角等。更高层会学习如何去组合更形象且有意义的特征。例如,如果输入集合包含人脸图像,更高层会学习识别和组合眼睛、鼻子、嘴等人脸器官。
 +
 +
 +
==中英对照==
 +
 +
自编码器(Autoencoder)
 +
 +
预训练(PreTrain)
 +
 +
栈式自编码神经网络(stacked autoencoder)
 +
 +
微调(fine-tuning)
 +
 +
原始输入(raw inputs)
 +
 +
层次型分组(hierarchical grouping)
 +
 +
部分-整体分解(part-whole decomposition)
 +
 +
一阶特征(first-order features)
 +
 +
二阶特征(second-order features)
 +
 +
更高阶特征(higher-order features)
 +
 +
 +
 +
初译@小猴机器人
初译@小猴机器人
一审@邓亚峰-人脸识别
一审@邓亚峰-人脸识别

Revision as of 09:38, 30 March 2013

Personal tools