神经网路的优化(1)----**函数:梯度消失问题、ReLU、Maxout

一、sigmoid函数会导致梯度消失问题                                                                                          点击此处返回总目录

二、ReLU**函数

三、Maxout network

 

 

刚才我们说,在deep learning的recipe里面,有两个问题。所以等一下,我们就这两个问题分来来讨论,看当遇到这两个问题的时候呢,有什么样解决的方法。

                               神经网路的优化(1)----**函数:梯度消失问题、ReLU、Maxout

如果今天在training上的结果不好的时候,你可能会说,是不是你在做网络架构的设计时候,是不是设计的不好。

举例来说,你可能**函数,是对training比较不利的函数。你可能会换一些新的**函数,它们可能会给你一个比较好的结果。

                                  神经网路的优化(1)----**函数:梯度消失问题、ReLU、Maxout

 

 

一、sigmoid函数会导致梯度消失问题 

 

我们知道,在1980年代,比较常用的**函数是sigmoid函数。我们之前有稍微解释为什么使用sigmoid函数。

如果我们使用sigmoid函数,其实会发现说deeper并不一定imply better。下面是在Mnist上的结果。当Layer越来越多的时候呢,你的准确率一开始持平,后来就掉下去了。在Layer是9层10层的时候,整个结果都崩溃了。有人看到这个图,会说9层10层参数太多,overfitting。但是这个并不是overfitting,overfitting是在training set上好,在testing data上差。而这个线就是training上的结果,所以这个不是overfitting,而是training的时候就train坏了。

                       神经网路的优化(1)----**函数:梯度消失问题、ReLU、Maxout

 

一个原因就是梯度消失问题:当你把网络叠的很深的时候,在最靠近input的地方,参数对最后Loss的微分是很小的;而在比较靠近output的地方,它的微分值会是很大的。

因此当你设定同样的learning rate的时候,会发现靠近input的地方,参数的更新很慢;而靠近output的地方,它参数的更新是很快的。所以你会发现,在input几乎还是random的时候,output就已经converge(聚集)了。当input的参数还是random的时候,output的参数就已经根据这些random的结果找到了一个local minimum,然后就converge了。

这时候就会发现,参数的loss下降速度很慢,你就会觉得卡在local minimum之类的,然后就把程序停掉了。这个时候得到的结果是很差的,为什么呢?因为这个converge是几乎based on random的参数。它几乎based  on random的output,然后去converge,所以得到的结果是很差的。

 

                                神经网路的优化(1)----**函数:梯度消失问题、ReLU、Maxout

为什么会有(梯度消失)这个现象发生呢?如果你试着把BP算法写出来的话,你可以很轻易地发现说,用sigmoid函数会导致梯度消失这件事情的发生。但是我们今天不看BP的式子,我们可以从直觉上讲,为什么这件事情发生。

                                      神经网路的优化(1)----**函数:梯度消失问题、ReLU、Maxout

怎么用直觉来想,一个参数的偏微分的值是多少呢?

我们知道一个参数w,对total Loss C的偏微分,他的直觉就是说:当我对参数w做小小的变化的时候,他对cost的影响是怎么样的。

也就是说,把一个参数做小小的变化,然后观察它对cost的影响,以此来决定这个参数它的gradient的值有多大。

所以,怎么做呢?我们就把第一个hidden layer的某一个参数w加上神经网路的优化(1)----**函数:梯度消失问题、ReLU、Maxout,看看呢,对Loss有什么样的影响。

                                神经网路的优化(1)----**函数:梯度消失问题、ReLU、Maxout

 

你会发现,如果今天神经网路的优化(1)----**函数:梯度消失问题、ReLU、Maxout很大,通过sigmoid函数以后,output是会变小的。也就是说,改变了某一个参数的weight,对神经元的output会有影响,但是影响呢,是会衰减的。为什么这么说呢?假设用的是sigmoid函数,sigmoid函数会把负无穷到正无穷之间的值硬压到0-1之间,也就是说有很大的input的变化,通过sigmoid函数以后,output的变化会是很小的。所以如果神经网路的优化(1)----**函数:梯度消失问题、ReLU、Maxout很大,造成sigmoid的input有很大的变化,对sigmoid来说,他的output的变化是会衰减的。

                             神经网路的优化(1)----**函数:梯度消失问题、ReLU、Maxout

 

而每通过一次sigmoid函数,变化就衰减一次。所以当你的网络越深,他的衰减的次数就越多,知道最后它对output的影响是非常小的。也就是说,你在input的地方,改一下你的参数,对最后output的变化其实是很小的,因此最后对cost的影响也很小。因此,就造成说,靠近input的那些w的偏微分是小的。

                           神经网路的优化(1)----**函数:梯度消失问题、ReLU、Maxout

 

 

