[机器学习] UFLDL笔记 - Sparse Coding(稀疏编码)

Posted WangBo_NLPR

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[机器学习] UFLDL笔记 - Sparse Coding(稀疏编码)相关的知识,希望对你有一定的参考价值。

前言

  [机器学习] UFLDL笔记系列是以我学习UFLDL Tutorial(Andrew Ng老师主讲)时的笔记资料加以整理推出的,内容以无监督特征学习和深度学习为主,同时也参考了大量网上的相关资料。

  本文的理论部分主要整理自UFLDL的“Sparse Coding”章节和一些经典教材,同时也参考了网上的一些经典博客,包含了Sparse Coding的一些基本概念、优化方法、数学推导和应用场景,供读者参考。

  文章小节安排如下:
  1)Sparse Coding的基本原理
  2)Sparse Coding的训练与应用
  3)Sparse Coding的Autoencoder Interpretation
  4)Topographic Sparse Coding
  5)参考资料
  
  

一、Sparse Coding的基本原理

1.1 基本概念

  稀疏编码算法是一种无监督学习方法,它用于寻找一组“超完备基(over-complete bases)”来更高效地表示样本数据。换句话收,稀疏编码算法的目的就是找到一组基向量Φϕ,使得我们能将输入向量 x 表示为这些基向量的线性组合:
  


  虽然形如主成分分析技术(PCA)能使我们方便地找到一组“完备基向量(a complete set of basis vectors)”,但是这里我们想要做的是找到一组“超完备基向量(an over-complete set of basis vectors)”来表示输入向量。也就是说基向量的数量要大于输入向量的维度。
   超完备基的好处是它们能更有效地找出隐含在输入数据内部的结构与模式(capture structures and patterns inherent in the input data)。然而,对于超完备基来说,系数 ai 不再由输入向量唯一确定。因此,在稀疏编码算法中,需要另加了一个评判标准“稀疏性(sparsity )”来解决因超完备(over-completeness)而导致的退化(degeneracy)问题。
    

1.2 完备基与超完备基

  回顾一下PCA中如何计算一组完备基向量:
  1)计算协方差矩阵
  


  2)奇异值分解(Singular Value Decomposition)
   [U, S, V] = svd(Σ);
  3)降维or白化

  这里第二部中得到的U就是所求的完备基(complete bases)。
  


  那么什么是超完备基?其实就是在U中再多几列,例如:
  
  
   为什么说:对于超完备基来说,系数 ai 不再由输入向量唯一确定?
  根据basis的原理,训练集中任意一个向量都可以唯一表示为完备基向量的线性组合:
  
  
   即系数a向量是唯一的,但对于超完备基来说,系数向量a就不唯一了,这也很好理解,毕竟超完备基中的基向量之间是线性相关的(任意n+1个n维向量必线性相关)。其实就类似于解方程组,k是变量数量,n是方程数量,如果方程较多而变量较少,则解是唯一的,如果方程较少而变量较多,则解是不唯一的。

  因为稀疏编码目的是找到一组超完备基,即 k>n,所以就无法直接通过原始数据得到特征矩阵 U(一组完备基向量),进而也就无法直接得到系数 a,所以我们需要次啊用学习的方式来找到这一组超完备基。
  

