说起对深度学习的了解,是在今年10月份看了StanfordUniversity的计算机科学家Andrew Y.Ng教授在Google的一个演讲视频开始的,看了之后还以为就是以前所说的artificial neutralnetwork(人工神经网络),这个东西在本世纪初就逐渐越来越少人研究了,特别是在support vectormachine(SVM,支持向量机)以其较强的分类能力和泛化能力出现之后,国内高校更没什么人在搞这个,这从高校的一些课题和基金项目就可以看出来,这种东西怎么又突然有人讲了呢?怀着一丝疑问,我查阅了一些相关的报道,不查不要紧,一查才知道这东西现在是多火。
首先看到的报道是在今年夏季,Google的技术人员JeffDean和Stanford University的Andrew Y.Ng把1.6万台电脑连在一起,使其能够自我训练,对2万个不同物体的1400万张图片进行辨识。尽管准确率较低,只有15.8%,但该系统的表现比之前最先进的系统都要好70%。
再接着,看到了今年10月份在天津的一次计算会议上,微软首席科学家RichardF. Rashid在上面演讲关于语音识别的时候,演示了其使用深度学习技术(他的原话是:deep neuralnetwork,深度神经网络,属于深度学习的一种)来提高语音识别准确率的效果(http://v.youku.com/v_show/id_XNDcyOTU3NDc2.html),相比目前最先进的基于HiddenMarkov Model的技术,其准确率提升了大约30%(If you use that to take it much moredata than had previously been able to be used with the hiddenmarkov models, so that one change that particular break throughincreased recognition rates by approximately thirtypercent)。然而,在7分35秒的时候,我也抑制不住地“哇”起来,原来,那个系统在进行语音识别的同时,还进行了识别,把英文翻译成了中文,不仅如此,它还学习了Richard的发音和腔调,用中文把翻译的结果念了出来,博得现场一片掌声。虽然仔细一看,有些中文还是没有实时翻译过来,发出中文声音也需要在原说话人发音之后大约2秒左右,但这已经是非常之牛,想想国内语音识别的先驱科大讯飞,目前还真是无法望其项背。
这种即将对我们的未来产生巨大改变的技术,到底是一种什么神秘的东西,其中的原理又到底什么,带着这种探索与求知的欲望,我开始利用工作之余的时间进行学习了解。
国内来说,应该是在今年和去年才在开始受到关注,然而,早在2006年,国外就已经开始这方面的深入研究,并取得了一定的阶段性成果,追根溯源,这还是基于神经网络的启发(还好本科时毕业论文就是神经网络用在字符之别,对神经网络还有点基础,当时也整理了一些资料,以后再整理汇总放上来吧)。在2006年前,神经网络尝试训练深度的架构都不是很成功,训练一个深度有监督前馈神经网络趋向于产生坏的结果(也即在训练和测试中误差的收敛性不好),然后将其变浅为1个或2个隐层。2006年,Universityof Toronto的Geoffrey E. Hinton教授(一查他的背景才知道他原来是19世纪数学家GeorgeBoole的玄孙,George Boole在逻辑领域的工作构成了现代数码计算机的基础,难道天分这东西还真是得遗传-_-)在DeepBeliefNetworks(DBN,深度信念网)这方面有了革命性的突破,引发了国外在方面的研究热潮。在其引领之下,有了这三篇重要的论文:
2006年的A fast learning algorithm for deep belief nets .(Hinton, G. E., Osindero, S. and Teh)
2007年的Greedy Layer-Wise Training of DeepNetworks(Yoshua Bengio, Pascal Lamblin, Dan Popovici and HugoLarochelle)
2007年的Efficient Learning of Sparse Representations with anEnergy-Based Model(Marc’Aurelio Ranzato, Christopher Poultney,Sumit Chopra and Yann LeCun)
在这三篇论文中以下主要原理被发现:
1.无监督学习的结果表示被用于(预)训练每一层;
2.在一个时间里的一个层次的无监督训练,接着之前训练的层次。在每一层学习到的结果表示作为下一层的输入;
3.用监督训练来调整所有层(加上一个或者更多的用于产生预测的附加层);
当前,国外在这方面的研究就是三分天下的局面,University ofToronto的Geoffrey E. Hinton与微软合作,Stanford University的Andrew Y.Ng和Google合作,以及New York University的计算机科学家Yann LeCun和RobFergus。国内方面百度的于凯是这方面的先行者;上个月和一个高校老师交流时,提到企鹅也在招人搞这个,据说是在做索引结构方面也能有一个质的飞跃,一篇文章提取特征后就剩一个20维的向量,也还不确定是否真能如此神,另外这个老师还提到可以用来做detection,因为目前adaboost确实是在训练上很花时间,自己之前在家搞了个手表的训练,也花了一周时间,而深度学习在特征选择方面还是挺有优势的,不过之前看Andrew教授的视频,提到未监督学习用在做detection上还是没有什么突破,不知道这里做检测效果会怎样;学术界现在在这块就是在与时间赛跑,谁先跑出个成果谁就是第一个吃螃蟹的(做人脸的山世光也对于凯在这方面的report挺看重)。下面就先附上一些个人觉得比较重要的相关论文,其中部分还未细读,有些因为放在springlink或者sciencedirect上无法下载,待有时间再请人找找后深入学习。
Learning multiple layers ofrepresentation, 2007.
这篇论文,篇幅短小,适合初学者理解DBNs,特别是非数学专业的。
Deep machine learning - a new frontierin artificial intelligence research, 2010.
深度学习的入门材料。
Learning deep architecture for AI,2009.
深度学习的经典论文,可以当作深度学习的学习材料。
To recognize shapes, first learn togenerate images, 2006.
多伦多大学的内部讲义。目前还没找到。
A fast learning algorithm for deepbelief nets, 2006.
Hinton关于DBNs的开山之作,也就是前面提到的引领性的文章。在这篇论文中,作者详细阐述了DBNs的方方面面,论证了其和一组层叠的RBMs的等价性,然后引出DBNs的学习算法。(这篇还真得好好看几遍)
Reducing the dimensionality of datawith neural networks, 2006.
未读,据说是Science上的大作,可算作一个里程碑,标志着深度学习总算有了高效的可行的算法。
A practical guide to trainingrestricted boltzmann machines, 2010.
训练RBM的指导书,里面对一些参数的设置也说明得比较清楚,如果要自己写这方面的code,这篇可以说是必读的了,俺可是花了一个礼拜才算是把这个弄清楚七八成,再花了一个礼拜才整出了code。
The difficulty of training deeparchitectures and the effect of unsupervised pretraining, 2009.
Why Does Unsupervised Pre-training HelpDeep Learning?, 2010.
阐述了非监督预训练的作用。这两篇可以结合起来一起看。
目前先整理这么多,由于RBM在监督学习和未监督学习的code还在整,目前只用了CD算法,用在识别手写体和去噪,效果是已经出来,但由于是对照着那篇RBM的指导书来写的,代码方面比较凌乱,所以还得花时间再整理整理,下次再把原理和结合一小点伪代码放到blog上吧。
关于RBM和CD
在神经网络中,两层神经网络(即一个hidden层和一个output层,visible层不算在内)的建模能力是很强的,但要求hidden层的节点数够多,但节点数太多就会导致计算量的复杂,矩阵的维护会相当大。一个很好想到的方法就是将层数加大,通过层数的增多来缓解单层中节点数过多的负担,比如设置两个hidden层,每层100个节点,就相当于单个hidden层100×100个节点的建模能力,同理三个hidden层,每层分别是100、200、300个节点,就相当于单层的100×200×300个节点的建模能力。然而这样做的问题在于,当层数大于2时,经典的训练方法效果会较差,因为参数的局部极小值太多,容易收敛到一个不好的极值。Hinton把RBM(RestrictedBoltzmannMachine)层叠在一起,训练出权值,然后把这个权值当成是下一个RBM层的输入作为权值的初始值,利用传统的梯度下降法去训练网络,得到了更好的结果,也即在每个RBM层通过筛选得到较好的参数初始值,使得最后的结果更好。
BoltzmannMachine其实是一种无向图,里面的节点是互相连接的,但不一定是全连接,也即不是每个节点都两两相连,连接着的两个节点之间就有一个权值。为理解方便就假设节点只能取值为0或者1,有些节点值是已知的,有些是未知的,把已知的节点集合记为V,未知的节点集合记为H,这样就把所有节点分成两个集合,其实集合V就可以认为是visible层,集合H就可以认为是hidden层。如果hidden层中的节点都不互相连接,visible层中的节点也都不互相连接,那么就成为了RBM模型。
为了理解方便,考虑训练样本是一些二值图像,将其进行向量化,得到二值向量的一个集合作为训练集,这些训练集就可以构建一个两层的成为RBM的网络,对于这些像素值就可以关联为visible层中的节点,因为它们像素值是“可见的”(像素值已知),特征的检测器就关联为hidden层中的节点,根据Hopfiled(了解神经网络的应该没什么人不知道他了,HopfiledNetwork)在1982年给出的一个能量函数的定义,定义一个函数来标记hidden中的某一个节点h和visible层中的某一个节点v之间的能量:
(1)
其中 、 分别是visible层和hidden层的状态值, 和分别是它们的bias值, 就是两个节点之间的weight。而网络通过另一个能量函数给每一对 节点对分配了一个概率值:
(2)
而网络给每个visible层节点分配的概率值就是把所有可能的与它相连的hidden层节点的概率值相加,也即:
(3)
在传统的神经网络中就可以知道,网络分配给每个训练样本的概率值是可以调节的,通过对weight和bias的调整来使该样本的能量降低并提高其它样本的能量,就可以使这个概率值变大,这其实从(2)式也可以看出,随着能量递增,概率值是递减的。由于能量是作为指数,所以为了求解方便就加上了取对数log操作,对log(p(v))关于weight求导来求得极值,所以得:
(4)
<>表示求期望,式子第一项是指已知样本集时, 的期望,这时的是由样本确定的,而 是未知的,第二项是模型中 的期望,这时的 和均是未知的。由于在RBM中,hidden层的节点并没有直接相连,所以要获取 的无偏采样是可以的,对于一个随机选取的训练样本,其每一个hidden层节点 状态量为1的概率是:
(5)
其中 是logistic sigmoid函数也即 。
同理,在visible层的节点并没有直接相连,所以要获取visible层节点状态量的无偏采样也是可以的,对于一个已知的hidden层的向量h,由其反退回去得到的状态量为1的概率值是:
(6)
然而,要得到的无偏采样,就没有那么容易了。它可以通过抽样法得到,随机选定一个visible层的节点由(6)式得到 ,将其结果代入(5)式得到,从而得到 的第一个采样,再将(5)式子结果代入(6)式,(6)结果代入(5),从而得到的第二个采样,如此反复,最后这个抽样过程得到的抽样分布就收敛于模型的真实分布,这个采样过程其实就是Gibbs采样,Gibbs采样是Metropolis-Hastings算法得到的特殊情况,而Metropolis-Hastings算法其实就是MarkovChain Monte Carlo(MCMC)算法的一种,用于产生MarkovChain。这种方式需要一个很长的采样过程。Hinton提出了一个较为快速的方法,他先把所有的visible层节点的状态设置为一个向量,使用(5)式得到所有hidden层节点的概率值,并根据这个概率值将节点设置为1或者0(将概率值与一个随机生成的(0,1)之间的浮点数去比较,大于该随机数则该节点状态量置为1,否则为0),再由(6)式返回计算visible层节点值(也即重构过程),进而得到的一个估计,也即权重weight的更新方式由
(7)
变为:
(8)
这种方式虽然只是粗略近似训练数据的log概率的梯度,但是学习效果却还是很好,其学习规则更接近于另一个决策函数的极值化,这个函数是ContrastiveDivergence(CD),也就是两个Kullback-Liebler divergences(KLdivergences)的差值。
在使用CD时,必须注意要把hidden节点值置为二值化形式(0或1),而不是直接采用其概率值本身,因为这样做的话,在进行重构的时候,每个hidden节点就和visible节点的真实值发生了联系,这会导致违反如下基本规则:每个hidden节点最多只能有一个状态量,也即它不能既是0又是1。然而,在最后一次更新hidden节点时,就不可以使用二值状态量了,因为此时已经没有什么是依赖于“哪个状态量被选中”,也即哪个状态为0或为1并不造成什么影响,所以应该是使用(5)式所得的概率值本身,以避免不必要的采样噪声,在使用CDn时只有最后一次更新才可以如此使用概率值本身。
RBM的指导书中还提到,在选择用于学习的数据时,假设visible层节点是使用真实的概率值而不是使用随机的二值状态,那么获取visible层与hidden层节点连接数据的方式有两种:或者 ,其中 是一个概率值,而以这个概率值取值为1。使用第一种方式更接近于RBM的数学模型,而使用第二种方式能有较少的采样噪声且学习速度更快。
关于初始weight和bias的设置方面,RBM指导书建议,weight初始化为一些小的随机制,这些随机值服从均值为0、方差为0.01的高斯分布,使用较大的值可以加速这个学习过程,但是学习效果却不是很好,而且要注意确保初始值不会使visible节点的概率值非常接近0或者1,以避免早熟。bias的初始值,通常visible层节点状态值为1的,bias初始值设为。
根据RBM指导书,本人使用单层无监督训练,将结果用于去噪的实验,训练样本为5000,训练时间约为1.5分钟,再从测试样本集中随机选择70个进行测试,运行时间大约为12毫秒。在进行分类识别的实验中,只使用单层的RBM,测试样本为1000时识别率可以达到89%以上,耗时约为62毫秒;多层的RBM由于涉及到隐层节点数的设置,所以还需要进行多种尝试才可以得到较佳效果(曾尝试过三个隐层,节点数分别为100、200、300,识别率为90.1%,时间约为160毫秒),但可以肯定的是识别率是在单层效果之上。