二、ReLU**函数

 

那怎么解决这个问题呢?早年的做法是train那个restricted Bolzmann Machine(受限玻尔兹曼机)。后来有人提出改一下**函数,可能就可以处理这个问题了。

现在比较常用的**函数叫做ReLU。这个函数长下面这样。z是**函数的输入,a是输出。如果输入大于0,a =z;如果输入小于0,a就为0。

那选择这样的**函数有什么样的好处呢?一是它比较快。跟sigmoid函数比起来,它的运算是快很多的。二是,如果你看bengio写的原始的paper的话呢,里面会告诉你说, 这个**函数的想法其实是有些生物上的理由的,他把这样的**函数跟一些生物上的观察呢结合在一起。三,Hitton说过,ReLU这样的**函数其实等同于是无穷多的sigmoid函数叠加的结果。第四,也是最重要的理由,它可以解决梯度消失问题。

 

                                            神经网路的优化(1)----**函数:梯度消失问题、ReLU、Maxout

 

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

 

那他是怎么解决梯度消失问题的呢?这是一个ReLU的网络,里面每个**函数都是ReLU。我们知道ReLU函数作用在两个不同的region,一个是input>0时,output=input;另一个region是,input<0,output为0。所以输出就有两个可能,一个是为0,一个是等于input。当output等于input的时候,其实这个**函数就是线性的。

                                 神经网路的优化(1)----**函数:梯度消失问题、ReLU、Maxout

对那些output是0的神经元来说,他其实对整个网络是一点影响都没有的,他根本都不会影响最后输出的值。所以如果一个神经元的输出是0的话,可以把这个神经元从网络里拿掉。

                                      神经网路的优化(1)----**函数:梯度消失问题、ReLU、Maxout

当把这些输出是0的神经元拿掉,剩下的神经元都是输出等于输入,都是线性的时候,整个网络就是一个很瘦长的线性的网络。刚才说梯度会递减是因为通过sigmoid函数,sigmoid会把比较大的input变成比较小的output。但是如果是linear的话,output等于input,就不会有梯度递减的问题了。

 

讲到这里有一个问题:如果使用ReLU的时候,整个网络变成linear的,但我们要的不是一个linear的网络。我们之所以用deep learning,就是因为我们不想我们的function是linear的,我们希望是一个非线性的,比较复杂的函数。当我们使用ReLU的时候,贬称给一个linear的function,这样不会有什么问题么?

答:整个网络其实整体来说还是非线性的。当每一个神经元他operation的region是一样的时候,它是线性的。也就是说,如果对输入只做小小的改变,不改变每个**函数输入的region(不会从a=z变成z=0,或者从a=0变成a=z),它是线性的。但是如果输入的改变比较大,改变了**函数输入的region的话(某个神经元),它就是非线性的了。

 

另外一个问题:ReLU不能微分。之前说做gradient descent的时候,要可以对loss function 做微分。意思是要对网络可以做微分。你的神经网络要是可微的。而ReLU不可微啊,至少在0点是不可微的。怎么办呢?

其实实做时是这样子,当z大于0时,微分就是1。当小于0时,微分就是0。反正不可能input的值正好是0,就不要管它。

 

 

三、Maxout network

 

ReLU其实还有种种变形。

有人说,ReLU在input<0的时候,output会是0,微分是0,这个时候就没有办法update你的参数了。所以,我们要在input<0的时候,output还是有一点点的值,比如说output是input乘上0.01。这个叫做Leaky ReLU。

这个时候,就会有人说,为什么是0.01呢?为什么不是0.07,0.08之类的呢?所以又有人提出了Parametric ReLU。在负的这边呢,output等于input乘上一个神经网路的优化(1)----**函数:梯度消失问题、ReLU、Maxout,而神经网路的优化(1)----**函数:梯度消失问题、ReLU、Maxout是一个网络的参数,它可以通过training data被学出来,每个神经元都可以有不同的神经网路的优化(1)----**函数:梯度消失问题、ReLU、Maxout值。

                                         神经网路的优化(1)----**函数:梯度消失问题、ReLU、Maxout

 

但是又有人会说,为什么要是ReLU这个样子呢?可不可以是别的样子。所以后来又有了更进阶的想法,叫做Maxout network。在Maxout network里面呢,就是让你的网络去自动学它的**函数。因为现在**函数是自动学出来的,所以ReLU就只是Maxout network的一个特例。Maxout network可以学出ReLU这样的**函数,也可以是其他的**函数。根据training data 决定现在的**函数长什么样子。

 

