Brief Introduction of Deep Learning

//李宏毅视频官网:http://speech.ee.ntu.edu.tw/~tlkagk/courses.html                                                    点击此处返回总目录

//邱锡鹏《神经网络与深度学习》官网:https://nndl.github.io
 

 

 

 

Deep learning现在非常地热门,它可以用在什么地方,真的不需要多讲,大家知道的搞不好比我都多。相信用deep learning的关键字随便谷歌一下就可以找到很多exciting 的result。所以我就用这个图呢,简单地总结一下趋势。

                        

                     

这张图想表达的是这样,横轴代表时间,从2012Q1到2016;纵轴呢,在谷歌内部有用到的deep learning的project的数目。可以发现,这个趋势是几乎从0,到超过2000。使用deep learning的project的数目呢,是呈指数增长的。如果你看它的应用的话,它有各种各样的应用,几乎涵盖你所有可以想象的领域,包括Android,Apps,...各种各样的应用,统统有用到deep learning。

deep learning可以做的应用实在太多了,我们就不花时间讲这些东西了,如果讲这些的话呢,再用两三堂课也是讲不完的。随便谷歌就有的东西呢,我们就不再讲述。

 

--------------------------------------------------------------------------------------------------------------------------------------

我们先来回顾一下deep learning的历史,历史上呢,它是有经过好几次的沉沉浮浮的。

                       

首先在1958年呢,有一个技术叫做Perceptron(感知机)被提出来,这个技术呢,也是一个linear的model。它非常像我们在前面讲的logistic Regression,它只是没有sigmod部分而已,但它还是linear的model。感知机是在一个军方的项目中提出来的,它刚开始提出来的时候,大家都非常兴奋。

后来,MIT有一个人写了一本教科书,这本教科书就叫Perceptron,在这里面呢,他指出linear的model是有极限的。然后大家的希望就破灭了。感知机这个名字就臭掉了。

后来,就有人想说,既然一个perceptron不行,我能不能接很多perceptron。这就叫做多层感知机。事实上,multi-layer perceptron的技术在1980年代就开发的差不多了。那个时候已经开发完的技术其实就跟 今天的deep learning是没有太significant的差别的。

有一个关键的技术是1986年,Hitton提出的BP算法。那其实很多人提出了BP,但是大部分人把这个归根于Hitton的paper,它那篇paper是比较著名的。但是在那个时候遇到的问题就是,通常超过3个layer的神经网络你就train不出好的结果。

后来在1989年,有人就发现了一个理论,就是说,一个hidden layer其实就可以model任何可能的function。所以根本没有必要叠很多个hidden layers。所以这个multi-layer perceptron的方法就又臭掉了。然后大家都比价喜欢做SVM。据说那一阵子,multi-layer perceptron这个方法,也有人叫它神经网络这个方法,就像是一个脏话一样,写在paper里面,那paper就一定会被拒绝。

后来呢,有人就想到一个突破的点。这个突破的点的关键的地方就是,把它改个名字。因为这个方法已经臭掉了,所以只好改一个名字,就改成deep learning。这个又炒起来。很多人说里面有一个关键的技术,是hitton在06年提的,用RBM做initialization,很多人觉得这是个突破,甚至有一阵子呢,大家的认知是到底deep learning到底跟1980年代的多层感知机有何不同呢?它的不同之处在于,如果你有RBM去做initialization,就是做gradient descent的时候,要找一个初始的值嘛,如果是用RBM找的,就是deep learning。如果没有用RBM找,就是传统的1980年代的多层感知机。后来,大家逐渐意识到说,因为RBM这个方法非常复杂,大家觉得这么复杂,一定就是非常powerful。后来,大家试来试去,发现这一招没什么用。现在读deep learning的文献,现在已经不太有人用RBM做initialization,因为这一招带给我们的帮助呢,并没有特别大,连hitton自己都知道这一点,他在某一篇paper里面提过这一件事情,大家可能没有注意到那一篇paper就是了。但是RBM有个最强的地方,就是它让大家重新对这个model(多层感知机)有了兴趣,因为它很复杂,所以大家就开始想要研究deep learning。所以就花很多力气去研究。