1.3 稀疏性(Sparsity)

  这里把“稀疏性(sparsity )”定义为:只有很少的几个非零元素或只有很少的几个远大于零的元素。
  要求系数向量 a 是稀疏的意思就是说:对于一个输入向量的基向量组合,我们只想有尽可能少的几个系数远大于零。
  选择使用具有稀疏性的分量来表示我们的输入数据是有原因的,因为绝大多数的感官数据(sensory data),比如自然图像,可以被表示成少量基本元素(atomic elements)的叠加,在图像中这些基本元素可以是面或者线。同时,比如与初级视觉皮层的类比过程也因此得到了提升。
  关于稀疏性的讨论,可以参考:[机器学习] UFLDL笔记 - Autoencoders and Sparsity(http://blog.csdn.net/walilk/article/details/78168358

二、Sparse Coding的训练与应用

2.1 代价函数

  稀疏编码的代价函数定义如下:  


   第一项可解释为一个“重构项(reconstruction term)”,这一项迫使稀疏编码算法为输入向量提供一个高拟合度的线性表达式;第二项即“稀疏惩罚项(sparsity penalty term)”,它使输入向量的表达式变得“稀疏”,也就是系数向量a变得稀疏。常量 λ 是一个变换量,由它来控制这两项式子的相对重要性。
  虽然“稀疏性”的最直接度量标准是 “L0” 范式:
  
  但这是不可微的,而且通常很难进行优化。在实际中,稀疏代价项 S(.) 的普遍选择是L1 范式代价函数(L1正则化):
  
  或者对数形式:
  
  同时,为了防止ai值过小的问题,我们对Φ的取值也进行了限制:
  
  

2.2 如何利用Sparse Coding提取数据特征?

  简单来说,Sparse Coding是将输入数据重构为一组超完备基向量的线性组合,然后这些基向量前面的系数所构成的向量就是输入数据的新特征。
  一般情况下要求超完备基向量的个数k非常大(远大于输入数据的维度n),因为这样的基向量组合才能更容易的学到输入数据内在的结构和特征。其实在常见的PCA算法中,是可以找到一组基来分输入数据X的,只不过那个基的数目比较小(小于等于输入数据维度),所以可以得到分解后的系数a是可以唯一确定,而在sparse coding中,k太大,比n大很多,其分解系数a不能唯一确定。

  另外,Sparse Coding在实际使用过程中速度很慢,这是因为即使我们在训练阶段已经把输入数据集的超完备基学习到了,在测试阶段时还是要通过凸优化的方法去求得其特征值(即基组合前面的系数值),所以这比一般的前向神经网络速度要慢。
  

2.3 训练(train)

  稀疏编码算法涉及超完备基Φ(字典)和系数向量a的学习,因此训练是由两个独立的优化过程组合起来的。每次迭代分两步:第一个是固定字典Φ,逐个使用训练样本x来优化系数 ai ,第二个是固定系数向量a,一次性处理多个样本对字典Φ进行优化。
  不断迭代,直至收敛,这就可以得到一组能够良好表示训练样本x的超完备基,也就是字典

  关于系数向量a的优化:
  使用 L1 范式作为稀疏惩罚函数,对 a(j)i的学习过程就简化为求解“由 L1 范式正则化的最小二乘法问题”,这个问题函数在域 a(j)i内为凸,已经有很多技术方法来解决这个问题。
  使用对数形式的稀疏惩罚函数,则可以采用基于梯度算法的方法,如共轭梯度法。

  关于字典Φ的优化:
  使用 L2 范式约束来学习基向量,同样可以简化为一个带有二次约束的最小二乘问题,其问题函数在域 Φ 内也为凸。
  

2.4 表示(representation)

  根据前面的的描述,稀疏编码是有一个明显的局限性的,这就是即使已经学习得到一组基向量,如果为了对新的数据样本进行“编码”,我们必须再次执行优化过程来得到所需的系数a。这个意味着在测试中,实现稀疏编码需要高昂的计算成本,尤其是与典型的前馈结构算法相比,例如稀疏自编码器(http://blog.csdn.net/walilk/article/details/78168358)。

  稀疏编码用于表示的形象描述如下:
  


  

三、Sparse Coding的Autoencoder Interpretation

3.1 Sparse Autoencoder VS Sparse Coding

  在Sparse Autoencoder中,我们试着学习得到一组权重参数 W (以及相应的截距 b ),通过这组参数W可以得到输入样本的稀疏特征向量,也就是隐层的激励值向量,由此也就得到了输入样本的稀疏表示;
  


  
   在Sparse Coding中,我们试图直接学习数据的稀疏特征向量,以及与之对应的超完备基(字典)。其实Sparse Coding的学习的也是一种特征映射,目标是将原始训练样本映射成(重构为)稀疏表示形式。

  UFLDL中说“稀疏编码可以看作是稀疏自编码方法的一个变形”,这一点我确实还不太理解。确切地说,在稀疏编码算法中,我们直接利用样本数据 x 进行特征学习,学习一个用于表示样本数据的稀疏特征 s(对应前面说的向量a),和一个将特征s从特征空间转换到样本数据空间的基底 A(对应前面说的超完备基Φ)。
  

3.2 Sparse Coding的代价函数重定义

  基于上面的理解,我们重定义Sparse Coding的代价函数如下:
  


  其中,第一项是重构代价项(reconstruction cost term),第二项是稀疏惩罚项(sparsity penalty term),第三项是权重衰减项(weight decay term)。具体对每一项的构建原因和解释可以查看UFLDL的教程( http://ufldl.stanford.edu/wiki/index.php/Sparse_Coding:_Autoencoder_Interpretation),讲解的很清楚。
  
  

3.3 重构项的理解

  为了理解重构代价项,我们将该代价函数与PCA进行对比。
  矩阵 A 是一组超完备基向量组成的,每一列是一个基向量,向量 s 是稀疏特征向量。这里其实跟PCA中数据近似还原计算的非常类似,PCA的数据近似还原计算如下:
  


  Sparse Coding中的A就对应PCA中的U,s对应x_rot。只不过, Sparse Coding目的是找到一组“超完备基向量”,PCA目的是找到一组“完备基向量”。

  注意,在UFLDL教程中代价函数的重构代价项没有*(1/m),这是不对的,如下:
  


   重构代价项实际上是均方误差,而不是误差平方和。
  参考: http://ufldl.stanford.edu/wiki/index.php/Sparse_Coding:_Autoencoder_Interpretation
  

3.3 权重衰减项的意义

  这里着重讲解一下权重衰减项的意义。
  如果只有前面两项(重构代价项和稀疏惩罚项),那么就存在一个问题:
  如果将系数向量s中各项系数值减到很小,且将字典A中每个基向量的值增加到很大,这样第一项的代价值基本保持不变,而第二项的稀疏惩罚值却会相应变小。也就是说只要将所有系数都减小同时基向量的值增大,那么就能最小化上面的代价函数。在这种情况下,所有的系数a都变得很小,即:它们都大于0但接近于0,而这并不满足我们对系数向量的稀疏性要求:系数向量s中只有少数系数远远大于0,而不是大部分系数都接近于0。
  所以为了防止这种情况发生,我们需要保证字典A中基向量的元素值都不会变得太大,这就是权重衰减项的意义。
  

3.5 Sparse Coding的迭代优化过程

  1. 随机初始化A
  2. 重复以下步骤直至收敛:
    a. 根据上一步给定的A,求解能够最小化J(A,s)的s
    b. 根据上一步得到的s,求解能够最小化J(A,s)的A

  理论上,Sparse Coding通过上述迭代方法求解目标函数的最优化问题最终得到的稀疏特征向量与通过Sparse Autoencoder学习得到的稀疏特征向量是差不多的。
  
 

四、Topographic Sparse Coding

4.1 基本概念  

  首先看一下大脑皮层中的特征秩序,摘录自UFLDL-Topographic Sparse Coding。
  举个例子,视觉特征,如前面所提到的,大脑皮层 V1 区神经元能够按特定的方向对边缘进行检测,同时,这些神经元(在生理上)被组织成超柱(hypercolumns),在超柱中,相邻神经元以相似的方向对边缘进行检测,一个神经元检测水平边缘,其相邻神经元检测到的边缘就稍微偏离水平方向,沿着超柱,神经元就可以检测到与水平方向相差更大的边缘了。
  受该例子的启发,我们希望学习到的特征也具有这样“拓扑秩序(topographically ordered)”的性质。这对于我们要学习的特征意味着什么呢?直观的讲,如果“相邻”的特征是“相似”的,就意味着如果某个特征被激活,那么与之相邻的特征也将随之被激活。
  
  通过Sparse Coding已经可以得到样本数据的稀疏表示。进一步,我们通过分组的方式,来使得学习得到的特征集中各项之间具有某种“秩序(orderly)”。
  

4.2 代价函数

  具体而言,假设我们将特征组织成一个方阵。我们就希望矩阵中相邻的特征(adjacent features)是相似的。实现这一点的方法是将相邻特征按“经过平滑的L1范式惩罚(the smoothed L1 penalty)” 进行分组,如果按 3x3 方阵分组,则是用:
  


  代替:
  
   其分组通常是重合的,例如从第 1 行第 1 列开始的 3x3 区域是一个分组,从第 1 行第 2 列开始的 3x3 区域是另一个分组,以此类推。最终,这样的分组会形成环绕,就好像这个矩阵是个环形曲面,所以每个特征都以同样的次数进行了分组。也就是说,将经过平滑的所有分组的 L1 惩罚值之和代替经过平滑的 L1 惩罚值,得到新的代价函数:
  
  
  进一步,我们将分组的操作通过“分组矩阵V”来完成,分组矩阵 V 的第 r 行标识了哪些特征被分到第 r 组中,即如果第 r 组包含特征 c ,则 Vr,c = 1,示例如下:
  
  通过分组矩阵实现分组使得目标函数的梯度计算更加直观,使用此分组矩阵后目标函数被重写为:
  
  该目标函数能够使用之前部分提到的迭代方法进行求解。
  拓扑稀疏编码得到的特征与稀疏编码得到的类似,只是拓扑稀疏编码得到的特征是以某种方式有“秩序”排列的。
  关于分组后的稀疏惩罚项的对s的梯度推导过程,可以参考:[机器学习] UFLDL笔记 - 反向传播算法(Backpropagation)( http://blog.csdn.net/walilk/article/details/78165557
  
  

五、Sparse Coding的训练注意事项

5.1 实验笔记

  这部分是我在实现Sparse Coding时候的一些实验笔记。
  1)优化算法对结果是有影响的。比如,对于拓扑稀疏编码,优化算法为cg,特征个数为121,小图像块大小为16*16时,cg算法得到的结果比lbfgs算法更好。
  2)patch大小对结果是有影响的。比如,拓扑稀疏编码算法,特征个数为121,采样patch大小为8*8时,如果用lbfgs算法就得不到结果,而用cg算法就可以得到上面的结果。
  3)规律:随着迭代次数的增加,代价函数值应该是越来越小的,如果不是,就永远不会得到正确结果。如果代价函数不是越来越小,可能是优化算法的选择有问题,或者小图像块的选择有问题,具体情况具体分析,有多种原因。当然更本质的原因,还没弄清楚。
  4)训练集中的10张512*512的灰度图像是已经白化后的图像,故它的值不是在[0,1]之间。以前实验的sampleIMAGES函数中要把样本归一化到[0,1]之间的原因在于它们都是输入到稀疏自动编码器,其要求输入数据为[0,1]范围,而本节实验是把数据输入到稀疏编码中,它并不要求数据输入范围为[0,1],同时归一化本身实际上是有误差的(因为它是根据3sigma法则归一化的),所以本节实验修改后的sampleIMAGES函数中,不需要再把随机抽取20000张小图像块归一化到[0,1]范围,即:要把原来sampleIMAGES函数中如下代码注释掉:patches = normalizeData(patches);。实际上这一步非常重要,因为它直接关系到最后是否可以得到要求的结果图。
  

