李宏毅深度学习——Tips for Deep Learning

目录

一、神经网络的表现 

二、改进神经网络

(一)梯度消失以及改进办法

(二)Adaptive Learning Rate

(三)Local minimize问题

三、解决overfitting

(一)Early Stopping

(二)Regulation

(三)Dropout


一、神经网络的表现 

建立deep learning的三个步骤

  • define a set function
  • goodness of function
  • pick the best function

做完这些事之后我们可以得到一个neural network。在得到neural network之后,我们需要判断神经网络的表现。

首先我们需要检查,这个神经网络在我们的training set上有没有好的结果(是否陷入局部最优),没有的话,回头看,是那个步骤出了什么问题,我们可以做一些修改来保证在training data上取得好的解。

  • New Activation Function
  • Adaptive Learning Rate

假如我们在training set上得到了一个好的结果,然后再把nerual network放在testing set,testing set上的performance才是我们关心的结果。如果在testing data上的performance不好,才是ovefitting。(注意:如果在training set上结果就不好,不能说是overfitting的问题)

  • Early Stopping
  • Regalarization
  • Dropout

如果training set上的结果变现不好,那么就要去neural network在一些调整,如果在testing set表现的很好,就意味成功了。

在testing data上看到一个56-layer和20-layer,显然20-layer的error较小,那么你就说是overfitting,那么这是错误的。首先你要检查你在training data上的结果。

在training data上56-layer的performance本来就比20-layer变现的要差很多,在做neural network时,有很多的问题使你的train不好,比如local mininmize等等,56-layer可能卡在一个local minimize上,得到一个不好的结果,这样看来,56-layer并不是overfitting,只是没有train的好。

二、改进神经网络

当我们在training data上的performance不好时,我们应该考虑是不是我们的nerual的架构不好,是不是我们选择的激活函数不好。

例如:上图中,在2006年以前,如果将网络叠很多层,往往会得到下图的结果。上图,是手写数字识别的训练准确度的实验,使用的是sigmoid function。可以发现当层数越多,训练结果越差,特别是当网络层数到达9、10层时,训练集上准确度就下降很多。但是这个不是当层数多了以后就overfitting,因为这个是在training set上的结果。

在之前可能常用的activation function是sigmoid function,今天我们如果用sigmoid function,那么deeper usually does not imply better,这个不是overfitting

(一)梯度消失以及改进办法

当网络比较深的时候,会出现梯度消失问题,比较靠近input的几层Gradient值十分小,靠近output的几层Gradient会很大,当你设定相同的learning rate时,靠近input layer的参数updata会很慢,靠近output layer的参数updata会很快。当前几层都还没有更动参数的时候(还是随机的时候),随后几层的参数就已经收敛了。

为什么靠近前几层的参数会特别小呢?

怎么样来算一个参数对total loss做偏微分,实际上就是对参数做一个小小的变化,对loss的影响,就可以说,这个参数gradient的值有多大。给第一个layer的某个参数加上△w时,对output与target之间的loss有什么样的变化。现在我们的△w很大,通过sigmoid function时这个output会很小(一个large input,通过sigmoid function,得到small output),每通过一次sogmoid function就会衰减一次(因为sogmoid function会将值压缩到0到1之间,将参数变化衰减),hidden layer很多的情况下,最后对loss的影响非常小(对input修改一个参数其实对output是影响是非常小)。理论上我们可以设计dynamic的learning rate来解决这个问题,确实这样可以有机会解决这个问题,但是直接改activation function会更好,直接从根本上解决这个问题。

如何解决?

ReLU Activation Function作用于两个不同的range,一个range是当activation input大于0时,input等于output,另外一个是当activation function小于0时,output等于0

那么对那些output等于0的neural来说,对我们的network一点的影响都没。加入有个output等于0的话,你就可以把它从整个network拿掉。(下图所示) 剩下的input等于output是linear时,你整个network就是a thinner linear network。


我们之前说,gradient descent递减,是通过sigmoid function,sigmoid function会把较大的input变为小的output,如果是linear的话,input等于output,你就不会出现递减的问题。

我们需要的不是linear network(就像我们之所以不使用逻辑回归,就是因为逻辑回归是线性的),所以我们才用deep learning ,就是不希望我们的function不是linear,我们需要它不是linear function,而是一个很复杂的function。对于ReLU activation function的神经网络,只是在小范围内是线性的,在总体上还是非线性的

如果你只对input做小小的改变,不改变neural的activation range,它是一个linear function,但是你要对input做比较大的改变,改变neural的activation range,它就不是linear function。

改进1:leaky ReLU:ReLU在input小于0时,output为0,这时微分为0,你就没有办法updata你的参数,所有我们就希望在input小于0时,output有一点的值(input小于0时,output等于0.01乘以input),这被叫做leaky ReLU。

改进2:Parametric ReLU:在input小于0时,output等于zα为neural的一个参数,可以通过training data学习出来,甚至每个neural都可以有不同的α值。

