李宏毅机器学习-----做深度学习的一些Tips

Tips for deep learning

在这里插入图片描述
上面的步骤我们都非常熟悉了,定义模型,评估模型,选择最好的function,得到神经网络,检查在训练集中的表现,然后检查在测试集中的表现。

  • 为什么要做训练集的检查?
    在传统机器学习中,通常在训练集都会表现得比较好,但是在神经网络中,不一定会表现得好,有可能陷入了局部最优,这是需要回头检查哪个步骤出了什么问题,你可以做什么样的修改,在training set得到好的结果。

  • 为什么要做测试集检查?
    假如说你在training set得到了一个好的performance了,然后再把neural network放在你的testing data,testing set的performance才是我们关心的结果。 在 t r a i n i n g d a t a 获 得 好 的 p e r f o r m a n c e 的 前 提 下 , t e s t i n g d a t a \color{red}{在training data获得好的performance的前提下,testing data} trainingdataperformance,testingdata 上 表 现 的 不 好 , 才 是 o v e r f i t t i n g \color{red}{上表现的不好,才是overfitting} overfitting
    在这里插入图片描述
    有时候我们不能认为问题都是overfitting,这里有个例子:

例如,单看右图时,在testing data上,56层的error rate要比20层的要高,这个时候,你就可以说56层因为参数过多,所以overfitting了吗?在神经网络中这样直接判断是 错 误 的 \color{red}{错误的} !!!你必须先检查一下你的training data上的结果。

看回左图,明显看到56层的performance是比20层差的,在做神经网络的时候,其实会有很多问题导致你train得不好,例如局部最优,56层可能卡在局部最优得地方,所以表现才这么差,所以56层并没有overfitting,只是在train的时候,已经出问题了。

  • 有人会问,那56层这个神经网络算是underfitting吗?
    对Underfitting的理解是这个model的参数不够多,所以model的能力不足以解决这个问题。
    其实也不算是,因为56层的参数肯定是比20层多的,你20层能做得好的事情,50层会可能做不好吗? 50层都已经包括了20层所有的参数,还添加了额外的参数,从理论上说,50层必然比20层表现得好的。
    在这里插入图片描述
  • 当你看到一个方法,你要知道它要解决什么样的问题?
    例如dropout,dropout是在training data表现好,testing data上表现不好的时候才会去使用,当training data 结果就不好的时候用dropout 往往会越训练越差。
    【随机失活(dropout)在学习过程中通过将隐含层的部分权重或输出随机归零,降低节点间的相互依赖性,从而实现神经网络的正则化,降低其结构风险】

如何解决神经网络遇到的问题?

下面将会针对training表现不好的这方面,给出一些修改建议

1.改变激活函数

在这里插入图片描述
当training 的结果不好,你可以思考一下,是否你的Network的架构有问题?activation function不适用?
在这里插入图片描述
在2006年以前,如果将网络叠很多层,往往会得到上图的结果。上图,是手写数字识别的训练准确度的实验,使用的是sigmoid function。可以发现当层数越多,训练结果越差,特别是当网络层数到达9、10层时,训练集上准确度就下降很多。但是这个不是当层数多了以后就overfitting,因为这个是在training set上的结果。

梯度消失Vanishing Gradient

在这里插入图片描述
在神经网络的layer比较深的时候,会出现梯度消失现象。

  • 什么是梯度消失?
    靠近input的layer的梯度值很小,靠近output的layer的梯度很大,当learning rate相同时,靠近input的layer的参数会更新得很慢,而靠近output的layer得参数会更新得很快,在input的参数几乎是随机的时候,output已经可以通过这些随机的结果找到一个local minimize,快要收敛了
    在这里插入图片描述
    用sigmoid function会导致这个事情发生,当我们计算参数w对total loss做偏微分的时候,实际意义是对参数进行一个小小的变化,会对cost产生一个影响,由此来决定这个参数的gradient有多大。

我们可以做一个试验,给第一个layer的某个参数加上△w时,对output与target之间的loss有什么样的变化。

现在我们改变某个参数的weight,让△w很大,通过sigmoid function时这个output会变小(一种影响),每通过一次sigmoid function就会衰减一次(影响的程度变小),因为sigmoid function会把所有的值压缩到0到1之间,如果你有很大的input,通过sigmoid以后,你的output的变化是很小的。当层数越深,衰减得越多,对最后的output的地方的影响就很小。

怎么去解决梯度消失