有一个关键的突破,就是09年的时候,我们知道要用GPU呢,来加速。本来要一周的东西,现在可能几个小时就看到结果了。

在11年的时候,这个方法,被引入到声音识别里面,发现这招果然很有用。大家开始疯狂地用deep learning的技术。

到12年的时候,deep learning的技术赢了一个很重要的图像的比赛,在图像那边的人呢也开始疯狂的用deep learning的技术。

--------------------------------------------------------------------------------------------------------------------------------------

其实deep learning的技术并没有真的很复杂,它其实非常简单。

我们之前讲说,machine learning就是三个步骤,其实deep learning也一样就是这三个step。

                          

 

--------------------------------------------------------------------------------------------------------------------------------------

我们说在machine learning里面,第一步就是要定义一个function。在deep learning里面,这个function其实就是一个Neural Network。

                      

这个Neural Network是什么呢?
我们刚才有讲说,我们把一个Logostic Regression称之为"Neuron"。

                                    

把很多个 Logistic Regression前后连在一起,整个称之为Neural Network(神经网络)。

               

 

我们可以用不同的方法来连接这些神经元。我们用不同的方法连接Neural Network,我们就得到了不同的structure.

                          

在这个Neural Network里面,我们有一大堆的Logistic Regression,每个Logistic Regression它都有自己的weight跟自己的bias。这些weight和bias集合起来,就是这个网络的parameter,我们这边用来描述它。

          

--------------------------------------------------------------------------------------------------------------------------------------

这些神经元,我们应该怎么把它接起来呢?有各种不同的方式,怎么连接其实是你手动去设计的,是手动去连接的。最常见的连接方式呢,叫做Fully Connect Feedforward Network(全连接前馈网络)。

在Fully Connect Feedforward Network里面,你就把神经元排成一排一排的,比如,这里有6个神经元,两个一排。

                                  

每一个神经元都有一组weight和一组bias。这个weight和bias是根据training data去找出来的。

假设最左上角蓝色的神经元的weight是1和-2,bias是1。它下面的蓝色的神经元weight是-1和1,他的bias是0。假设我们先在的输入是1,-1。他的output是什么呢?

                                      

1*1+(-1)*(-2)+1 = 4,再经过sigmoid()函数,得到1/(1+e^(-4)) = 1/(1+0.0183156388887) = 0.98。同样,下面的得到0.12。

 

接下来,假设这个structure里面的每一个神经元他的weight和bias我们都是知道的,我们就可以反复进行刚才的运算。最后得到以下的结果。所以输入1跟-1,最后得到0.62和0.83。

                      

 

 如果输入是0跟0的话,经过一模一样的运算,得到的输出是0.51和0.85。

                      

 

所以一个神经网络,如果他里面的所有参数都知道的话,它就可以看做是一个function。

他的输入是一个vector,他的输出呢,也是一个vector。比如输入是[1,-1],输出是[0.62,0.83];输入是[0,0],输出是[0.51,0.85]。

所以,一个神经网络,如果我们把参数已经设上去的话,他就是一个function。

                      

 

如果我们今天不知道参数,我只是定出了这个network的structure,我只是决定了这些神经元之间我们要怎么连接在一起。这样的network structure,他其实就是定义了一个function set。我们可以给这个network设不同的参数,他就会变成不同的function。把这些可能的function统统集合起来,我们就得到了一个function set。

 

所以一个function set,你还没有learn 参数,只是把它的架构架起来,决定这些神经元怎么连接,你把连接的图画出来的时候,其实就决定了一个function set。

 

这跟我们之前学的是一样的,做Logistic  regression,做Linear Regression,我们也都是决定了一个function set。而这里,我们也是换了一种方式来决定function set。只是我们用Neural Network来决定function的时候,你的function set是比较大的,他包含了很多原来你做Logistic Regression,做Linear Regression所没有办法包含的function。

             

 

--------------------------------------------------------------------------------------------------------------------------------------

