0%

DL笔记(4)Brief Introduction of Deep Learning

首先简单了解一下Deep Learning 深度学习的发展历程:

  • 1958:Perceptron(linear model),感知机的提出
    • 和Logistic Regression类似,只是少了sigmoid的部分
  • 1969:Perceptron has limitation,from MIT
  • 1980s:Multi-layer Perceptron,多层感知机
    • 和今天的DNN很像
  • 1986:Backpropagation,反向传播
    • Hinton propose的Backpropagation
    • 存在problem:通常超过3个layer的neural network,就train不出好的结果
  • 1989: 1 hidden layer is “good enough”,why deep?
    • 有人提出一个理论:只要neural network有一个hidden layer,它就可以model出任何的function,所以根本没有必要叠加很多个hidden layer,所以Multi-layer Perceptron的方法又坏掉了,这段时间Multi-layer Perceptron这个东西是受到抵制的
  • 2006:RBM initialization(breakthrough):Restricted Boltzmann Machine,受限玻尔兹曼机
    • Deep learning -> another Multi-layer Perceptron ?在当时看来,它们的不同之处在于在做gradient descent的时候选取初始值的方法如果是用RBM,那就是Deep learning;如果没有用RBM,就是传统的Multi-layer Perceptron
    • 那实际上呢,RBM用的不是neural network base的方法,而是graphical model,后来大家试验得多了发现RBM并没有什么太大的帮助,因此现在基本上没有人使用RBM做initialization了
    • RBM最大的贡献是,它让大家重新对Deep learning这个model有了兴趣(石头汤的故事)
  • 2009:GPU加速的发现
  • 2011:start to be popular in speech recognition,语音识别领域
  • 2012:win ILSVRC image competition,Deep learning开始在图像领域流行开来

1.Neural Network

实际上,Deep learning跟machine learning一样,也是“大象放进冰箱”的三个步骤。在Deep learning的step1里定义的function,就是neural network。

把多个Logistic Regression前后connect在一起,然后把一个Logistic Regression称之为neuron,整个称之为neural network。我们可以用不同的方法连接这些neuron,就可以得到不同的structure,neural network里的每一个Logistic Regression都有自己的weight和bias,这些weight和bias集合起来,就是这个network的parameter,我们用$\theta$来描述。

Fully Connect Feedforward Network

这些神经元Neuron之间的连接方式需要我们自己去设计的,最常见的连接方式叫做Fully Connect Feedforward Network(全连接前馈网络)。如果一个neural network的参数weight和bias已知的话,它就是一个function,它的input是一个vector,output是另一个vector,这个vector里面放的是样本点的feature,vector的dimension就是feature的个数

如果现在我们还不知道网络中每个神经元中的参数,只是定出了这个network的structure,只是决定好这些neuron该怎么连接在一起,这样的一个network structure其实是定义了一个function set(model),给这个network设不同的参数,它就变成了不同的function,把这些可能的function集合起来,就得到了一个function set。用neural network决定function set的时候,这个function set是比较大的,它包含了很多原来你做Logistic Regression、做linear Regression所没有办法包含的function。

上图中,每一排表示一个layer,每个layer里面的每一个球都代表一个neuron

  • layer和layer之间neuron是两两互相连接的,layer 1的neuron output会连接给layer 2的每一个neuron作为input
  • 对整个neural network来说,它需要一个input,这个input就是一个feature vector,而对layer 1的每一个neuron来说,它的input就是input layer的每一个dimension
  • 最后那个layer L,由于它后面没有接其它东西了,所以它的output就是整个network的output
  • 这里每一个layer都是有名字的
    • input layer,输入层(严格来说input layer其实不是一个layer,它跟其他layer不一样,不是由neuron所组成的)
    • output layer,输出层
    • 中间层,叫做hidden layer,隐藏层
  • 每一个neuron里面的sigmoid function,在Deep Learning中被称为activation function(激励函数),事实上它不见得一定是sigmoid function,还可以是其他function(sigmoid function是从Logistic Regression迁移过来的,现在已经较少在Deep learning里使用了)
  • 有很多层layers的neural network,被称为DNN(Deep Neural Network)