在这里插入图片描述
修改activation function,ReLU input 大于0时,input 等于 output,input小于0时,output等于0。

使用这个function的好处

  1. 比sigmoid function比较起来是比较快的
  2. 考虑到一些生物研究
  3. 等同于无穷多的sigmoid function叠加在一起的结果(sigmoid带有不同的bias)
  4. 可以处理 vanishing gradient problem(下面讲解为何可以解决)
    在这里插入图片描述
    ReLU是作用在两个范围,一个是大于0,一个是小于0
    对那些output等于0的neural来说,对我们的network一点的影响都没。加入有个output等于0的话,你就可以把它从整个network拿掉。(下图所示) 剩下的input等于output是linear时,你整个network就是a thinner linear network
    在这里插入图片描述
    之前sigmoid funcion会把很大的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。【这里要慢慢琢磨一下,不好理解】
在这里插入图片描述
第一种改进:当input小于0时,output为0,微分值也是0,这样会导致你无法update参数,所以我们希望input小于0时有值,就让output等于0.01乘以input,这叫“leaky ReLU”

第二种改进:Parametric ReLU在input小于0时,output等于 α z \alpha z αz为neural的一个参数,可以通过training data学习出来,甚至每个neural都可以有不同的 α \alpha α值。
在这里插入图片描述
第三种改进:让network自动学习属于它的激活函数,ReLU就是一种特殊的Maxout case。

看图很好理解,例子的input是个二维向量,乘以weight,得到4个数,然后把value group起来,group多少个element是我们自己事先决定,在group里挑出最大的值作为output,然后重复这个操作。
在这里插入图片描述
Maxout是怎么做到跟ReLU一样的事情呢?