刚才讲的是一个比较简单的例子,在这个例子里面呢,我们把神经元分成一排一排的,然后每一排的neural都两两互相连接。蓝色都接给红色,红色都接给绿色。绿色后面没有别人可以接,所以就输出;蓝色前面没有其他人了,所以接输入。

 

in jeneral而言呢,我们可以把network画成这样:

                 

 

有第1排,第2排,到第L排,共L排神经元。每一排里面神经元的数目有很多,比如说1000个,2000个,每个球代表一个神经元。

layer和layer之间的neuron是两两互相连接的。Layer1的每一个神经元的output会接给Layer2的每一个神经元。Layer2的每一个神经元的输入就是Layer1的所有神经元的output。

因为Layer和Layer之间所有神经元两两间都有连接,所以它叫Fully Connect Network(全连接网络)。因为现在传递的方向呢,是从前往后传,所以叫Feedforward Network(前馈网络)。

整个network需要一个Input,这个Input呢,就是一个vector。那对每一个Layer1的每一个神经元来说,他的输入就是Input Layer的每一个dimension。最后L Layer后面没有接其他东西了,所以它的output就是整个Network的Output。假设L排有M个神经元的话,他的output就是y1,y2,...,yM。

Network的每一个Layer呢,他是有一些名字的。输入呢,叫Input Layer。output的地方呢,我们叫他Output Layer。其余的部分,我们就叫Hidden Layer。

 

--------------------------------------------------------------------------------------------------------------------------------------

所谓的deep是什么意思呢?所谓的deep就是有很多hidden layer。有人问一个问题,要几个hidden layer才叫做deep呢?这个就很难说了,有人会告诉你说要三层以上才叫做deep,有人告诉你说要8层以上才叫做deep,所以这就看每个人的定义了。本来没有deep learning 这个词的时候,大家都说,我再做neural Network,通常只有一层。自从有了deep learning以后,有一层的人他都说,我在做deep learning。所以,现在基本上,只要是neural Network base的方法的话呢,大家都会说是deep learning的方法。

 

                   

 

那到底可以有几层呢?

在2012年的时候,参加Image net 比赛获得冠军的AlexNet有8层,它的错误率是16.4%.大家可能都知道,它比第二名好的非常多,第二名的错误率是30%.

到14年的时候,VGG net有19层,他的错误率降到7.3%

GoogleNet有22层,他的错误率降到6.7%

 

但是这些都还不算什么,Residual Network有152层。把它跟GoogleNet、VGG、AlexNet比起来,他长这样。他的错误率是3.57%,其实,他这个performance是比人在同一个test上做的还要好。你可能会怀疑说,人怎么可能会在图像识别上输给机器呢?因为那个test其实还蛮难的,它给你一张狗的图,你光回答是狗还是不够的,你要回答这个是哈士奇这样。其他为了公平的比较,当时在比较的时候,那些人是事先看过training data的。也就是,人经过训练以后,还是没有机器那么强。

 

后面是跟101作一下比较。

 

还要说一下,Residual Network呢,不是一般的Fully Connect Feedforward Network。如果用Fully Connect Feedforward Network搞在这个地方,其实是有问题的,并不是overfitting,而是train都train不起来。所以,其实要特别的structure才能搞定这么深的网络。这个我们以后再讲。

                                

 

--------------------------------------------------------------------------------------------------------------------------------------

Network的操作,我们常常用矩阵运算来表示。怎么说呢?我们举刚才的例子,假设第1层的两个神经元的weight分别是1,-2;-1,1。可以把他们排成一个矩阵。当输入1,-1做运算的时候,就可以把[1,-1]当成一个向量放在右边。再加上bias。算出来就是[4,-2]。

之后再经过激活函数(不一定是sigmoid函数,现在大家都把它换成其他函数了,如果是从Logstic regression那边想过来的话呢,你会觉得是sigmoid函数,但是现在已经比较少了),假设我们用的是sigmoid()函数。把[4,-2]丢到sigmoid里面,得到的是[0.98,0.12]。

                              

 

