Deep Learning的学习实践 4 -- DBN

时间:2024-05-23 11:23:16

首先,讨论一下Deep Learning的一些起源文章,在2006年以前,深度的神经网络一直没有很好地训练方法,有一些问题(比如前文所说的“梯度消亡”的问题),结果不好。2006年,发了3篇重要的初创文章,改变了这一局面,并开始了Deep Learning这个领域的大发展。这3篇文章是:

Hinton,G. E., Osindero, S. and Teh, Y.,Afast learning algorithm for deep belief nets.Neural Computation 18:1527-1554, 2006

Yoshua Bengio, Pascal Lamblin, Dan Popovici and HugoLarochelle,Greedy LayerWise Training of DeepNetworks, in J. Platt et al. (Eds), Advances in Neural Information Processing Systems 19 (NIPS 2006), pp. 153-160, MIT Press, 2007

Marc’Aurelio Ranzato, Christopher Poultney, Sumit Chopra and YannLeCun Efficient Learning of SparseRepresentations with an Energy-Based Model, in J. Platt et al. (Eds), Advances in Neural InformationProcessing Systems (NIPS 2006), MIT Press, 2007

(Google上搜蓝色标题的3paper可以查到原文。)

首先被研究出来的是DBNDeepBelief Networks)模型(基于RBM模型),这是Hinton开创的,就是上面第1篇论文。然后Bengio详细分析了DBN,并提出了一种训练效率比较DBN要高,更加generalization,结果与DBN近似的模型:auto-encoders,就是上面第2篇论文。然后YannLeCun等人进一步提出Sparse auto-encoders 模型,就是上面第3篇论文。我觉得分层训练,Pretraining是整个技术的核心突破。

另外,Bengio2003年发表了一篇论文“ANeural Probabilistic Language Model”,提出了一种基于神经网络的语言模型用于NLP(自然语言处理),这是很重要的论文,后面被NLP领域广泛引用,包括Googleword2vec,包括MT(机器翻译)领域的一些文章。这些模型也是Deep Learning领域的模型。

还有,Yann LeCun1998年做的CNNConvolutionalneural networks卷积神经网络),(CNN最早是1980 Kunihiko Fukushima提出来的),这个模型在图像处理领域应用非常广泛,特别是在银行领域的手写数字识别,效果很好。这也是典型的Deep learning模型中的一种,后面详细说明。

 

下面介绍一下DBN相关的模型。DBN的基础是RBM模型,先说一下RBM模型(受限波尔兹满机)。

波尔兹曼分布是一种能量分布函数,Wiki解释如下:统计力学的领域。任何(宏观)物理系统的温度都是组成该系统的分子原子运动的结果。这些粒子有一个不同速度的范围,而任何单个粒子的速度都因与其它粒子的碰撞而不断变化。然而,对于大量粒子来说,处于一个特定的速度范围的粒子所占的比例却几乎不变,如果系统处于或接近处于平衡。麦克斯韦-玻尔兹曼分布具体说明了这个比例,对于任何速度范围,作为系统的温度的函数。示意如下图:Deep Learning的学习实践 4 -- DBN

为什么要采用波尔兹满分布(Boltzmann),是我比较疑惑的问题,一个前辈告诉我,因为波尔兹满分布是自然界很普遍的现象,但我的疑惑还没有完全解开。

BM(波尔兹满机)是基于统计力学波尔兹曼分布的一种2层网络模型(分为可见层和隐藏层),是HintonSejnowski1986年提出的,后来Smolensky提出了简化版的RBM(受限波尔兹曼机),如下图:Deep Learning的学习实践 4 -- DBN

RBM的层内无连接,层间全连接是BM的一种简化模型,主要为了求解方便。而且,RBM具有很好的性质,在给定可见层单元状态,各隐单元的**条件独立,反之,在给定隐单元状态时,可见层单元的**也是条件独立,而且通过Gibbs采样可以得到服从RBM表示的随机样本,(Roux和Bengio从理论上证明,只要隐单元数据足够多,RBM能够拟合任意离散分布。)。另外,经过简化后的RBM模型就是一个条件随机场模型(无向图模型),如下图:Deep Learning的学习实践 4 -- DBN

Gibbs采样,使用马尔科夫链蒙特卡洛方法,可以模拟RBM模型的样本分布,即用一个训练样本初始化可见层状态V0 ,交替进行如下采样:Deep Learning的学习实践 4 -- DBN

  不过,Gibbs采样需要很多采样步数,特别是特征维度高时计算量很大,Hinton2002年提出CD算法(Contrastive Divergence 对比散度算法),简单说,Hinton指出,用一个训练样本初始化可见层状态V0后,只需要KGibbs采样就可以得到足够好的近似值,通常K=1 CD算法是RBM的快速学习方法,对RBM模型发展的起了重要的推动作用。