上图中的神经网络中layer和layer之间,所有的neuron都是两两连接,所以它叫Fully connected network;因为现在传递的方向是从layer 1->2->3,由前向后传,所以它叫做Feedforward network。

那所谓的Deep其实就是指有很多层hidden layer,具体的层数并没有规定。但好像现在只要是neural network base的方法,都被称为Deep Learning(苦笑)。

Matrix Operation

network的运作过程,我们通常会用Matrix Operation来表示,以下图为例,假设第一层hidden layers的两个neuron,它们的weight分别是$w_1=1,w_2=-2,w_1’=-1,w_2’=1$,那就可以把它们排成一个matrix:$\begin{bmatrix}1 \ \ \ -2\\ -1 \ \ \ 1 \end{bmatrix}$,而我们的input又是一个2*1的vector:$\begin{bmatrix}1\-1 \end{bmatrix}$,将$w$和$x$相乘,再加上bias的vector:$\begin{bmatrix}1\\0 \end{bmatrix}$,就可以得到这一层的vector $z$,再经过activation function得到这一层的output:(activation function可以是很多类型的function,这里还是用Logistic Regression迁移过来的sigmoid function作为运算)

这里我们把所有的变量都以matrix的形式表示出来,注意$W^i$的matrix,每一行对应的是一个neuron的weight,行数就是neuron的个数,而input $x$,bias $b$和output $y$都是一个列向量,行数就是feature的个数(也是neuron的个数,neuron的本质就是把feature transform到另一个space)。

写成矩阵运算的好处是不仅在于形式简洁,还在于可以用GPU加速,GPU对matrix的运算是比CPU要来的快的,所以写neural network的时候,习惯把它写成matrix operation,然后call GPU来加速它。

Output Layer

我们可以把hidden layers这部分,看做是一个feature extractor(特征提取器),这个feature extractor就r代替了我们之前手动做feature engineering,feature transformation这些事情,经过这个feature extractor得到的$x_1,x_2,…,x_k$就可以被当作一组新的feature。

output layer做的事情,其实就是把它当做一个Multi-class classifier,它是拿经过feature extractor转换后的那一组比较好的feature(能够被很好地separate)进行分类的,如果我们想把把output layer看做是一个Multi-class classifier,那么可以在最后一个layer加上softmax

2.Example Application: Handwriting Digit Recognition

这里举一个手写数字识别的例子,input是一张image,对机器来说一张image实际上就是一个vector,假设这是一张16*16的image,那它有256个pixel,对machine来说,它是一个256维的vector,image中的每一个pixel都对应到vector中的一个dimension,我们把黑色的pixel的值设为1,白色的pixel的值设为0。

而neural network的output,如果在output layer使用了softmax,那它的output就是一个突出极大值的Probability distribution,假设output是10维(10个数字,0~9),这个output的每一维都对应到它可能是某一个数字的几率,实际上这个neural network的作用就是计算这张image成为10个数字的几率各自有多少,几率最大(softmax突出极大值的意义所在)的那个数字,就是机器的预测值。

Step 1:Neural Network

在这个手写字体识别的demo里,我们需要的就是一个function,这个function的input是一个256的vector,output是一个10维的vector,这个function就是neural network(这里我们用简单的Feedforward network)。

input固定为256维,output固定为10维的feedforward neural network,实际上这个network structure就已经确定了一个function set(model)的形状,在这个function set里的每一个function都可以拿来做手写数字识别,接下来我们要做的事情是用gradient descent去计算出一组参数,挑一个最适合拿来做手写数字识别的function。(input、output的dimension,加上network structure,就可以确定一个model的形状,前两个是容易知道的,而确定这个network的structure则是整个Deep Learning中最为关键的步骤)