改进3:Maxout:ReLU是一个特殊的Maxout,Maxout可以让一个网络去自动学习它的Activation Function

input是x1,x2,x1,x2乘以weight得到5,7,-1,1。这些值本来是通过ReLU或者sigmoid function等得到其他的一些value。现在在Maxout里面,在这些value group起来(哪些value被group起来是事先决定的,如上图所示),在组里选出一个最大的值当做output(选出7和1,这是一个vector 而不是一个value),7和1再乘以不同的weight得到不同的value,然后group,再选出max value。
怎么分组是我们自己决定的。

对比ReLu和Maxout

  • ReLu:input乘以w,b,再经过ReLU得a。
  • Maxout:input中x和1乘以w和b得到z1,z2,x和1乘以w和b得到z2,z2(现在假设第二组的w和b等于0,那么z2,z2等于0),在两个中选出max得到a(如上图所示) 现在只要第一组的w和b等于第二组的w和b,那么Maxout做的事就是和ReLU是一样的。

当然在Maxout选择不同的w和b做的事也是不一样的(如上图所示),每一个Neural根据它不同的wight和bias,就可以有不同的activation function。这些参数都是Maxout network自己学习出来的,根据数据的不同Maxout network可以自己学习出不同的activation function。        ​​​​​​​        

 Maxout中的激活函数可以被分段为多个线性的凸函数,多少段取决于之前我们分组后一组元素的个数。

max operation用方框圈起来,当我们知道一组值中的哪一个比较大的时候,max operation其实在这边就是一个linear operation,只不过是在选取前一个group的element。把group中不是max value拿掉。

没有被training到的element,那么它连接的w就不会被training到了,在做BP时,只会training在图上颜色深的实线,不会training不是max value的weight。这表面上看是一个问题,但实际上不是一个问题。

当你给到不同的input时(training data有很多),得到的z的值是不同的,max value是不一样的,因为我们有很多training data,而neural structure不断的变化,实际上每一个weight都会被training。 

(二)Adaptive Learning Rate

在前面我们在学习Regression的时候介绍过一个自适应的Learning Rate的方法Adagrad,但是这是不够的,这里介绍了一个进阶版本RMSProp。

同一方向上,考虑同一个参数w1,参数在绿色箭头处,可能会需要learning rate小一些,参数在红色箭头处,可能会需要learning rate大一些。

一个固定的learning rate除以一个σ(在第一个时间点,σ就是第一个算出来GD的值),在第二个时间点,你算出来一个g1,σ1(你可以去手动调一个α值,把α值调整的小一点,说明你倾向于相信新的gradient)告诉你的这个error surface的平滑或者陡峭的程度。

(三)Local minimize问题

除了learning rate问题以外,我们在做deep learning的时候,有可能会卡在local minimize,也有可能会卡在saddle point,甚至会卡在plateau的地方。

其实在error surface上没有太多的local minimize,所以不用太担心。因为,你要是一个local minimize,你在一个dimension必须要是一个山谷的谷底,假设山谷的谷底出现的几率是P,因为我们的neural有非常多的参数(假设有1000个参数,每一个参数的dimension出现山谷的谷底就是各个P相乘),你的Neural越大,参数越大,出现的几率越低。所以local minimize在一个很大的neural其实没有你想象的那么多。

使用现实世界的一个方法处理上述问题:在真实的世界中,在如图所示的山坡中,把一个小球从左上角丢下,滚到plateau的地方,不会去停下来(因为有惯性),就到了山坡处,只要不是很陡,会因为惯性的作用去翻过这个山坡,就会走到比local minimize还要好的地方,所以我们要做的事情就是要把这个惯性加到GD里面(Mometum)。

我们每次移动的方向,不再只有考虑gradient,而是现在的gradient加上前一个时间点移动的方向。

 

加上Momentum之后,每一次移动的方向是negative gardient加上Momentum的方向(现在这个Momentum就是上一个时间点的Moveing)。现在假设我们的参数是在这个位置(左上角),gradient建议我们往右走,现在移动到第二个黑色小球的位置,gradient建议往红色箭头的方向走,而Monentum也是会建议我们往右走(绿的箭头),所以真正的Movement是蓝色的箭头(两个方向合起来)。现在走到local minimize的地方,gradient等于0(gradient告诉你就停在这个地方),而Momentum告诉你是往右边的方向走,所以你的updata的参数会继续向右。如果local minimize不深的话,可以借Momentum跳出这个local minimize。

Adam =(RMSProp + Momentum)

三、解决overfitting

(一)Early Stopping

随着你的training,你的total loss会越来越小(learning rate没有设置好,total loss变大也是有可能的),training data和testing data的distribute是不一样的,在training data上loss逐渐减小,而在testing data上loss逐渐增大。理想上,假如你知道testing set上的loss变化,你应该停在不是training set最小的地方,而是testing set最小的地方(如图所示),可能training到这个地方就停下来。但是你不知道你的testing set(有label的testing set)上的error是什么。所以我们会用validation集解决
会validation set模拟testing set,什么时候validation set最小,你的training会停下来