此外,RBM还有挺多参数,比如学习率,动量学习率,权衰减,隐单元个数,Wb的初始值等。附件的文章《受限波尔兹曼机简介》有对该模型和算法实现过程的详细说明。

 

RBM的隐层h,其实是对可见层v进行重构,所以也是对样本数据的特征自学习,或者说是Representation Learning,示意如下图:

 Deep Learning的学习实践 4 -- DBN

多层的RBM叠加在一起,就组成了DBN的深度网络,如下图所示(来自Hinton的论文):Deep Learning的学习实践 4 -- DBN

 

同样,DBN的训练,也分为Pretraining,和fineTurningBP算法)两个步骤,与AutoEncoder类似。我感觉DBN更多地考虑了特征之间的相互依赖性(马尔科夫链),在各个维度的特征是不同类型的数据时(如离网预测的数据),效果会更好,这是与AutoEncoder不同的地方,AutoEncoder更适合所有维度的特征是同一类型的数据。

 

 

TheanoDBN代码要点说明:

 # construct the RBM class

   rbm = RBM(input=x, n_visible=28 * 28,

             n_hidden=n_hidden, numpy_rng=rng, theano_rng=theano_rng)

默认参数:

deftest_rbm(learning_rate=0.1, training_epochs=15,

            dataset='mnist.pkl.gz', batch_size=20,

            n_chains=20, n_samples=10, output_folder='rbm_plots',

            n_hidden=500):

运行参数:

test_rbm(training_epochs=3,n_hidden=160)

经过0,1,2三次迭代后,分别得到的0~9的手写数字图像特征:Deep Learning的学习实践 4 -- DBN   Deep Learning的学习实践 4 -- DBN   Deep Learning的学习实践 4 -- DBN

DBN基于离网预测的数据进行测试:

   # Construct an RBM that shared weights with this layer

           rbm_layer = RBM(numpy_rng=numpy_rng,

                           theano_rng=theano_rng,

                           input=layer_input,

                           n_visible=input_size,

                           n_hidden=hidden_layers_sizes[i],

                           W=sigmoid_layer.W,    #权值与隐层一致,实际上是一层

                           hbias=sigmoid_layer.b)

           self.rbm_layers.append(rbm_layer)

 

       # We now need to add a logistic layer on top of the MLP  隐层最后一层的输出是LR的输入

       self.logLayer = LogisticRegression(

           input=self.sigmoid_layers[-1].output,

           n_in=hidden_layers_sizes[-1],

           n_out=n_outs)

       self.params.extend(self.logLayer.params)

 

#这里返回cost最后的LR分类器的权值W,b,最后一个隐层的权值W,b

       train_fn = theano.function(inputs=[index],

             outputs=[self.finetune_cost, self.logLayer.W, self.logLayer.b,self.sigmoid_layers[self.n_layers-1].W,self.sigmoid_layers[self.n_layers-1].b],

             updates=updates,

             givens={self.x: train_set_x[index * batch_size:

                                         (index + 1) * batch_size],

                     self.y: train_set_y[index * batch_size:

                                         (index + 1) * batch_size]})

 

#construct the Deep Belief Network

  dbn = DBN(numpy_rng=numpy_rng, n_ins=dimension, #输入层,输入个数为特征维数

             hidden_layers_sizes=[10, 10, 10],     #3个隐层,每层10个神经元

             n_outs=2)   #输出层,2分类softMax

 

#得到模型参数

minibatch_avg_cost, LR_W, LR_b,lastHiddenlyer_W, lastHiddenlyer_b = train_fn(minibatch_index)

 

# 模型训练参数(k是动量学习率,不能用0.5):

test_DBN(finetune_lr=0.1,pretraining_epochs=10, pretrain_lr=0.01, k=1, training_epochs=10,batch_size=500) 

 

调整这些训练参数测试,对DBN模型训练很重要,不同的DBN结构(层数,神经元数等),不同的参数组合,训练结果会有很大区别。所以,不同的人使用DBN,可能会做出区别很大的结果。Deep Learning的调参训练,也是个很高深的学问。我曾经问过Hinton的学生,有没有什么rule可以用于设计DNN的结构,得到的答案是要看数据的情况去设计。