In jeneral来说,假设第一个Layer的weight全部集合起来当做一个矩阵W1,把它的bias集合起来当做b1。第2层的weight集合起来当做W2,bias集合起来当做b2。到第L层的全部weight集合起来当做WL,bias集合起来当做bL。当给定x的时候y怎么算出来呢?

W1乘以x,再加上b1,经过sigmoid函数,得到第一层的输出a1。同样的W2乘以a1,再加上b2,经过sigmoid得到a2。这样一层一层做下去,直到最后一层,得到y。

 

                      

 

所以整个Neural Network的运算,其实就是一连串的矩阵的操作。y跟x的关系,就是下面这个样子。

                      

所以呢,一个network做的事情,就是一连串的矩阵乘以矩阵再加上矩阵,也就是一连串的矩阵运算。把这件事情写成矩阵运算的好处就是,你可以用GPU加速。

实际上呢,现在一般在用GPU做加速的时候,GPU加速并不是对神经网络做什么特化(当然现在有的GPU是对神经网络做特化,但是一般买的那种玩游戏的显卡的话,他是没有对神经网络做什么特化),你实际上拿来加速的方式是,当需要算矩阵运算的时候,CPU就call一下GPU,让它帮你做矩阵运算,这样会比用CPU来算要快。

所以我们再写神经网络的式子的时候,我们习惯把它写成矩阵操作的样子。当需要用到矩阵运算的时候,就call GPU来做。

 

--------------------------------------------------------------------------------------------------------------------------------------

整个Network,我们怎么来看待呢?

我们可以把到Output之前的部分(不含Output层),看作是一个Feature extractor。这个就代替了我们之前手动做的特征工程,做feature transformation这件事情。所以,把x输入,通过很多很多Hidden Layers,在最后一个Hidden Layer的output:x1,x2,...,xK,就可以想成是一组新的feature。

那output做的事情呢?Output-Layer就是一个Multi-class Classifier,这个多分类的分类器,它是拿第L层的output x1,x2,...,xk当做特征。它用的特征不是从x直接抽出来的,而是经过很多个Hidden Layer,做了很复杂的转换以后,抽出一组特别好的特征。这组好的特征可以被用一个简单的一个Layer的多分类分类器分得很好。

刚才讲过说,多分类分类器要通过一个softmax()函数。因为我们output Layer也看作是一个多分类的分类器,所以呢,我们最后一个Layer也会加上softmax()函数。

 

             

 

--------------------------------------------------------------------------------------------------------------------------------------

举一个不是宝可梦的例子,之后会示范一下实做这个例子。

输入一张image,它是一个手写数字。然后,output说这个input的image它对应的数字时什么。

                                                

在这个问题里面,你的input是一张image。但是对机器来说呢,一张image,它就是一个vector。假设这是一张分辨率16*16的image。它有256个像素。对机器来说呢,它就是一个256维的vector。在这个image里面,每一个像素就对应到其中的一个维度,第一个像素对应x1,第2个像素对应x2,最后一个像素代表x256。有涂黑的地方就是1,没有涂黑的地方就是0。

                                                                               

output呢。如果你用softmax,他的output代表一个概率的分布。假如output是10维的话,就可以把output看成是对应到每一个数字的概率。y1代表了输入一张图片,根据这个神经网络判断呢,是1的概率;y2代表是2的概率。

实际上就是输入一张图片,让神经网络判断属于每个数字的概率是多少。假如属于2的概率最大,是0.7,那你的机器呢,output就会说,这张image,它是数字2。

 

                               

 

--------------------------------------------------------------------------------------------------------------------------------------

在这个应用里面,假设要解决手写数字识别的问题,那你唯一需要的呢,就是一个function。这个function输入是一个256维的向量,输出是一个10维的向量。而这个function呢,就是神经网络。

                       

 

所以,你只需要丢一个神经网络。可以使用简单的Fully Connect Feedforward Network就好了。它的输入有256维,是一张image。它的输出呢,设成10维,10维里面每一个维度对应到一个数字。如果做这样的设计,输入是256维,输出是10维,那这一个网络其实就代表了一个可以拿来做手写数字识别的function set。这个function set里面,每一个function都可以拿来做手写数字识别,只是有些做出来结果比较好,有些做出来结果比较差。那接下来你要做的事情就是,用Gredient Descent去找出一组参数,去挑一个最适合来做手写数字识别的function。

 

