(入门)|深度学习通俗理解
1. 深度学习到底是干啥的?
2017年10月18日,《自然》杂志网站公布的论文显示,此前战胜人类围棋世界冠军的电脑程序AlphaGo的开发团队又出力作——新程序AlphaGo Zero(阿尔法元)不依靠人类指导和经验,仅凭自身算法强化学习,就以100:0的战绩击败了AlphaGo(阿尔法狗)。深度学习愈演愈烈,那么究竟什么是深度学习呢?对于新手该怎么快速入门呢?本文从仿生学角度做出一个入门级的介绍,如有好的建议或者疑问,欢迎文末留言。
在深度学习出现之前,科学家们都是通过人为设计特征,然后将人为设计的特征用于图像的后续处理,思路如下图所示。这里的特征有一些还是比较牛逼的,像SIFT,HOG,等等。
但是这些特征的设计都是非常费力、启发式(需要专业知识)的,并且所具有的效果相对比较局限,既然手工选取特征不太好,那么能不能自动地学习一些特征呢?答案是能!Deep Learning就是用来干这个事情的,将海量的数据直接投放到算法中,让数据自己说话,系统自动从数据中学习。例如“猫”,从来不告诉机器说这个有小耳朵,小胡子圆头圆脑的动物就是猫,而是让机器自己领悟“猫”的概念。就好比小朋友是通过什么来认识这个世界的?
2.生物学发现了什么?
1981 年的诺贝尔医学奖,颁发给了 David Hubel(出生于加拿大的美国神经生物学家)和TorstenWiesel,以及 Roger Sperry。前两位的主要贡献,是“发现了视觉系统的信息处理”:可视皮层是分级的:
他们在猫的后脑头骨上,开了一个3 毫米的小洞,向洞里插入电极,测量神经元的活跃程度。然后,他们在小猫的眼前,展现各种形状、各种亮度的物体。并且,在展现每一件物体时,还改变物体放置的位置和角度。他们期望通过这个办法,让小猫瞳孔感受不同类型、不同强弱的刺激。
之所以做这个试验,目的是去证明一个猜测。位于后脑皮层的不同视觉神经元,与瞳孔所受刺激之间,存在某种对应关系。一旦瞳孔受到某一种刺激,后脑皮层的某一部分神经元就会活跃。
David Hubel 和Torsten Wiesel 发现了一种被称为“方向选择性细胞(Orientation Selective Cell)”的神经元细胞。当瞳孔发现了眼前的物体的边缘,而且这个边缘指向某个方向时,这种神经元细胞就会活跃。
这个发现激发了人们对于神经系统的进一步思考。神经-中枢-大脑的工作过程,或许是一个不断迭代、不断抽象的过程。这里的关键词有两个,一个是抽象,一个是迭代。从原始信号,做低级抽象,逐渐向高级抽象迭代。人类的逻辑思维,经常使用高度抽象的概念。
若把人脑的这种分析方式比喻成图像处理,则如下图所示:第一层为像素级别,通过摄入瞳孔中形成像素;第二层级为某些细胞发现边缘和方向;第三层级为判定形状,是眼睛还是鼻子;第四层级进一步抽象(判断这是一个人脸)。
3.生物学与稀疏编码的不谋而合
1995 年前后,Bruno Olshausen和 David Field 两位学者任职 Cornell University,他们试图同时用生理学和计算机的手段,双管齐下,研究视觉问题。他们收集了很多黑白风景照片,从这些照片中,提取出400个小碎片,每个照片碎片的尺寸均为 16x16 像素,不妨把这400个碎片标记为 S[i], i = 0,.. 399。接下来,再从这些黑白风景照片中,随机提取另一个碎片,尺寸也是 16x16 像素,不妨把这个碎片标记为 T。
他们提出的问题是,如何从这400个碎片中,选取一组碎片,S[k], 通过叠加的办法,合成出一个新的碎片,而这个新的碎片,应当与随机选择的目标碎片 T,尽可能相似,同时,S[k] 的数量尽可能少。用数学的语言来描述,就是:
Sum_k (a[k] * S[k]) --> T, 其中 a[k] 是在叠加碎片 S[k] 时的权重系数。
为解决这个问题,Bruno Olshausen和 David Field 发明了一个算法,稀疏编码(Sparse Coding)。
稀疏编码是一个重复迭代的过程,每次迭代分两步:
1)选择一组 S[k],然后调整 a[k],使得Sum_k (a[k] * S[k]) 最接近 T。
2)固定住 a[k],在 400 个碎片中,选择其它更合适的碎片S’[k],替代原先的 S[k],使得Sum_k (a[k] * S’[k]) 最接近 T。
经过几次迭代后,最佳的 S[k] 组合,被遴选出来了。令人惊奇的是,被选中的 S[k],基本上都是照片上不同物体的边缘线,这些线段形状相似,区别在于方向。如下图所示:一个图可以通过用64种正交的edges(可以理解成正交的基本结构)来线性表示。比如样例的x可以用1-64个edges中的三个按照0.8,0.3,0.5的权重调和而成。而其他基本edge没有贡献,因此均为0 。
Bruno Olshausen和 David Field 的算法结果,与 David Hubel 和Torsten Wiesel 的生理发现,不谋而合!也就是说,复杂图形,往往由一些基本结构组成。这里我们可以将像素级到边缘的抽象作为深度学习网络的第一层,那接下来的网络层次如何拓展呢?这里我们将讨论深度学习的更深入层次。
4. 深度学习的层级到底怎么说?
小块的图形可以由基本edge构成,更结构化,更复杂的,具有概念性的图形如何表示呢?这就需要更高层次的特征表示,比如下图的V2,V4。
因此V1看像素级是像素级。V2看V1是像素级,这个是层次递进的,高层表达由底层表达的组合而成。专业点说就是基basis。V1取提出的basis是边缘,然后V2层是V1层这些basis的组合,这时候V2区得到的又是高一层的basis。即上一层的basis组合的结果,上上层又是上一层的组合basis……(所以有大牛说Deep learning就是“搞基”,因为难听,所以美其名曰Deep learning或者Unsupervised Feature Learning),如下所示为“高级”的结果。
深度学习的层级关系:
1.训练第一层
如下图所示,我们将input输入一个encoder编码器,就会得到一个code,这个code也就是输入的一个表示,那么我们怎么知道这个code表示的就是input呢?我们加一个decoder解码器,这时候decoder就会输出一个信息,那么如果输出的这个信息和一开始的输入信号input是很像的(理想情况下就是一样的),那很明显,我们就有理由相信这个code是靠谱的。所以,我们就通过调整encoder和decoder的参数并且加入稀疏惩罚项,在稀疏性最小的同时,使得重构误差最小,这时候我们就得到了输入input信号的第一个表示了,也就是稀疏性的编码code了。
2.训练然后训练下一层。这样逐层训练:
那上面我们就得到第一层的code,我们的重构误差最小让我们相信这个code就是原输入信号的良好表达了,或者牵强点说,它和原信号是一模一样的(表达不一样,反映的是一个东西)。那第二层和第一层的训练方式就没有差别了,我们将第一层输出的code当成第二层的输入信号,同样最小化重构误差,就会得到第二层的参数,并且得到第二层输入的code,也就是原输入信息的第二个表达了。其他层就同样的方法炮制就行了(训练这一层,前面层的参数都是固定的,并且他们的decoder已经没用了,都不需要了)。
将第一步训练的图重新表示如下(灰色表示输入或者前一层的输出、黑色表示encoder、紫色表示decoder、红色椭圆表示error,而稀疏正则项在这里我们省去):
则逐层训练表示如下图所示:
3.顶层设计:
经过上面的方法,我们就可以得到很多层了。至于需要多少层(或者深度需要多少,这个目前本身就没有一个科学的评价方法)需要自己试验调了。每一层都会得到原始输入的不同的表达。当然了,我们觉得它是越抽象越好了,就像人的视觉系统一样。
到这里,这个AutoEncoder(自动编码器)还不能用来分类数据,因为它还没有学习如何去连结一个输入和一个类。它只是学会了如何去重构或者复现它的输入而已。或者说,它只是学习获得了一个可以良好代表输入的特征,这个特征可以最大程度上代表原输入信号。那么,为了实现分类,我们就可以在AutoEncoder的最顶的编码层添加一个分类器(例如logistic回归、SVM等),然后通过标准的多层神经网络的监督训练方法(梯度下降法)去训练。
也就是说,这时候,我们需要将最后层的特征code输入到最后的分类器,通过有标签样本,通过监督学习进行微调,这也分两种,一个是只调整分类器(黑色部分):
5. 深度学习小结:
至此对于深度学习的基本入门已经讲解的差不多了,深度学习能自动将低层次抽象到高层次的表达,相对于图像和语音特征不明晰(需要手动设计出耗时耗力的特征)的问题,减少了手动设计特征的巨大工作量,而且由于模型的层次、容量足够,能够更好的表达大规模数据。由于本人水平有限,如有好的建议或者疑问,欢迎文末留言。