前言
[机器学习] UFLDL笔记系列是以我学习UFLDL Tutorial(Andrew Ng老师主讲)时的笔记资料加以整理推出的,内容以无监督特征学习和深度学习为主,同时也参考了大量网上的相关资料。
本文的理论部分主要整理自UFLDL的“Autoencoders and Sparsity”章节和一些经典教材,同时也参考了网上的一些经典博客,包含了Autoencoders和Sparsity的一些基本概念、应用场景和推导,供读者参考。
文章小节安排如下:
1)自编码器(autoencoder)的基本原理
2)基于Autoencoder的数据压缩表示
3)基于Autoencoder的数据稀疏表示
4)Autoencoder的可视化
5)参考资料
一、自编码器(autoencoder)的基本原理
1.1 基本概念
自编码器是一种无监督学习算法,它采用神经网络的形式,令目标值等于输入值,利用反向传播算法学习数据内在的结构。因此自编码器也可以称作是自编码神经网络(autoencoder neural network),自动编码体现在哪里?体现在它无需标签,利用数据本身就可以学习出数据内在的有趣结构。
1.2 发展历史
Autoencoders were first introduced in the 1980s by Hinton and the PDP group (Rumelhart et al., 1986 [18]) to address the problem of backpropagation without a teacher, by using the input data as the teacher.
更多的关于Autoencoder的发展历史可以参考论文:Baldi P, Guyon G, Dror V, et al. Autoencoders, Unsupervised Learning, and Deep Architectures Editor: I[J]. Journal of Machine Learning Research, 2012.
1.3 网络结构
UFLDL给出的Autoencoder神经网络结构如下:
但确切的说,Autoencoder指的是上图中第一个权重矩阵,第二个权重矩阵是解码器。
1.4 学习目标
Autoencoder尝试学习一个恒等函数:
换句话说,它尝试逼近一个恒等函数,从而使得输出接近于输入,
恒等函数虽然看上去没有学习的意义,但是当在自编码神经网络加入某些限制,比如限定隐藏神经元的数量,就可以从输入数据中发现一些有趣的结构。
二、基于Autoencoder的数据压缩表示
2.1 如何利用Autoencoder学习数据的压缩表示
假设Autoencoder的输入是100维的数据,其中隐层L2的神经元数量是50,输出层是100维。此时由于只有50个隐藏神经元,也就相当于迫使Autoencoder去学习输入数据的压缩表示,即,它必须从隐层L2的50维激励值向量中重构出100维的输入数据。
当然这种学习是有前提的, 如果输入的数据中各项是完全随机的,也就是每一项都是跟其它项完全无关的独立同分布高斯随机变量,那么压缩表示将会非常难以学习。但如果输入的数据中某些项是彼此相关的,那么Autoencoder就可以发现这一相关性,也就可以学习到压缩表示。事实上,Autoencoder通常可以学习出一个跟主成分分析(PCA)结果非常相似的输入数据的低维表示。
举例来说,
设现在利用4bit来表示4个数字,希望可以进行压缩至2bit来表示,可通过训练得到如下压缩表示:
(0,0,0,1) ->(0.99,0.09) -> (0.06,0.00,0.01,0.91)
(0,0,1,0) ->(0.85,0.99) -> (0.00,0.07,0.90,0.07)
(0,1,0,0) ->(0.01,0.67) -> (0.06,0.87,0.11,0.00)
(1,0,0,0) ->(0.12,0.00) -> (0.89,0.10,0.00,0.02)
input_layer hidden_layer output_layer
观察hidden层的编码可以发现下面对应关系:
(0.99,0.09) 1,0
(0.85,0.99) 1,1
(0.01,0.67) 0,1
(0.12,0.00) 0,0
2.2 代价函数
用于数据压缩表示的Autoencoder的代价函数如下:
从形式上看十分简单,第一项使代价项,第二项是正则项。
2.3 数据预处理
这里Autoencoder中激励函数选择的是Sigmoid函数,而Sigmoid函数的输出在0-1之间,因此为了满足Autoencoder的学习目标,数据在输入网络之前,需要对各项进行归一化操作,例如白化操作。
2.4 Autoencoder与PCA
Autoencoder用于压缩表示时与PCA类似,都是要找到可以代表原始信息的主要成分(捕捉可以代表输入数据的最重要的因素),事实上Autoencoder通常可以学习出一个跟PCA结果非常相似的数据低维表示。只是PCA是线性的,而Autoencoder因为有Sigmoid函数,所以是非线性的降维。
三、基于Autoencoder的数据稀疏表示
3.1 如何利用Autoencoder学习数据的稀疏表示
前面压缩表示例子是基于隐藏神经元数量小于输入数据的维度,如果隐藏神经元的数量大于输入数据的维度,我们可以通过给Auto encoder施加稀疏性限制来学习输入数据的稀疏表示。
补充:什么是稀疏性?
这里用稀疏特征的特点来解释稀疏性,如果说一个特征是稀疏的,那么这个特征向量里面有很多项都是0,而非零的项远小于向量的维度。说白了,稀疏特征就是0比较多而已。
接触机器学习的同学应该都听过稀疏表示,高维数据的稀疏表示是近年来机器学习和计算机视觉领域的研究热点之一。那么稀疏表示的优越性在哪里呢?其实需要说明的是,讨论稀疏表示的优越性之前需要明确应用场景(没有一种理论是万能的),稀疏表示对于大多数的inverse problem一般都具有良好的表现,例如图像,音频,视频等等自然信号,因为这些信号具有很好的可稀疏性。
在Machine Learning,Signal/Image Processing等众多领域,很多inverse problem都是不适定/病态的(under-determined, ill-posed)。为了能获得比较好的解,人们需要x的先验知识。而稀疏性便是众多先验知识中,最为主要的一种。这种性质使得不适定的问题变得适定(well-posed),进而获得“好的解”成为可能。
3.2 稀疏性限制
如果当神经元的输出接近于1的时候认为它被激活,而输出接近于0的时候认为它被抑制,那么使得神经元大部分的时间都是被抑制的限制则被称作稀疏性限制。这里假设神经元的激活函数是sigmoid函数,如果使用tanh作为激活函数,则当神经元输出为-1的时候认为神经元是被抑制的。
那么如何在Autoencoder中加入稀疏性限制呢?
首先我们定义隐藏神经元 j 的平均激活度:
接着我们对这个平均激活度进行限制,
其中, ρ 是 稀疏性参数(sparsity parameter),通常是一个接近于0的较小的值,该等式的目的就是要让隐藏神经元 j 的平均活跃度接近 0,也就是隐藏神经元 j 对于每个训练样本的活跃度都必须接近于0。
为了实现这一限制,我们可以在目标函数中加入一个稀疏惩罚项(sparse penalty term),这个惩罚项将惩罚那些使上面式子显著不等的情况(即神经元的平均激活度与稀疏性参数值显著不同),从而使隐藏神经元的平均激活度保持在较小范围内。
稀疏惩罚项的具体形式有很多种合理的选择,在这里选择基于相对熵(KL divergence)的形式:
其中,
这是一个以 ρ 为均值和一个以 ρ ^ j 为均值的两个伯努利随机变量之间的相对熵。相对熵是一种标准的用来测量两个分布之间差异的方法。
3.3 代价函数
Sparse Autoencoder的代价函数如下:
在形式上,Sparse Autoencoder的代价函数在Autoencoder代价函数的基础上加上了稀疏惩罚项,在反向传播求偏导数的时候要注意数学推导上的更新。
3.4 KL divergence
在概率论或信息论中,KL散度( Kullback–Leibler divergence),又称相对熵(relative entropy),信息散度(information divergence),信息增益(information gain),是描述两个概率分布P和Q差异的一种方法(P和Q差别的非对称性的度量)。它是非对称的,这意味着D(P||Q) ≠ D(Q||P)。特别的,在信息论中,D(P||Q)表示当用概率分布Q来拟合真实分布P时,产生的信息损耗,其中P表示真实分布,Q表示P的拟合分布。
有人将KL散度称为KL距离,但事实上,KL散度并不满足距离的概念,原因在于:
1)KL散度不是对称的;
2)KL散度不满足三角不等式。
四、Autoencoder的可视化
4.1 可视化的是什么
训练出的Autoencoder其实就是第一个权重矩阵,我们可视化的是函数:
确切的说是可视化这个函数的参数W(W中每一组参数对应一幅图像),如下:
从可视化的结果可以看出, 不同的隐藏单元学会了在图像的不同位置和方向进行边缘检测。
4.2 局部模式检测器
很多人会困惑为什么可视化以后是这样的结果,因此这里有几点需要明确:
第一,训练Autoencoder时候的训练数据是什么?
我们拿到的数据集是数字灰度图像,
但我们 训练Autoencoder用的图像是在这些数字图像中随机采样出来的10x10的patch。这里的Autoencoder是一个全链接网络,所以学习出的是全局特征(也就是对图像整体做检测)。但由于训练时候采用的是从原始数字图像中随机采样的10x10的patch,所以给人感觉好像是学习出了局部特征。
第二,为何可视化后的图像看起来像是数字图像中的局部边缘?
事实上这些图像就是原始数字图像中的局部边缘,我们训练出的Autoencoder具备了边缘检测器的能力,隐藏层的每一个神经元,都是一个边缘检测器,而神经元激活的过程,就是边缘检测的过程。
有些同学不理解为什么 神经网络中的神经元可以作为局部模式检测器,越深层的神经元越能检测复杂的局部模式,这其实就是神经网络的性质。我们知道,神经网络可以看作是多层感知机(perceptron),每一个隐层神经元都可以看作是一个感知机单元。而所谓 感知,本质上就是一个模板匹配的过程,如果我们利用原始图像数据训练一个线性分类器,对该分类器进行可视化,可以看到可视化的图像也就是分类对象的抽象描述。
分类器:
可视化分类器:
注意看这里面的car和truck,是不是非常像一辆车。而这里的hourse,看起来是一匹双头马,这是因为训练数据中有些马头是朝左,有些是朝右……
参考资料
UFLDL-Autoencoders and Sparsity
http://ufldl.stanford.edu/wiki/index.php/Autoencoders_and_Sparsity
Visualizing a Trained Autoencoder
http://ufldl.stanford.edu/wiki/index.php/Visualizing_a_Trained_Autoencoder
CS231n-Linear Classification
http://cs231n.github.io/linear-classify/
什么是稀疏特征(Sparse Features)?
https://www.zhihu.com/question/31951092?sort=created
稀疏表达的意义在于?为什么稀疏表达得到广泛的应用?
https://www.zhihu.com/question/26602796/answer/33457780
KL Divergence KL散度
http://blog.csdn.net/gao1440156051/article/details/44162269