在这个过程中,我们需要做一些设计,之前在做Logistic regression或者是Linear Regression的时候,我们对model的structure是没有什么好设计的。但是对神经网络来说,我们现在唯一的限制是输入是256维,输出是10维。但是中间要有几个隐藏层,每个隐藏层要有多少个神经元,是没有限制的。你必须要自己去设计,你要自己决定要几个Layer,每个Layer要有多少个神经元。

 

决定有多少层,每一层有多少神经元,就相当于决定了你的function set长什么样子。如果决定了一个差的function set,那里面没有包含任何好的function,那之后再在里面找最好的function,就好像是大海捞针,针不在海里这样,怎么找都找不到一个好的function。所以决定一个好的function set其实很关键,也就是决定这个Network 的结构很关键。

                    

 

讲到这里,总是会有人问一个问题。我们怎么决定层数和每层的神经元的个数呢?

答案是不知道。这个问题很难,这只能够凭着经验和直觉。神经网络长什么样,要经过直觉,多方尝试,然后想办法找一个最好的网络结构。其实找网络结构这件事情呢,并没有那么容易,有时候是蛮困难的,有时候甚至需要一些领域知识。

所以我觉得从非deep learning 的方法到deep learning的方法,我并不认为machine learning真的变得比较简单,而是我们把一个问题转化成另外一个问题了。就本来不是deep的model,我们想要得到好的结果,我们常常要做特征工程,也就是feature transform,你要找一组好的feature。但是今天做deep learning的时候,你往往不需要找一个好的feature,比如做图像识别的时候,你可以直接把像素都丢进去,硬做。但是deep learning今天制造了一个新的问题,就是你需要设计网络结构,问题从如何抽特征转化成如何设计网络结构。那deep learning是不是真的好用,这得看你觉得哪一个问题比较容易。我是觉得,如果是图像识别或者是声音识别的话,设计网络结构可能比特征工程容易,因为虽然说我们人都会看会听,但是这件事情太过潜意识了,它离我们意识的层次太远,我们无法意识到我们怎么做声音识别的。所以对人来说,你要抽一组好的特征,对人来说很难,因为你根本不知道好的feature长什么样,还不如设计一个网络结构,或者尝试各种结构,让机器自己去找出好的特征,这件事情反而变得比较容易。对图像来说也是一样。对其他task,就是case by case,比如说你有没有听过一个说法,说deep learning在NLP上面,觉得表现没有那么好。这件事情是这样,如果看图像识别或者声音识别的文献,图像和声音这两个领域是最早开始用deep learning,一用进去,进步量就非常惊人。比如说识别的错误率相对下降了20%.但如果是NLP的话,你就会觉得说,他的进步量似乎没有那么惊人。甚至很多人,认为deep learning不见得那么work。我自己的猜想是这个原因,对文字处理这件事情,人是比较强的,比如叫你设计一个方法,detect一篇文章是正面情绪还是负面情绪,你可以说,我就列表,列一些正面情绪和负面情绪的词汇,看这个文章里面正面情绪和负面情绪的词汇占多少,你可能就会得到一个不错的结果。在NLP这个task,对人来说,比较容易设计方法,这些方法往往能给你一个还不错的结果。这就是为什么deep learning相较与传统的方法,进步没有那么显著。但其实还是有一些进步的,只是没有像图像和声音领域这么显著。我觉得就长久而言呢,因为文字处理其实也是很困难的问题,里面有一些信息有可能是人也不知道的,所以deep learning,让机器自己去学这件事,还是可以占到一些优势,只是一下子,眼下看,进步没有那么显著而已。

再有就是说,有没有自动学网络结构?其实是可以的,有一些方法,不过这些方法还没有非常的普及。你看那些非常惊人的应用,比如AlphaGo什么的,都不是用这些方法做出来的。