5.2 实验效果

  non-topographic的结果我找不到了……这里贴上UFLDL的:
  


  
  topographic的实验结果如下:
  topographic:迭代200次,patchDim = 16; Method = ‘cg’;
  
  所谓“ordered”,一眼就可以看出来了吧。
  
  

参考资料

Sparse Coding
http://ufldl.stanford.edu/wiki/index.php/Sparse_Coding
Sparse Coding: Autoencoder Interpretation
http://ufldl.stanford.edu/wiki/index.php/Sparse_Coding:_Autoencoder_Interpretation
Exercise:Sparse Coding
http://ufldl.stanford.edu/wiki/index.php/Exercise:Sparse_Coding
Autoencoders and Sparsity
http://ufldl.stanford.edu/wiki/index.php/Autoencoders_and_Sparsity

以上是关于[机器学习] UFLDL笔记 - Sparse Coding(稀疏编码)的主要内容,如果未能解决你的问题,请参考以下文章

[机器学习] UFLDL笔记 - 反向传播算法(Backpropagation)

[机器学习] UFLDL笔记 - 反向传播算法(Backpropagation)

[机器学习] UFLDL笔记 - Autoencoders and Sparsity

[机器学习] UFLDL笔记 - Autoencoders and Sparsity

[机器学习] UFLDL笔记 - PCA and Whitening

[机器学习] UFLDL笔记 - Convolutional Neural Network - 矩阵运算