所以这里很重要的一件事情是,我们要对network structure进行design,之前在做Logistic Regression或者是linear Regression的时候,我们对model的structure是没有什么好设计的,但是对neural network来说,我们现在已知的constraint只有input是256维,output是10维,而中间要有几个hidden layer,每个layer要有几个neuron,都是需要我们自己去设计的,它们近乎是决定了function set长什么样子。如果network structure设计的很差,这个function set里面根本就没有好的function,那就会像大海捞针一样,结果针并不在海里(=´ω`=)

input 256维,output 10维,以及自己design的network structure =》function set(model)

Step 2:Goodness of function

定义一个function的好坏,由于我们做的是一个Multi-class classification,所以image为数字1的label “1”告诉我们,现在的target是一个10维的vector,只有在第一维对应数字1的地方,它的值是1,其他都是0

input这张image的256个pixel,通过这个neural network之后,会得到一个output,称之为y;而从这张image的label中转化而来的target,称之为$\hat{y}$,有了output $y$和target $\hat{y}$之后,要做的事情是计算它们之间的cross entropy(交叉熵),这个做法跟我们之前做Multi-class classification的时候是一模一样的

Step 3:Pick the best function

接下来就去调整参数,让这个cross entropy越小越好,当然整个training data里面不会只有一笔data,你需要把所有data的cross entropy都sum起来,得到一个total loss $L=\sum\limits_{n=1}^Nl^n$,得到loss function之后要做的就是找一组network的parameters:$\theta^*$,它可以minimize这个total loss,这组parameter对应的function就是我们最终训练好的model。

那如何去找这个使total loss minimize的$\theta^$呢?我们依然可以使用之前学过的——*Gradient Descent

实际上在deep learning里面用gradient descent,跟在linear regression里面使用完全没有什么差别,只是function和parameter变得更复杂了而已,其他事情都是一模一样的。现在的$\theta$里面是一大堆的weight、bias参数,先random找一个初始值,接下来去计算每一个参数对total loss的偏微分,把这些偏微分全部集合起来,就叫做gradient,有了这些偏微分以后,就可以更新所有的参数,都减掉learning rate乘上偏微分的值,这个process反复进行下去,最终找到一组好的参数,就做完deep learning的training了。

Design network structure V.s. Feature Engineering

其实network structure的design是一件蛮难的事情,我们到底要怎么决定layer的数目和每一个layer的neuron的数目呢?其实这个只能够凭着经验和直觉、多方面的尝试,有时候甚至会需要一些domain knowledge(专业领域的知识),从非deep learning的方法到deep learning的方法,并不是说machine learning比较简单,而是我们把一个问题转化成了另一个问题。

本来不是deep learning的model,要得到一个好的结果,往往需要做feature engineering(特征工程),也就是做feature transform,然后找一组好的feature;一开始学习deep learning的时候,好像会觉得deep learning的layers之间也是在做feature transform,但实际上在做deep learning的时候,往往不需要一个好的feature ,比如说在做影像辨识的时候,你可以把所有的pixel直接丢进去,但是在过去做图像识别,你是需要对图像抽取出一些人定的feature出来的,这件事情就是feature transform,但是有了deep learning之后,你完全可以直接丢pixel进去硬做

但是,今天deep learning制造了一个新的问题,它所制造的问题就是,你需要去design network的structure,所以你的问题从本来的如何抽取feature转化成怎么design network structure,所以deep learning是不是真的好用,取决于你觉得哪一个问题比较容易。

如果是影像辨识或者是语音辨识的话,design network structure可能比feature engineering要来的容易,因为,虽然我们人都会看、会听,但是这件事情,它太过潜意识了,它离我们意识的层次太远,我们无法意识到,我们到底是怎么做语音辨识这件事情,所以对人来说,你要抽一组好的feature,让机器可以很方便地用linear的方法做语音辨识,其实是很难的,因为人根本就不知道好的feature到底长什么样子;所以还不如design一个network structure,或者是尝试各种network structure,让machine自己去找出好的feature,这件事情反而变得比较容易,对影像来说也是一样的。

3.Why Deep?

前面在介绍Deep Learning发展历程的时候有提到“只要neural network有一个hidden layer,它就可以model出任何的function”,那么是不是意味着我们并不不需要费尽心思地设计”Deep”的Network,只要用有一层layer的Network就可以解决问题了?显然不是这样的(要不然Deep Learning怎么发展到今天啊喂ヽ(#`Д´)ノ┌┛〃),那么Deep好在哪呢?