还有一个常问的问题,那我们能不能自己设计网络结构,我可不可以不要全连接,而是第一个连到第3个,第2个连到第4个,可不可以乱接?可以,一个特殊的解法就是CNN。这个我们后面讲。

 

                

 

--------------------------------------------------------------------------------------------------------------------------------------

接下来,第2步。第2步和第3步很快,秒讲。

                     

第2步是什么呢?要定义一个function的好坏,在神经网络里面,怎么决定一组参数的好坏呢?

假设给定一组参数,要做手写数字识别,所以有一张image,跟它的label "1"。这个label告诉我们说现在的target y^是一个10维的vector,只有在第1维是1,其他的都是0。你就输入这一张image的像素,然后通过这个网络以后得到output y。

接下来要做的事情就是,计算y跟y^之间的交叉熵损失。就跟我们做多分类时,是一模一样的。

                             

接下来就是要调整参数,去让这个损失越小越好。

当然,整个training data里面,不会只有一张图片,有一大堆的data,比如第1张图片算出来的交叉熵损失是C1,第二张算出来的是C2,...,第N张算出来的是CN。

                                            

然后把所有图片的交叉熵损失加起来,得到一个Total Loss L。然后呢,接下来要做的事情,就是在function set里面,找一个function 是Loss最小。或者是找一组参数,使得Loss最小。

                                                                

怎么来做这件事情呢?

--------------------------------------------------------------------------------------------------------------------------------------

                            

 

用到的方法就是,Gredient Descent。GD大家已经太熟了,没有什么好讲的,实际上,在deep learning中的Gredient Descent 跟线性回归那边没有什么差别,是一样的,只是function变复杂了而已,其他东西都是一样的。

里面是一大堆的参数,w和b。先随便找一个初始值0.2,-0.1,...,0.3,...。接下来呢,计算一下它的gradient(计算每一个参数对Total Loss的偏微分)。

                                                             

把这些偏微分全部集合起来呢,叫做gradient:

                                                                 

有了这些偏微分以后呢,你就可以更新你的参数。用所有的参数都减到learning rate u 乘以偏微分的值,这样就得到一组新的参数。

                                                 

 

这个过程就一直进行下去,有了新的参数,再计算gradient,然后再更新参数。

                        

一直下去,就做完神经网络的训练了。

所以就这样子咯,deep learning的training就是这样。即使是AlphaGo也是用Gradient Descent train的。

                      

 

你可能会问,gradient descent 的function式子长什么样子,之前都是手把手的把算式算出来,但是在神经网络里面,function比较复杂。如果要手把手的算出来,是比较难,要花一些时间。

几年前做deep learning很痛苦,因为要自己实现backpropagation(BP ,反向传播),现在应该没有人在做这件事了。因为有太多太多的工具,可以帮你算backpropagation。反向传播算法就是算微分的比较有效的方法。很多人其实已经不会算微分了,都在使用工具。

工具很多,列一些作为参考:

            

 

--------------------------------------------------------------------------------------------------------------------------------------

最最后一个思考题。为什么我们要deep learning?

你可能会说,答案很直观,越deep,效果越好。比如下面是一个2011年的实验,越来越deep以后,error rate越来越低。

                                       

 

但是如果,稍微有machine learning的常识的话,这个结果并没有让你太surprise。因为本来有越多的参数,它cover的function set就越大,他的bias就越小。一个比较复杂的model,一个参数比较多的model,他的performance 比较好是正常的。那变deep有什么特别了不起的地方。

甚至有一个理论是这样的:任何连续的function(假设他的输入是N维的向量,输出是M维的向量),它都可以用一个隐藏层的神经网络来表示,只要这个隐藏层的神经元够多,它可以表示成任何的function。既然一个隐藏层的神经网络可以表示成任何的function,而我们需要的东西就是一个function。那做deep的意义何在呢,没有什么特别的意义啊?所以有人说,deep learning就只是一个噱头而已。因为做deep的感觉比较潮,如果变宽,就变成fat network,就感觉太虚弱了,没有办法引起大家的注意,所以大家做deep learning。真的是这样么?我们以后再讲。

 

                                         

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值