首页 > 代码库 > [深度学习]受限玻尔兹曼机生成手写数字训练样本分析

[深度学习]受限玻尔兹曼机生成手写数字训练样本分析

基于能量的模型(EBM)
基于能量的模型将每一个我们感兴趣的变量构造联系到一个标量能量上. 学习就是修改能量方程从而使得它的外形有我们需要的特点. 举例来说, 我们希望的是: 期望构造的能量低. 基于能量的概率性模型定义了一个概率分布, 它是由能量方程决定的:
p(x) = \frac {e^{-E(x)}} {Z}.
归一化因子Z被称为配分函数, 类比于物理系统.
基于能量的模型可以通过SGD(随机梯度下降)算法基于数据的负值对数相似性(NLL)学习得到. 对于对数回归我们首先定义了对数相似性, 之后是损耗函数, 即 负值对数相似性(NLL).
使用随机梯度下降, 其中是模型的参数(权值, 偏置等)
 

有隐层单元的EBM
在许多实例中, 我们并不能观测到样本x的所有特征, 或者我们想要引入一些并非观测得到的变量来增加模型的区分度. 因此我们定义一个观察项x和一个隐藏项h
这种情况下, 为了将此式映射到近似等式(1)上, 我们引入自由能量的记号(取自物理), 如下定义:
从而(2)式可以改写为
[此处Sigma的x上应有波浪号, 表示所有x]
从而数据的负值对数相似性(NLL)梯度有一个特别有趣的形式:
[第一项为分子偏导, 第二项为分母偏导, 注意d exp(-F(x))/ d = exp(-F(x)) * d(-F(x))/d ]
注意到上述梯度包含了两部分, 分别是正向和负向分量. 
这两部分并不和它们在等式中的符号对应, 但是反映了它们对于概率密度的影响.
第一部分增加了训练数据的概率(通过减少对应的自由能量), 第二部分则降低了模型产生的样本概率.
通常很难从分析这些梯度, 因为它涉及了计算. 这完全和从输入x的所有可能结构中获得的期望相同(在模型给定的分布P的条件下).
 
解决这个问题的第一步就是使用一个固定数量的模型样本来估计期望. 用于估计负向分量梯度的样本被称为负粒子, 使用表示. 梯度可以表示为:
理论上我们希望中的能够按照P来采样(比如做蒙特卡洛). 我们几乎已经得到了用于训练EBM的一个实用的, 随机算法. 唯一缺失的要素是如何提取这些负粒子. 马尔科夫链蒙特卡洛方法对于RBM模型(EBM的一种特殊情况)非常合适.

受限玻尔兹曼机(RBM)
玻尔兹曼机(BMs)是对数线性马尔科夫随机域的一种特殊形式, 它的能量函数对于自由参数是线性的. 为了能够使得它们能够表达复杂的分布(比如从受限变参设置到一个非变参的情况), 我们假设某些变量从未被观察到(隐藏的). 通过构造更多的隐含变量(隐含单元), 我们可以增加BM模型的容量. 受限BM进一步限制了BM, 它没有可见-可见和隐藏-隐藏的连接. RBM的图示如下:
能量方程E(v, h)定义为:
其中W代表连接隐藏和可见单元的权重, b,c则是可见和隐藏层的偏置.
从而可以得到下面的自由能量公式:
因为RBM的特殊结构, 可见和隐藏单元是相互独立的, 使用这个特性我们得到:
二进制单元的RBM
使用二进制单元的一般情况下(v_jand h_i \in \{0,1\}), 我们可以从式(6)和(2)中得到一个概率版本的一般神经元的激活函数:
RBM的自由能量则简化为:
使用二进制单元更新等式
结合等式(5)和(9), 我们可以得到下列二进制单元RBM的对数相似性梯度:
我们在Theano中使用T.grad对式(4)进行处理得到此式而不是直接使用.

RBM的采样
p(x)的采样可以通过运行一个马尔科夫链来收敛得到, 使用Gibbs采样作为过渡操作.
  • N个随机变量的Gibbs采样通过一系列形如的N个子采样步骤(sub-step)实现, 其中包含S中除了的其他N-1个随机变量.
对于RBM, S由可见和隐藏神经元集合组成, 但是因为它们是条件独立的, 所以可以进行Gibbs块采样(block Gibbs sample). 在这种条件下, 可见神经元在隐藏神经元值给定同时进行采样. 相似的, 隐藏神经元也在可见神经元值给定同时进行采样. 马尔科夫链中的一步(step)操作如下:神经
sigm(x) = sigmoid(x) = exp(-x)/(1+exp(-x)) 
其中代表马尔科夫链的第n步的所有隐藏神经元集合. 它的意义是, 按照概率随机设置为1/0, 相似的则按照概率随机设置为1/0. 如下图:
, 采样对就能保证为p(v,h)的精确采样.
理论上, 学习过程中每次更新参数都要求运行一次这个链直到收敛. 毫无疑问这样做成本太高. 因此, 很多算法设计出来, 用于有效地在学习过程中对p(v,h)进行采样.

对比差异算法(contrastive divergence, CD-k)
CD算法使用2个技巧来加速采样过程:
  • 因为最终希望(数据的真实分布), 我们使用一个训练样本来初始化马尔科夫链(即使用一个更接近于p的分布, 从而使得链已经接近于收敛到最终分布p)
  • CD并不等待链收敛, 采样点集在第k步Gibbs采样结束后就获得了. 实际应用中, k = 1效果已经非常好.

持续CD(PCD)
持续CD使用了另一种p(v,h)采样的估计. 它依赖于一个单一马尔科夫链, 该链有一个不变的状态(即并不对于每一个观测样本都重启该链). 对于每一次参数更新, 我们通过简单的运行链k步来提取新的样本. 链的状态被保存, 用于之后的更新.
基本思想是如果参数变化相对链的混合状态足够小, 马尔科夫链就能够"跟上"模型的变化.

实现
我们构造了RBM类. 网络的参数可以通过构造器或者是输入参数初始化.
这样RBM可以用作构造一个深度网络, 在这种情况下, 权值矩阵和隐层偏置是和一个MLP网络的sigmoidal层共享的.
  1. 写好构造函数, 对一些参数的默认值进行设置, 并完成一系列的初始化
    • 权值初始化成均匀分布
    • 偏置初始化成0
  2. 定义与(7)(8)两式相关的符号图.
    • propup()/propdown()
      • 给定V/H层状态, 返回V/H层[激励函数, 均值/概率]
      • 这两个方法供给下面的两个方法调用
    • sample_h_given_v()/sample_v_given_h()
      • 给定V/H层神经元状态, 返回H/V层[激励函数, 概率/均值, 采样点]
    • 我们可以使用这4个函数来定义Gibbs采样的一个符号图.
      • gibbs_vhv定义了从可见神经元开始的一步Gibbs采样, 这在RBM采样中非常有用
      • gibbs_hvh则相反, 这在CD和PCD更新中将会很有用
      • 返回V,H/H,V层[激励函数, 均值, 采样点]