Fat + Short v.s. Thin + Tall

论上只要这一层里neuron的数目足够多,有足够的参数,就可以表示出任何函数。那用大量的data加上参数足够多的model就可以实现这个效果,那为什么一定要用DNN呢?我们完全可以用一层的shallow neural network来做同样的事情,其实“Deep”和”Shallow”这两种结构的Network的performance是会不一样的,这里我们就拿下面这两种结构的network做一下比较。

如果要给Deep和Shallow的model一个公平的评比,就要调整它们的形状,让它们的参数是一样多的,在这个情况下Shallow的model就会是一个“矮胖”的model,Deep的model就会是一个“瘦高”的model。有学者在这个公平的评比之下,得到的结果如下图所示。左侧表示的是deep network的情况,右侧表示的是shallow network的情况,为了保证两种情况下参数的数量是比较接近的,因此设置了右侧1*3772和1*4634这两种size大小,它们分别对应比较左侧5*2k和7*2k这两种情况下的network(注意参数数目和neuron的数目并不是等价的)。

发现,在参数数量接近的情况下,只有1层的network,它的error rate是远大于好几层的network的;1层的shallow network的performance甚至都比不过很多参数比它少但层数比它多的deep network。根据上面的对比可知,deep learning显然是在结构上存在着某种优势,不然无法解释它会比参数数量相同的shallow learning表现得更好这个现象。

Modularization

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一样,每次在用到的时候都要重新去检测一遍,因此大大降低了程序的复杂度。

这里举一个分类的例子,我们要把input的人物分为四类:长头发女生、长头发男生、短头发女生、短头发男生。如果按照shallow network的想法,我们分别独立地train四个classifier(其实就相当于训练四个独立的model),然后就可以解决这个分类的问题;但是这里有一个问题,长头发男生的data是比较少的,没有太多的training data,所以,你train出来的classifier就比较weak,去detect长头发男生的performance就比较差。

其实我们的input并不是没有关联的,长头发的男生和长头发的女生都有一个共同的特征,就是长头发,因此如果我们分别独立地训练四个model作为分类器,实际上就是忽视了这个共同特征,也就是没有高效地用到data提供的全部信息,这恰恰是shallow network的弊端。

而利用modularization的思想,使用deep network的架构,我们可以训练一个model作为分类器就可以完成所有的任务,我们可以把整个任务分为两个子任务:

  • Classifier1:检测是男生或女生
  • Classifier2:检测是长头发或短头发

虽然长头发的男生data很少,但长头发的人的data就很多,这样就真正做到了充分、高效地利用数据,最终的Classifier再根据Classifier1和Classifier2提供的信息给出四类人的分类结果。

经过层层layer的任务分解,其实每一个Classifier要做的事情都是比较简单的,又因为这种分层的、模组化的方式充分利用了data,并提高了信息利用的效率,所以只要用比较少的training data就可以把结果train好。

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,利用第二层得到的特征分类出蜂窝、轮胎、人
  • 以此类推

这边要强调的是,在做deep learning的时候,怎么做模块化这件事情是machine自动学到的,也就是说,第一层要检测什么特征、第二层要检测什么特征…这些都不是人为指定的,人只定好有几层layer、每层layer有几个neuron,剩下的事情都是machine自己学到的。