(二)Regulation

重新去定义要去minimize的那个loss function。在原来的loss function(minimize square error, cross entropy)的基础上加一个regularization term(L2-Norm),在做regularization时是不会加bias这一项的,加regularization的目的是为了让线更加的平滑(bias跟平滑这件事情是没有任何关系的)。

在update参数的时候,其实是在update之前就已近把参数乘以一个小于1的值(ηλ都是很小的值),这样每次都会让weight小一点。最后会慢慢变小趋近于0,但是会与后一项梯度的值达到平衡,使得最后的值不等于0。L2的Regularization又叫做Weight Decay,就像人脑将没有用的神经元去除。regularization term当然不只是平方,也可以用L1-Norm。

w是正的微分出来就是+1,w是负的微分出来就是-1,可以写为sgn(w)。

每一次更新时参数时,我们一定要去减一个ηλsgn(wt)(w值是正的,就是减去一个值;若w是负的,就是加上一个值,让参数变大)。

L2、L1都可以让参数变小,但是有所不同的,若w是一个很大的值,L2乘以一个小于1的值,L2下降的很快,很快就会变得很小,在接近0时,下降的很慢,会保留一些接近0的值;L1的话,减去一个固定的值(比较小的值),所以下降的很慢。所以,通过L1-Norm training 出来的model,参数会有很大的值。

(三)Dropout

怎么训练

在train的时候,每一次update参数之前,对network里面的每个neural(包括input),做sample(抽样)。 每个neural会有p%会被丢掉,跟着的weight也会被丢掉。

为什么Dropout会有用

training的时候会丢掉一些neural,就好像使在练习轻功一样在脚上绑上一些重物,然后实际上战斗的时候把重物拿下来就是testing时(没有进行dropout),那时候你就会变得很强。

另外一个很直觉的理由是:在一个团队里面,总是会有人摆烂(摆烂,指事情已经无法向好的方向发展,于是就干脆不再采取措施加以控制而是任由其往坏的方向继续发展下去),这是会dropout的。

假设你觉得你的队友会摆烂,所以这个时候你就想要好好做,你想要去carry他。但实际上在testing的时候,大家都是有在好好做,没有需要被carry,因为每个人做的很努力,所以结果会更好。

testing时为什么要乘以(1-p)%

假设dropout rate是50 percent,那在training的时候总是会丢掉一般的neural。假设在training时learning好一组weight(w1,w2,w3,w4),但是在testing时没有dropout,对同一组weights来说:在training时得到z,在testing是得到z′。但是training和testing得到的值是会差两倍的,所以在做testing时都乘以0.5,这样得到的结果是比较match:z=z′。

其实dropout还是有很多的理由,这个问题还是可以探讨的问题,你可以在文献上找到很多不同的观点来解释dropout。我觉得我比较能接受的是:dropout是一个终极的ensemble方法。ensemble的意思是:我们有一个很大的training set,每次从training set里面只sample一部分的data。我们之前在讲bias和variance时,打靶有两种状况:一种是bias很大,所以你打准了;一种是variance很大,所以你打准了。如果今天有一个很复杂的model,往往是bias准,但variance很大。若很复杂的model有很多,虽然variance很大,但最后平均下来结果就很准。所以ensemble做的事情就是利用这个特性。我们可以training很多的model(将原来的training data可以sample很多的set,每个model的structures不一样)。虽然每个model可能variance很大,但是如果它们都是很复杂的model时,平均起来时bias就很小。

在training时train了很多的model,在testing时输入data x进去通过所有的model(Network1, Network2, Network3, Network4),得到结果(y1​,y2​,y3​,y4​),再将这些结果做平均当做最后的结果。

第一个、第二个、第三个、第四个minibatch如图所示,所以在进行dropout时,是一个终极ensemble的方式。假设有M个neurons,每个neuron可以dropout或者不dropout,所以可能neurons的数目为2^M,但是在做dropout时,你在train2^Mneurons。

每次只用one mini-batch去train一个neuron,总共有可能的neuron。最后可能update的次数是有限的,你可能没有办法把的neuron都train一遍,但是你可能已经train好多的neurons。每个neuron都用one mini-batch来train,每个neuron用一个batch来train可能会让人觉得很不安(一个batch只有100笔data,怎么可能train整个neuron呢)。这是没有关系的,因为这些不同neuron的参数是共享的。

在testing的时候,按照ensemble方法,把之前的network拿出来,然后把train data丢到network里面去,每一个network都会给你一个结果,这些结果的平均值就是最终的结果。但是实际上没有办法这样做,因为network太多了。所以dropout最神奇的是:当你把一个完整的network不进行dropout,但是将它的weights乘以(1-p)percent,然后将train data输入,得到的output y。神奇的是:之前做average的结果跟output y是approximated

解释为什么是approximated

w1*2/4=(w1)/2   w2*2/4=(w2)/2,在线性模型中ensemble和weight乘以一个系数是equivalent。非线性模型不是equivalent的,但是结果依然是work的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值