Maxout长什么样子呢?假设现在输入是2维的向量[x1,x2]。我们把[x1,x2]乘上不同的weight,变成5。再乘上不同的weight得到7。再乘不同的weight得到-1。再乘不同的weight得到1。

本来5、7、-1、1这些值呢,要通过一个**函数得到另外一个值,但是现在在maxout network里面,我们做的事情是这样子:把这些value 分组(哪些值应该被分组,是实现决定的),比如5和7是一组,-1和1是一组。然后再同一个组里面选一个值最大的,作为output。其实这件事跟max-pooling一模一样,只不过不是在image上做max-pooling,而是在一个Layer上面做max-pooling。得到的值是7和1。你可以把红色框框中的看成是一个神经元。只不过它的输入是一个向量,而不是一个值。

接下来,7和1又乘上不同的weight,得到另外一排不同的值1,2,4,3,然后一样分组、从每个分组中求最大值,得到2,4。

在实做上,几个元素放在一组,是可以自己决定的。它就跟网络结构一样,是可以自己调的参数,可以不是两个,可以是3个、4个、5个啊都可以,是你自己决定的。

                                                    

                             神经网路的优化(1)----**函数:梯度消失问题、ReLU、Maxout

 

我们现在先解释,maxout是可以做到跟ReLU一模一样的事情,它可以模仿ReLU这个**函数。

怎么做呢?假设我们现在有一个ReLU的**函数,z= wx+b ,而a=max{0,wx+b}。所以,今天如果用ReLU**函数,它的输出a和输入x之间的关系是左下图绿色这样。

如果今天使用maxout network,把input x乘上w,加上b 得到z1;再用x乘上另外一组weight 加上另外一组bias,得到z2。假设这另外一组weight和bias都是0,那么z2就是0。然后分组,选最大值,就得到a。所以a = max{z1,z2} = max{z1,0} = max{wx+b , 0}

所以,只要maxout的wb设好,就可以让maxout的input、output的关系等于ReLU的input、output的关系。

由此可知,ReLU是maxout可以做得到的事情,只要它设定出正确的参数。

 

                                         神经网路的优化(1)----**函数:梯度消失问题、ReLU、Maxout

但是,maxout可以做出更多不同的**函数。比如说,现在另外两个参数不是0,而是w',b'。就会得到蓝色线z1和红色线z2。这样就得到了一个不一样的**函数。这个**函数长什么样子,是有w,b,w',b'决定的。所以这个**函数是一个Learnable的**函数。

 

                                        神经网路的优化(1)----**函数:梯度消失问题、ReLU、Maxout

 

还有,就是Maxout可以做出任何的piecewise linear convex function(分段线性凸函数)。如果看一下它的性质,就不难理解。至于piecewise linear convex function里面有多少个piece,就决定于你现在把多少个elements放到一个组。假设2个elements一个group,可以有ReLU函数,可以有去绝对值的函数;假设3个一组,可以长成类似下面这样。

                             神经网路的优化(1)----**函数:梯度消失问题、ReLU、Maxout

 

接下来,面对的问题就是,maxout这个东西怎么train?max()这个东西不能微分,怎么train呢?

这个做法是这样的,假设现在每组中比较大的是红色框框的值。

 

                      神经网路的优化(1)----**函数:梯度消失问题、ReLU、Maxout

那比较大的值,就会等于max操作的output。所以max操作其实就是线性的的操作。只是他会选择每组中某一个element。

                        神经网路的优化(1)----**函数:梯度消失问题、ReLU、Maxout

而没有接到的元素,其实就没有用,他们不影响网络的output,就可以拿掉。所以,在做maxout的时候,当给他一个input的时候,其实也是得到一个比较细长的linear 网络,所以在训练的时候,train的是这个比较细长的网络里面的参数,是这些练到红色框框的参数。就用BP算法train就好了。

                         神经网路的优化(1)----**函数:梯度消失问题、ReLU、Maxout

 

这时候,可能会有一个问题。没有被train到的参数怎么办呢?那些没有连到最大的框框的weight怎么办呢?

这看起来表面是一个问题,但实做上不是一个问题。因为当给他不同的input的时候,得到的这些z的值是不一样的。所以每次给不同的input的时候,网络的结构是不一样的。而我们有很多很多比training data,网络结构不断变换,最终每一个weight都会被train到。

CNN中的maxpooling也是这样的原理。会train maxout,就会train maxpooling。