传统的机器学习算法,是人为地根据domain knowledge指定特征来进行提取,这种指定的提取方式,甚至是提取到的特征,也许并不是实际最优的,所以它的识别成功率并没有那么高;但是在Deep Learning中,提取什么特征、怎么提取这件事让机器自己去学,它所提取的就会是那个最优解,因此识别成功率普遍会比人为指定要来的高。

后面老师举了一个DNN在语音识别领域的例子,传统的HMM-GMM方法是默认把所有的phone或者state都看做是无关联的,对它们分别训练independent model,没有充分利用data提供的信息。而DNN的做法是把所有的state通通用同一个model来做分类,比较lower的layer会先观察人是用什么样的方式在发这个声音,人的舌头位置应该在哪里,是高是低,是前是后;接下来的layer再根据这个结果,去决定现在的发音是属于哪一个state或哪一个phone。这些lower的layer是一个人类发音方式的detector,而所有phone的检测都share这同一组detector的结果,因此最终的这些classifier是share了同一组用来detect发音方式的参数,这就做到了模块化,同一个参数被更多的地方share,因此显得更有效率。

Deep is better

Universality Theorem告诉我们任何的continuous的function都可以用一层足够宽的neural network来实现,在90年代,这是很多人放弃做deep learning的一个原因。但是这个理论只告诉了我们可能性,却没有说明这件事的效率问题;根据上面的几个例子我们已经知道,只用一个hidden layer来描述function其实是没有效率的;当你用multi-layer,用hierarchy structure来描述function的时候,才会是比较有效率的。

老师分别用逻辑电路和剪窗花的小例子来说明”Deep”相比于”Shallow”的优势,这里就不详细展开了。下面是老师做的一个小例子,左边的图是training data,右边则是1层hidden layer与3层hidden layer的不同network的情况对比,这里已经控制它们的参数数量趋于相同,试验结果是,当training data为10w笔的时候,两个network学到的样子是比较接近原图的,而如果只给2w笔training data,1层hidden layer的情况就完全崩掉了,而3层hidden layer的情况会比较好一些。

End-to-end Learning

所谓的End-to-end learning 端到端的学习,指的是只给model input和output,而不告诉它中间每一个function要怎么分工,让它自己去学会知道在生产线的每一站,自己应该要做什么事情;在DNN里,就是叠一个很深的neural network,每一层layer就是生产线上的一个站,我们不需要告诉机器生产线上的每一站是干什么的,而是是让机器自己去完成整条生产线的学习。

相对于深度学习,传统机器学习的流程往往由多个独立的模块组成,比如在一个典型的自然语言处理(Natural Language Processing)问题中,包括分词、词性标注、句法分析、语义分析等多个独立步骤,每个步骤是一个独立的任务,其结果的好坏会影响到下一步骤,从而影响整个训练的结果,这是非端到端的。

深度学习模型在训练过程中,从输入端(输入数据)到输出端会得到一个预测结果,与真实结果相比较会得到一个误差,这个误差会在模型中的每一层传递(反向传播),每一层的表示都会根据这个误差来做调整,直到模型收敛或达到预期的效果才结束,这是端到端的。

CNN就是比较典型的end2end模型。在图像分类里输入image各通道像素,输出图像类别。 相比于非end2end,conv层的卷积核可以充当feature extractor部分而不需要额外的工作去做特征工程的内容。尽管每一层需要自己设计,但如何得到feature并不需要额外的操作。

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)。

Complex Task

有时候我们会遇到非常复杂的task:

  • Very similar input, but different output
  • Very different input, but similar output

如果你的network只有一层的话,就只能做简单的transform,没有办法把一样的东西变得很不一样,把不一样的东西变得很像;如果要实现这些,就需要做很多层次的转换,就像前面那个剪窗花的例子,在二维、三维空间上看起来很难辨别,但是到了高维空间就完全有可能把它们给辨别出来。

这里以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”的一个优势所在。