文章目录
Why Deep?
本文主要围绕Deep这个关键词展开,重点比较了shallow learning和deep learning的区别:
shallow:不考虑不同input之间的关联,针对每一种class都设计了一个独立的model检测
deep:考虑了input之间的某些共同特征,所有class用同个model分类,share参数,modularization思想,hierarchy架构,更有效率地使用data和参数
Shallow V.s. Deep
Deep is Better?
我们都知道deep learning在很多问题上的表现都是比较好的,越deep的network一般都会有更好的performance
那为什么会这样呢?有一种解释是:
- 一个network的层数越多,参数就越多,这个model就越复杂,它的bias就越小,而使用大量的data可以降低这个model的variance,performance当然就会更好
如下图所示,随着layer层数从1到7,得到的error rate不断地降低,所以有人就认为,deep learning的表现这么好,完全就是用大量的data去硬train一个非常复杂的model而得到的结果
![](https://i-blog.csdnimg.cn/blog_migrate/bee0649bfe673af4c2551c7896b51cf8.png)
既然大量的data加上参数足够多的model就可以实现这个效果,那为什么一定要用DNN呢?我们完全可以用一层的shallow neural network来做同样的事情,理论上只要这一层里neuron的数目足够多,有足够的参数,就可以表示出任何函数;那DNN中deep的意义何在呢?
Fat + Short v.s. Thin + Tall
其实深和宽这两种结构的performance是会不一样的,这里我们就拿下面这两种结构的network做一下比较:
![](https://i-blog.csdnimg.cn/blog_migrate/1b66c3d588bc254fdec1347e113b5315.png)
在这个公平的评比之下,得到的结果如下图所示:
左侧表示的是deep network的情况,右侧表示的是shallow network的情况,为了保证两种情况下参数的数量是比较接近的,因此设置了右侧1*3772和1*4634这两种size大小,它们分别对应比较左侧5*2k和7*2k这两种情况下的network(注意参数数目和neuron的数目并不是等价的)
![](https://i-blog.csdnimg.cn/blog_migrate/e5a237a5625894c61f86fc9102258062.png)
这个时候你会发现,在参数数量接近的情况下,只有1层的network,它的error rate是远大于好几层的network的;这里甚至测试了1*16k大小的shallow network,把它跟左侧也是只有一层,但是没有那么宽的network进行比较,由于参数比较多所以才略有优势;但是把1*16k大小的shallow network和参数远比它少的2*2k大小的deep network进行比较,结果竟然是后者的表现更好
也就是说,只有1层的shallow network的performance甚至都比不过很多参数比它少但层数比它多的deep network,这是为什么呢?
有人觉得deep learning就是一个暴力辗压的方法,我可以弄一个很大很大的model,然后collect一大堆的data,就可以得到比较好的performance;但根据上面的对比可知,deep learning显然是在结构上存在着某种优势,不然无法解释它会比参数数量相同的shallow learning表现得更好这个现象
Modularization
introduction
DNN结构一个很大的优势是,Modularization(模块化),它用的是结构化的架构
就像写程序一样,shallow network实际上就是把所有的程序都写在了同一个main函数中,所以它去检测不同的class使用的方法是相互独立的;而deep network则是把整个任务分为了一个个小任务,每个小任务又可以不断细分下去,以形成modularization,就像下图一样
在DNN的架构中,实际上每一层layer里的neuron都像是在解决同一个级别的任务,它们的output作为下一层layer处理更高级别任务的数据来源,低层layer里的neuron做的是对不同小特征的检测,高层layer里的neuron则根据需要挑选低层neuron所抽取出来的不同小特征,去检测一个范围更大的特征;neuron就像是一个个classifier ,后面的classifier共享前面classifier的参数
这样做的好处是,低层的neuron输出的信息可以被高层不同的neuron重复使用,而并不需要像shallow network一样,每次在用到的时候都要重新去检测一遍,因此大大降低了程序的复杂度
![](https://i-blog.csdnimg.cn/blog_migrate/b4f1902e537425150bda03484127f374.png)
example
这里举一个分类的例子,我们要把input的人物分为四类:长头发女生、长头发男生、短头发女生、短头发男生
如果按照shallow network的想法,我们分别独立地train四个classifier(其实就相当于训练四个独立的model),然后就可以解决这个分类的问题;但是这里有一个问题,长头发男生的data是比较少的,没有太多的training data,所以,你train出来的classifier就比较weak,去detect长头发男生的performance就比较差
![](https://i-blog.csdnimg.cn/blog_migrate/c6d615f205157d1568fe34cce344d6b0.png)
但其实我们的input并不是没有关联的,长头发的男生和长头发的女生都有一个共同的特征,就是长头发,因此如果我们分别独立地训练四个model作为分类器,实际上就是忽视了这个共同特征,也就是没有高效地用到data提供的全部信息,这恰恰是shallow network的弊端
而利用modularization的思想,使用deep network的架构,我们可以训练一个model作为分类器就可以完成所有的任务,我们可以把整个任务分为两个子任务:
- Classifier1:检测是男生或女生
- Classifier2:检测是长头发或短头发
虽然长头发的男生data很少,但长头发的人的data就很多,经过前面几层layer的特征抽取,就可以头发的data全部都丢给Classifier2,把男生或女生的data全部都丢给Classifier1,这样就真正做到了充分、高效地利用数据,最终的Classifier再根据Classifier1和Classifier2提供的信息给出四类人的分类结果
![](https://i-blog.csdnimg.cn/blog_migrate/f2ff8097965c83bef4b64f89e1073caa.png)
deep -> modularization
做modularization的好处是把原来比较复杂的问题变得简单,比如原来的任务是检测一个长头发的女生,但现在你的任务是检测长头发和检测性别,而当检测对象变简单的时候,就算training data没有那么多,我们也可以把这个task做好,并且所有的classifier都用同一组参数检测子特征,提高了参数使用效率,这就是modularization、这就是模块化的精神
由于deep learning的deep就是在做modularization这件事,所以它需要的training data反而是比较少的,这可能会跟你的认知相反,AI=big data+deep learning,但deep learning其实是为了解决less data的问题才提出的
每一个neuron其实就是一个basic的classifier:
- 第一层neuron,它是一个最basic的classifier,检测的是颜色、线条这样的小特征
- 第二层neuron是比较复杂的classifier,它用第一层basic的classifier的output当作input,也就是把第一层的classifier当作module,利用第一层得到的小特征分类出不同样式的花纹
- 而第三层的neuron又把第二层的neuron当作它module,利用第二层得到的特征分类出蜂窝、轮胎、人
- 以此类推
![](https://i-blog.csdnimg.cn/blog_migrate/7b2ed8afd9cb14e13bdf52d0000837c4.png)
传统的机器学习算法,是人为地根据domain knowledge指定特征来进行提取,这种指定的提取方式,甚至是提取到的特征,也许并不是实际最优的,所以它的识别成功率并没有那么高;但是如果提取什么特征、怎么提取这件事让机器自己去学,它所提取的就会是那个最优解,因此识别成功率普遍会比人为指定要来的高
Speech
前面讲了deep learning的好处来自于modularization(模块化),可以用比较efficient的方式来使用data和参数,这里以语音识别为例,介绍DNN的modularization在语音领域的应用
language basics
当你说what do you think的时候,这句话其实是由一串phoneme所组成的,所谓phoneme,中文翻成音素,它是由语言学家制订的人类发音的基本单位,what由4个phoneme组成,do由两个phoneme组成,you由两个phoneme组成,等等
同样的phoneme也可能会有不太一样的发音,当你发d uw和y uw的时候,心里想要发的都是uw,但由于人类发音器官的限制,你的phoneme发音会受到前后的phoneme所影响;所以,为了表达这一件事情,我们会给同样的phoneme不同的model,这个东西就叫做tri-phone(三音素)
一个phoneme可以拆成几个state,我们通常就订成3个state
![](https://i-blog.csdnimg.cn/blog_migrate/9dd4d620bb0a7f7c3a53a16cc2b3eac9.png)
process
语音辨识的过程其实非常复杂,这里只是讲语音辨识的第一步
你首先要做的事情是把acoustic feature(声学特征)转成state,这是一个单纯的classification的problem
大致过程就是在一串wave form(声音信号)上面取一个window(通常不会取太大,比如250个mini second大小),然后用acoustic feature来描述这个window里面的特性,每隔一个时间段就取一个window,一段声音信号就会变成一串vector sequence,这个就叫做acoustic feature sequence
![](https://i-blog.csdnimg.cn/blog_migrate/cd5f6acee71f39780b2e5663fb93b08b.png)
具体点来说就是
-
声音(波)转换为矩阵
声音是一种波常见的mp3、wmv等格式都是压缩格式,必须转成非压缩的纯波形文件来处理,比如Windows PCM文件,也就是俗称的wav文件,wav文件里存储了一个文件头和声音波形的一个个点
-
在开始语音识别之前,有时需要切除首尾端的静音,降低对后续步骤造成的干扰。
这个静音切除的操作一般称为VAD,需要用到信号处理的一些技术
-
要对声音进行分析,需要对声音分帧
-
分帧就是把声音切开成一小段一小段,每小段称为一帧。分帧操作一般不是简单的切开,而是使用移动窗函数来实现,帧与帧之间是有交叠的
-
举例来说,下图中,每帧的长度为25毫秒,每两帧之间有25-10=15毫秒的交叠,称为以帧长25ms、帧移10ms分帧
-
-
分帧后,语音就变成了很多小段,但波形在时域上几乎没有描述能力,因此必须将波形作变换
- 常见的一种变换方法是提取MFCC特征,根据人耳的生理特性,把每一帧波形变成一个多维向量(简单理解为向量包含了这帧语音的内容信息),这个过程叫做声学特征提取
- 声学特征提取后,声音就成了一个d × n d\times nd×n维的矩阵,称之为观察序列,其中d dd为声学特征维数,n nn为总帧数
-
-
矩阵转换为文本
- 第一步:把帧识别成状态(难点)
- 第二步:把状态组合成音素
- 第三步:把音素组合成单词
图中,每个小竖条代表一帧,若干帧语音对应一个状态,每三个状态组合成一个音素,若干个音素组合成一个单词。也就是说,只要知道每帧语音对应哪个状态了,语音识别的结果也就出来了。
HMM
隐马尔可夫模型(HMM)是语音信号处理中的一种统计模型,是由马尔可夫链演变来的,所以它是基于参数模型的统计识别方法。由于其模式库是通过反复训练形成的与训练输出信号吻合概率最大的最佳模型参数而不是预先储存好的模式样本,且其识别过程中运用待识别语音序列与HMM参数之间的似然概率达到最大值所对应的最佳状态序列作为识别输出,因此是较理想的语音识别模型。
![](https://i-blog.csdnimg.cn/blog_migrate/2561e47e07d9f8468a0aa8743ce325da.png)
红圈–>一个可见状态。 蓝框–>一个隐含状态
举个例子来理解隐含马尔可夫链:
假设在暗室中由N个口袋,每个口袋中由M种不同颜色的求。一个实验员根据某一概率分布随机的选取一个初始口袋,从中根据不同颜色的求的分布概率随机的取出一个球并记录下该球的颜色。而后再根据口袋的概率分布选取一个口袋,再根据不用管色球的概率分布随机选取一个球,记录下颜色。重复这个过程我们就得到了一串标记球颜色的序列,如"红黄红蓝…"。当你把这串序列给暗室外的人看的时候,他们只是看到最终球的颜色序列,但不知道口袋的序列。
在上面的例子中,口袋对应于HMM中的隐藏状态,而颜色序列则代表可观察的输出序列。从一个口袋转向另一个口袋代表状态间的转换,从口袋中取球代表该状态的观察状态输出
HMM解决的问题
-
计算likelihood–前向算法 :给定HMM的模型参数和一个观察序列,计算出观察序列O的概率分布矩阵P(O|u),可采用前向算法进行解决。
-
解码问题–Viterbi算法:给定一个HMM的模型参数u和观察序列o=o1,o2…oT,找到最优的状态序列Q=q1,q2…qT。可以用Viterbi算法解决。
-
HMM的训练–前向后向算法︰给定一个观察序列O=o1,o2…or和HMM一系列可能的状态,如何调节HMM的参数使得P(o|p)最大。
PS:
观察状态序列: 语音中的每一帧; 词性标注中的词串
隐藏状态序列: 语音每一帧对应的音素; 词性标注中每个词对应的词性标签
状态转移矩阵: 语音中音素之间的转移概率(数据集计算, GMM-HMM计算??); 词性标注中词性之间的转移概率
classification
传统做法
传统的方法叫做HMM-GMM
GMM,即Gaussian Mixture Model ,简单理解混合高斯模型就是几个高斯的叠加。每个state有一个GMM,包含k个高斯模型参数。它假设语音里的每一个state都是相互独立的(跟前面长头发的shallow例子很像,也是假设每种情况相互独立),因此属于每个state的acoustic feature都是stationary distribution(静态分布)的,因此我们可以针对每一个state都训练一个GMM model来识别
但这个方法其实不太现实,因为要列举的model数目太多了,一般中英文都有30几、将近40个phoneme,那这边就假设是30个,而在tri-phone里面,每一个phoneme随着contest(上下文)的不同又有变化,假设tri-phone的形式是a-b-c,那总共就有30*30*30=27000个tri-phone,而每一个tri-phone又有三个state,每一个state都要很用一个GMM来描述,那参数实在是太多了
![](https://i-blog.csdnimg.cn/blog_migrate/c9c192ad44047b40aa9d201fbab56a2d.png)
那这样的处理方法太粗糙了,所以又有人提出了subspace GMM,它里面其实就有modularization、有模块化的影子,它的想法是,我们先找一个Gaussian pool(里面包含了很多不同的Gaussian distribution),每一个state的information就是一个key,它告诉我们这个state要从Gaussian pool里面挑选哪些Gaussian出来
比如有某一个state 1,它挑第一、第三、第五个Gaussian;另一个state 2,它挑第一、第四、第六个Gaussian;如果你这样做,这些state有些时候就可以share部分的Gaussian,那有些时候就可以完全不share Gaussian,至于要share多少Gaussian,这都是可以从training data中学出来的
思考
HMM-GMM的方法,默认把所有的phone或者state都看做是无关联的,对它们分别训练independent model,这其实是不efficient的,它没有充分利用data提供的信息
对人类的声音来说,不同的phoneme都是由人类的发音器官所generate出来的,它们并不是完全无关的,下图画出了人类语言里面所有的元音,这些元音的发音其实就只受到三件事情的影响:
- 舌头的前后位置
- 舌头的上下位置
- 嘴型
比如图中所标英文的5个元音a,e,i,o,u,当你发a到e到i的时候,舌头是由下往上;而i跟u,则是舌头放在前面或放在后面的差别;在图中同一个位置的元音,它们舌头的位置是一样的,只是嘴型不一样
![](https://i-blog.csdnimg.cn/blog_migrate/7ac8cb70a95a3c3574827c7b5a99cb5e.png)
DNN做法
如果采用deep learning的做法,就是去learn一个deep neural network,这个deep neural network的input是一个acoustic feature,它的output就是该feature属于某个state的概率,这就是一个简单的classification problem
那这边最关键的一点是,所有的state识别任务都是用同一个DNN来完成的;值得注意的是DNN并不是因为参数多取胜的,实际上在HMM-GMM里用到的参数数量和DNN其实是差不多的,区别只是GMM用了很多很小的model ,而DNN则用了一个很大的model
![](https://i-blog.csdnimg.cn/blog_migrate/487d0a9cf4b78ae6b9e74c46cf38f7d8.png)
我们拿一个hidden layer出来,然后把这个layer里所有neuron的output降维到2维得到下图,每个点的颜色对应着input a,e,i,o,u,神奇的事情发生了:降维图上这5个元音的分布跟右上角元音位置图的分布几乎是一样的
因此,DNN并不是马上就去检测发音是属于哪一个phone或哪一个state,比较lower的layer会先观察人是用什么样的方式在发这个声音,人的舌头位置应该在哪里,是高是低,是前是后;接下来的layer再根据这个结果,去决定现在的发音是属于哪一个state或哪一个phone
这些lower的layer是一个人类发音方式的detector,而所有phone的检测都share这同一组detector的结果,因此最终的这些classifier是share了同一组用来detect发音方式的参数,这就做到了模块化,同一个参数被更多的地方share,因此显得更有效率
![](https://i-blog.csdnimg.cn/blog_migrate/35f0ae1a58e19e6ae5680cbad3a93b63.png)
result
这个时候就可以来回答之前在机器学习-07-Deep Learning(深度学习简介)中提到的问题了
Universality Theorem告诉我们任何的continuous的function都可以用一层足够宽的neural network来实现,在90年代,这是很多人放弃做deep learning的一个原因
但是这个理论只告诉了我们可能性,却没有说明这件事的效率问题;根据上面的几个例子我们已经知道,只用一个hidden layer来描述function其实是没有效率的;当你用multi-layer,用hierarchy structure来描述function的时候,才会是比较有效率的
![](https://i-blog.csdnimg.cn/blog_migrate/64c948afda93e7f8ad15bd4b20fc0d0f.png)
Analogy
下面用逻辑电路和剪窗花的例子来更形象地描述Deep和shallow的区别
Logic Circuit
逻辑电路其实可以拿来类比神经网络
-
每一个逻辑门就相当于一个neuron
-
只要两级逻辑门就可以表示任何的boolean function;有一个hidden layer的network(input layer+hidden layer共两层)可以表示任何continuous的function
注:逻辑门只要根据input的0、1状态和对应的output分别建立起门电路关系即可建立两级电路
-
实际设计电路的时候,为了节约成本,会进行多级优化,建立起hierarchy架构,如果某一个结构的逻辑门组合被频繁用到的话,其实在优化电路里,这个组合是可以被多个门电路共享的,这样用比较少的逻辑门就可以完成一个电路;在deep neural network里,践行modularization的思想,许多neuron作为子特征检测器被多个classifier所共享,本质上就是参数共享,就可以用比较少的参数就完成同样的function
比较少的参数意味着不容易overfitting,用比较少的data就可以完成同样任务
![](https://i-blog.csdnimg.cn/blog_migrate/785086df5ac9810cf56c0bd6c41462c6.png)
剪窗花
我们之前讲过这个逻辑回归的分类问题,可能会出现下面这种linear model根本就没有办法分类的问题,而当你加了hidden layer的时候,就相当于做了一个feature transformation,把原来的x1,x2转换到另外一个平面,变成x1’、x2’
你会发现,通过这个hidden layer的转换,其实就好像把原来这个平面按照对角线对折了一样,对折后两个蓝色的点就重合在了一起,这个过程跟剪窗花很像:
- 我们在做剪窗花的时候,每次把色纸对折,就相当于把原先的这个多维空间对折了一次来提高维度
- 如果你在某个地方戳一个洞,再把色纸打开,你折了几折,在对应的这些地方就都会有一个洞;这就相当于在折叠后的高维空间上,画斜线的部分是某一个class,不画斜线的部分是另一个class,那你在这个高维空间上的某一个点,就相当于展开后空间上的许多点,由于可以对这个空间做各种各样复杂的对折和剪裁,所以二维平面上无论多少复杂的分类情况,经过多次折叠,不同class最后都可以在一个高维空间上以比较明显的方式被分隔开来
这样做==既可以解决某些情况下难以分类的问题,又能够以比较有效率的方式充分利用data==(比如下面这个折纸,高维空间上的1个点等于二维空间上的5个点,相当于1笔data发挥出5笔data的作用)
![](https://i-blog.csdnimg.cn/blog_migrate/2783067646fdf434d1540e7633d27217.png)
左边的图是training data,右边则是1层hidden layer与3层hidden layer的不同network的情况对比,这里已经控制它们的参数数量趋于相同,试验结果是,当training data为10w笔的时候,两个network学到的样子是比较接近原图的,而如果只给2w笔training data,1层hidden layer的情况就完全崩掉了,而3层hidden layer的情况会比较好一些,它其实可以被看作是剪窗花的时候一不小心剪坏了,然后展开得到的结果
注:关于如何得到model学到的图形,可以用固定model的参数,然后对input进行梯度下降,最终得到结果,具体方法见前几章
![](https://i-blog.csdnimg.cn/blog_migrate/baba9d81cb813a57b1d7fa9d8dd1c3ee.png)
End-to-end Learning
introduction
所谓的End-to-end learning,指的是只给model input和output,而不告诉它中间每一个function要怎么分工,让它自己去学会知道在生产线的每一站,自己应该要做什么事情;在DNN里,就是叠一个很深的neural network,每一层layer就是生产线上的一个站
![](https://i-blog.csdnimg.cn/blog_migrate/b6c6842e2fe25292e5690180700b80f7.png)
Speech Recognition
End-to-end Learning在语音识别上体现的非常明显
在传统的Speech Recognition里,只有最后GMM这个蓝色的block,才是由training data学出来的,前面绿色的生产线部分都是由过去的“五圣先贤”手动制订出来的,其实制订的这些function非常非常的强,可以说是增一分则太肥,减一分则太瘦这样子,以至于在这个阶段卡了将近20年
后来有了deep learning,我们就可以用neural network把DCT、log这些部分取代掉,甚至你从spectrogram开始都拿deep neural network取代掉,也可以得到更好的结果,如果你分析DNN的weight,它其实可以自动学到要做filter bank这件事情(filter bank是模拟人类的听觉器官所制定出来的filter)
![](https://i-blog.csdnimg.cn/blog_migrate/86e52050afe9a19b4b96588fcc9ef84b.png)
有关End-to-end Learning在Image Recognition的应用和Speech Recognition很像,这里不再赘述
Complex Task
那deep learning还有什么好处呢?
有时候我们会遇到非常复杂的task:
-
有时候非常像的input,它会有很不一样的output
比如在做图像辨识的时候,下图这个白色的狗跟北极熊其实看起来是很像的,但是你的machine要有能力知道,看到左边这张图要output狗,看到右边这张图要output北极熊
-
有时候看起来很不一样的input,output其实是一样的
比如下面这两个方向上看到的火车,横看成岭侧成峰,尽管看到的很不一样,但是你的machine要有能力知道这两个都是同一种东西
![](https://i-blog.csdnimg.cn/blog_migrate/b7f7b82f7a4b3b3a16a0f1067c4e22d5.png)
这里以MNIST手写数字识别为例,展示一下DNN中,在高维空间上对这些Complex Task的处理能力
如果把28*28个pixel组成的vector投影到二维平面上就像左上角所示,你会发现4跟9的pixel几乎是叠在一起的,因为4跟9很像,都是一个圈圈再加一条线,所以如果你光看input的pixel的话,4跟9几乎是叠在一起的,你几乎没有办法把它分开
但是,等到第二个、第三个layer的output,你会发现4、7、9逐渐就被分开了,所以使用deep learning的deep,这也是其中一个理由
![](https://i-blog.csdnimg.cn/blog_migrate/f662f32941ec6b55ff62d0a2278fb44a.png)
Conclusion
Deep总结:
- 考虑input之间的内在关联,所有的class用同一个model来做分类
- modularization思想,复杂问题简单化,把检测复杂特征的大任务分割成检测简单特征的小任务
- 所有的classifier使用同一组参数的子特征检测器,共享检测到的子特征
- 不同的classifier会share部分的参数和data,效率高
- 联系logic circuit和剪纸画的例子
- 多层hidden layer对complex问题的处理上比较有优势