ReLu:input乘以w,b,再经过ReLU得a。
Maxout:input中x和1乘以w和b得到z1,z2,x和1乘以w和b得到z2,z2(现在假设第二组的w和b等于0,那么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 network中有两个pieces,如果Maxout network中有三个pieces,Maxout network会学习到不同的activation function如下图。
在这里插入图片描述
这个max函数是无法微分的,该怎么train?其实只要可以算出参数的变化,对loss的影响就可以用梯度下降来train网络。
在这里插入图片描述
假设最大值我们用红色框框住,当你知道在一组值里面哪一个比较大的时候,max operation其实在这边就是一个linear operation,只不过是在选取前一个group的element。把group中不是max value拿掉。
在这里插入图片描述
有个问题是,如果只是选择最大值,那么那些不是最大值的那条线就可以不用看了,不会training不是max value的weight,其实这不是一个问题!

当你给到不同的input时,得到的z的值是不同的,max value是不一样的,因为我们有很多training data,而neural structure不断的变化,实际上每一个weight都会被training。例如,x1求出来是z1最大,但是x2求出来是z2最大,其实所有的weight都会被train到的。

2. Adaptive Learning Rate

在这里插入图片描述
之前有提过Adagrad,每一个parameter 都要有不同的learning rate,这个 Adagrd learning rate 就是用固定的learnin rate除以这个参数过去所有GD值的平方和开根号,得到新的parameter。
在这里插入图片描述
考虑的情况是,不同方向的w,给它对应的大小的learning rate
在这里插入图片描述
在做deep learning的时候,error surface可以是任何形状,例如上图,你在同一个方向,却有一些地方平坦(需要小的学习率),一些地方陡峭(需要大的学习率),learning rate是要能够快速的变动。所以有了RMSProp。(该方法是Hinton在上课的时候提出来的,找不到对应文献出处)。
在这里插入图片描述
这个方法和Adagrad唯一不同的地方是,Adagrad的分母是之前所有的gradient的平方和取算术平方根。而RMSProp是一个 σ t \sigma^t σt

σ t = α ( σ t − 1 ) 2 + ( 1 − α ) ( g t ) 2 \sigma^t=\sqrt{\alpha(\sigma^{t-1})^2+(1-\alpha){(g^t)}^2} σt=α(σt1)2+(1α)(gt)2

这个 α \alpha α是让我们手动调整的,把α值调整的小一点,说明你倾向于相信新的gradient 告诉你的这个error surface的平滑或者陡峭的程度
在这里插入图片描述
除了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还要好的地方,我们要做的就是模拟这个过程,把惯性加到gradient descent,我们叫 M o m e t u m \color{blue}{Mometum} Mometum

首先需要复习一下一般gradient descent的内容:
在这里插入图片描述
选择一个初始的值,计算它的gradient,Gradient的负梯度方向乘以learning rate,得到θ1,然后继续前面的操作,一直到gradinet等于0时或者趋近于0时。
在这里插入图片描述
Momentum的作用就是,在我们每一次移动的时候,不再只考虑gradient,而是在考虑gradient的同时,考虑前一个时间点移动的方向。
像上图那样,gradient是红色线,同时我们也要考虑绿色线(前一个点移动的方向),最后才得出蓝色线。 λ \lambda λ 的作用是告诉你惯性的影响有多大.
在这里插入图片描述
v i v^i vi是代表之前的点移动的方向,从公式上看,第i个时间点就是过去所有gradient的总和
在这里插入图片描述
上图是直观的表示,加上Momentum之后,每一次移动的方向是 negative gardient加上Momentum的方向

在local minimize的位置,gradient等于0(gradient告诉你就停在这个地方),而Momentum告诉你是往右边的方向走,所以你的updata的参数会继续向右。如果local minimize不深的话,可以借Momentum跳出这个local minimize
在这里插入图片描述
Adam是比较多人用的,RMSProp加上Momentum就是Adam, m 0 m_0 m0就是momentum,前一个时间点的movement; v 0 v_0 v0是RMSProp里面的 σ \sigma σ


下面将会针对training表现得好,但是testing表现不好这方面,给出一些修改建议
在这里插入图片描述

Early Stopping

在这里插入图片描述
如果learning rate设置得好得话,training 的loss应该是慢慢变小的,但是training和testing的分布不完全一样,有可能training的loss在下降,而testing在上升。所以假如我们知道testing的loss的变化,我们就知道应该停在testing set上Loss最小的地方。然而实际上我们并不知道,所以实际上我们使用validation set去验证这个事情。即当validation set在loss最小的时候,我们就停止training。

Regularization

在这里插入图片描述
在这里插入图片描述
之前我们加上了正则化,是为了让function看上去更加的平滑,而bias和平滑度是没有关系的,所以没有加上去,只考虑weight。上图使用了L2惩罚项,是所有的w的平方和。(回忆一下:正则化的目的是为了防止过拟合,正则化方法会自动削弱不重要的特征变量)
在这里插入图片描述
然后我们得到一个新的Loss function L ′ L^{\prime} L,就是原来的loss function加上L2惩罚项,对新的loss funciton做gradient descent,然后更新参数的时候,可以把 L ′ L^{\prime} L分解一下,得到上图最后一条式子,其实就是变成每次你在update参数之前,乘上 ( 1 − η λ ) (1-\eta \lambda) (1ηλ) η \eta η就是learning rate, λ \lambda λ通常也会设置为一个很小的值(如0.001),所以通常KaTeX parse error: Undefined control sequence: \lshiambda at position 9: (1-\eta \̲l̲s̲h̲i̲a̲m̲b̲d̲a̲)是一个接近1的值(如0.99),这样会让你的参数越来越接近零。就是每一次你update参数,都会让参数先乘上一个小于1的值,慢慢靠近零。

但是不用担心,会与后一项求微分的值达到平衡,使得最后的值不等于0,使用L2惩罚项会使weight慢慢变小,L2的Regularization 又叫做Weight Decay,就像人脑将没有用的神经元去除.
在这里插入图片描述
当然,我们除了使用L2,也可以使用L1惩罚项,有人会认为绝对值不可以微分啊?然而实际上,绝对值就是个“V”的形状,w是正的微分出来就是+1,w是负的微分出来就是-1,只有0的位置无法微分,就直接给个0就好了,最后可以写为sgn(w)。

所以我们会发现,每一次更新时参数时,我们一定要去减一个 η λ s g n ( w t ) \eta \lambda sgn(w^t) ηλsgn(wt)值。
【w是正的,就是减去一个值;若w是负的,就是加上一个值,让参数变大】

比较一下L1和L2:

  • 它们都是让参数变小了
  • 若w是一个很大的值,L2会下降得很快,参数很快就会变得很小,在接近0时,下降的很慢,会保留一些接近0的值
  • L1的话,减去一个固定的值(比较小的值),所以下降的很慢。通过L1-Norm training 出来的model,参数会有很大的值。但是出来的值比较稀疏,有很多接近0的值,也有一些很大的值
  • 在这里插入图片描述
  • 上面是一个婴儿成长的脑神经的图片,一开始神经元慢慢增多,到后面就会减少,我们的神经网络也一样,因为有一些weight很久没有去update它,它就会越来越小,最后就接近0.

Dropout

在这里插入图片描述
在这里插入图片描述
在traning的时候,每一次update参数之前,对network里面的每个neural(包括input),做sampling。 每个neural会有p%会被丢掉,跟着的weight也会被丢掉。
在这里插入图片描述
network structure就会变瘦了(thinner),然后,我们再去train这个细长的network,因为每一次update都要做一次这个sampling的操作 ,所以每次update参数时,你拿来training network structure是不一样的。【其实这样做performance是会变差的,因为neuron不见了,不过dropout的目的是虽然你的training效果变差了,但是你的testing是会变好的】
在这里插入图片描述
在Testing的时候,不做dropout。如果在training的时候,dropout rate是p%,那么在testing时,所有weight要乘上 ( 1 − p ) (1-p)% (1p)。例如dropout rate是50%,如果training的w=1,那么testing 要设置w为0.5

为什么dropout有用?

在这里插入图片描述
为什么在训练的时候要dropout,但是测试的时候不dropout?
看过火影都知道,就像小李一样,假如你在练习轻功的时候,你在脚上绑了一些重物(training),实际上在战斗把重物拿下来(testing),那么你就会变得很强
在这里插入图片描述
另一个比喻:当你和同学组队去做一个项目的时候,(training)你会觉得你的队友不太行,所以你要好好做,希望carry你的队友,但是当到最后(testing)时,你会发现大家都做得很好,所以最终会获得一个好的结果。 所以在testing的时候不用dropout
在这里插入图片描述
为什么testing的weight要乘以(1-p)%?

假设dropout rate是50%,training的时候,你总是会期望丢掉一半的neuron。假设选定一组weight(w1,w2,w3,w4)。testing时是没有dropout的,所以对同一组的weihgt来说testing的时候和training时候的z有一个很明显的差距,他的期望约等于training的两倍。所以,我们要把所有的weight都乘以0.5,把差距拉回来。

dropout是种ensemble的方法

在这里插入图片描述
ensemble方法就是 从一个很大的Training set中,每次从training set里只sample一部分的data,然后training 很多的model(每个model的结构可能不一样),虽然每个model可能variance很大,但是他们如果都是很复杂的model的话,平均起来,bias就会很小。
在这里插入图片描述
所以到testing的时候,放入test data,每个model出一个结果,把结果平均起来,如果model很复杂的话,这招很有用。随机森林就是使用这个方法,如果只用决策树,很容易就overfitting,但是随机森林就没那么容易overfitting
在这里插入图片描述
每拿一次minibatch,就会做一次sample,在做dropout时就像是在做终极版本的ensemble,因为你每一次更新参数都会train一个network出来,假设你有M个神经元,这M个神经元有可能或者没有被dropout,所以你有 2 M 2^M 2M种可能的network的结构。

  • 有个问题就是,每个minibatch的data不多,假设100个,那么做出来的network靠谱吗?
  • 其实不用担心,因为在网络中参数是share的,所以在训练参数的时候是一大堆参数合起来去训练网络。例如4个minibatch都同时用了同一个参数,那么这个参数就被同时train了

在这里插入图片描述
到了testing阶段,按照ensemble的方法,我们得到了一堆network,然后就把testing data都丢到这些network中,把所有network得出来的结果求平均。但是实际上这些network太多了,没办法去给所有的network放进一个input,运算量太大了。

所以,dropout最神奇的地方是,它告诉你,当一个完整的network不做dropout,而是把它的weight乘以(1-p%),把你的training data丢进去,得到的output就是average的近似值。

例子:

在这里插入图片描述
假设我们有一个network要做ensemble,activation function是线性的,如蓝色框内的图。那么有四种dropout的可能,最后得到4个output z,一共四个值, w 1 x 1 和 w 2 x 2 w_1x_1和w_2x_2 w1x1w2x2分别一共出现了两次,所以就是乘上0.5。然后如果我们直接乘上(1-0.5),明显结果是一样的。

在这个最简单的case里面,ensemble这件事情跟我们把weight乘以1/2得到一样的结果。但是这个结果只有是linear network(例如maxout和ReLU)才会有这样的结果。sigmoid就不一定行。有个猜想,就是如果我的network比较贴近linear,那么dropout的表现就会比较好囖?

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值