机器学习打卡第五天

网络设计的技巧

一、局部最小值与鞍点(Local Minimum And Saddle Point)


在做优化(Optimization)的时候,我们有时候会发现随着参数不断更新,训练的损失值不再下降,但这并不是我们想要的结果,出现梯度为0的情况有以下三种:
1、local minima
2、local maxima
3、saddle point:梯度为零,不是local minima,也不是local maxima,像右下图的红点,它的左右这个方向是比较高的,前后这个方向是比较低的,就像是一个马鞍的形状。
这三种点统称为 critical point。

对于我们是卡在了local minima 还是saddle point 该如何区分呢?
首先,如果我们卡在了local minima,我们已经处在最低位置了,损失值也是最小了,周围的点都比这里高,此刻处于无路可走的状况;但是如果我们卡在saddle point,还是有路可走的,有可以使损失值更小的点,所以我们需要区分两者。

这个过程经过了一些数学推导,最终的结论为:
h e s s i a n hessianhessian,它是一个矩阵,这个矩阵里面元素就是L LL的二次微分。
这个矩阵如果它所有的eigen value,都是正的,那就代表我们现在在local minima;如果它所有的eigen value,都是负的,那就代表我们现在在local maxima;如果它有正有负,就代表在saddle point。
举例来说:
我们有如下的网络:

我们只有一笔数据,这笔数据是x,是1的时候,它的level是1 ,所以输入1进去,你希望最终的输出跟1越接近越好。

四个角落loss是高的,这个图上你可以看出来说,有一些critical point,这个黑点的地方( 0 , 0 ) (0,0)(0,0)是critical point,然后事实上,右上三个黑点也是一排critical point,左下三个点也是一排critical point。
如果要更进一步分析,它们是saddle point,还是local minima,那( 0 , 0 ) (0,0)(0,0)这个地方是local minima 还是 saddle point呢?
我们可以根据刚才的结论来算矩阵H HH,如下图所示:

这个矩阵有两个eigen value,2 22和− 2 -2−2 ,有正有负,是saddle point。
如果我们今天是在一个saddle point,你也不一定要惊慌,你只要找出负的eigen value,再找出它对应的eigen vector,用这个eigen vector去加θ ′ θ'θ 

 ,就可以找到一个新的点,这个点的loss比原来还要低。(这个方法不常用)
接着上个例子来看:

这个Hessian有一个负的eigen value:− 2 -2−2,那它对应的eigen vector其中的一个eigen vectoru = [ 1 1 ] u=
[11]
[11]
u=[ 
1
1
​    
 ],我们只要顺着u uu的方向,去更新我们的参数,就可以找到一个比saddle point的loss还要更低的点。

注:local minima 不常见,saddle point 常见一些。

二、批次与动量(Batch and Momentum)

实际上在算微分时,并不是真的对所有数据算出来的L LL作微分,而是把所有数据分为一个一个b a t c h batchbatch,每次更新参数时,我们是拿一个b a t c h batchbatch,来算L o s s LossLoss,算梯度,然后更新参数,依此类推。所有的b a t c h batchbatch看过一遍,叫做一个E p o c h EpochEpoch。实际上在每一个E p o c h EpochEpoch开始之前,会分一次 b a t c h batchbatch,每一个E p o c h EpochEpoch的b a t c h batchbatch都不一样,这叫做 S h u f f l e ShuffleShuffle。
下图是有关 s m a l l smallsmall b a t c h batchbatch和l a r g e largelarge b a t c h batchbatch的比较:

s m a l l smallsmall b a t c h batchbatch的o p t i m i z a t i o n optimizationoptimization 和 g e n e r a l i z a t i o n generalizationgeneralization都要优于l a r g e largelarge b a t c h batchbatch;
l a r g e largelarge b a t c h batchbatch一次e p o c h epochepoch的时间要少于s m a l l smallsmall b a t c h batchbatch;
B a t c h BatchBatch S i z e SizeSize是需要调整的 H y p e r p a r a m e t e r HyperparameterHyperparameter。

Momentum是另一个有可能可以对抗 Saddle Point或 Local Minima 的技术,Momentum 的运作如下图所示:

从物理的角度来看,假设 Error Surface 是真正的斜坡,而我们的参数是一个球,把球从斜坡上滚下来,如果今天是 Gradient Descent,它走到 Local Minima 就停住了,走到 Saddle Point 就停住了。
但是在物理的世界里,一个球如果从高处滚下来,就算滚到 Saddle Point,如果有惯性,它从左边滚下来,它还是会继续往右走,甚至它走到一个 Local Minima,如果今天它的动量够大的话,它还是会继续往右走,甚至翻过这个小坡然后继续往右走。
那所以在物理世界里,一个球从高处滚下来的时候,它并不会被 Saddle Point或 Local Minima卡住,那我们能不能把这个概念用到 Gradient Descent 里呢?


如上图所示,加上 Momentum 之后,每一次我们在移动参数的时候,不是只往 Gradient Descent的反方向来移动,而是向 Gradient 的反方向加上前一步移动的方向,两者加起来的结果,来调整我们的参数。

三、自动调整学习率(Adaptive Learning Rate)
一般来说,在训练过程中,出现loss不在下降的情况时,我们的第一反应是卡在了critical point,而事实上,它的gradient真的很小吗?实则不然,如下图所示,当loss值不再下降,它的gradient并没有很小。既然不是这个原因,那是什么原因呢?
举例来说,我们有一个如下图(右上)所示的error surface,这个error surface的最低点在黄色X这个地方,现在我们要从黑点开始,作为初始点,来做gradient descend。当 learning rate 为1 0 − 2 10^{-2}10 
−2
 时(左下),参数在峡谷的两端不断震荡,loss值没有下降,但是gradient仍然是很大的。然后你会想,是不是learning rate设置的太大了,然后把learning rate调到1 0 − 7 10^{-7}10 
−7
 (右下)的时候,它不再震荡了,但你发现说,这个训练永远走不到终点,因为learning rate已经太小了,竖直往上这一段坡度很陡,gradient的值很大,所以还能够前进一点,左拐以后这个地方坡度已经非常的平滑,,这么小的learning rate,根本没有办法再继续训练下去,事实上在左拐这个地方,看到这边一大堆黑点,显然就算是一个convex的error surface,你用gradient descend也很难train。


因此,我们要根据不同的gradient设置不同的learning rate。从刚才的例子里,其实我们可以看到一个大原则,如果在某一个方向上的gradient的值很小,非常的平坦,那我们会希望learning rate调大一点;如果在某一个方向上非常的陡峭,坡度很大,那我们其实期待learning rate可以设得小一点。
我们把原来gradient descend固定的learning rate改为如下的式子:

σ σσ这个参数,首先它是取决于i ii的,不同的参数我们要给它不同的σ σσ,同时它也是iteration dependent的,不同的iteration我们也会有不同的σ σσ。
σ σσ的常见计算方式为算gradient的Root Mean Square。

这个σ ᵢ ᵗ σᵢᵗσᵢᵗ它就是过去所有的gradient,g ᵢ ᵗ gᵢᵗgᵢᵗ从第一步到目前为止,所有算出来的g ᵢ ᵗ gᵢᵗgᵢᵗ的平方和,再平均,再开根号得到σ ᵢ ᵗ σᵢᵗσᵢᵗ。(之前提到的Adagrad就是用的这个方式),还有另一种方法,即RMS Prop。

它的第一步跟刚才讲的Root Mean Square,也就是那个Adagrad的方法,是一模一样的。
从第二步往后,在RMS Prop里,你可以自己调整现在的这个gradient,你觉得它有多重要。α αα就像learning rate一样,需要你自己调它,这是一个hyperparameter。

回到我们之前的例子,接下来我们采用Adagrad来train,这个做下来就没有问题(右下图),有一个问题是,为什么走到快终点的位置突然爆炸了呢?
我们在做这个σ σσ的时候,是把过去所有看到的gradient都拿来作平均。所以这个纵轴的方向,在初始位置感觉gradient很大,经过一段时间的训练,纵轴方向算出的gradient都很小,所以纵轴这个方向累积了很小的σ σσ,累积到一定地步以后,这个step就变很大,然后就喷出去了;喷出去以后有办法修正回来,因为喷出去以后,就走到了gradient比较大的地方,σ σσ又慢慢的变大,σ σσ慢慢变大以后,这个参数update的距离就慢慢的变小。


有一个方法也许可以解决这个问题,叫做learning rate的scheduling。

我们不把η ηη当一个常数,我们把它与时间有关。最常见的策略叫做Learning Rate Decay,也就是说,随着时间的不断进行,参数不断的update,η ηη会越来越小。

一开始我们距离终点很远,随着参数不断update,我们距离终点越来越近,所以我们把learning rate减小,让我们参数的更新踩了一个刹车,使参数的更新能够慢慢地慢下来,所以刚才那个状况,加上Learning Rate Decay就解决了。

还有另一个常用的Learning Rate Scheduling的方式,叫做Warm Up。

Warm Up的方法是让learning rate先变大后变小,这个也是hyperparameter,需要自己用手调。

四、损失函数
我们以分类为例来讲解,通常在做分类的问题的时候,比较常见的做法是把Class用 One-hot vector来表示。假设我们有3类,可以用如下的方式来表示:

过去做的都是Regression的问题,所以只Output一个数字,其实从一个数值改到三个数值,它是没有什么不同的。

把a ₁ a₁a₁ a ₂ a₂a₂ a ₃ a₃a₃,乘上三个不同的Weight 加上bias,得到y ₁ y₁y₁;
再把a ₁ a₁a₁ a ₂ a₂a₂ a ₃ a₃a₃乘上另外三个Weight,再加上另外一个bias得到y ₂ y₂y₂;
再把a ₁ a₁a₁ a ₂ a₂a₂ a ₃ a₃a₃再乘上另外一组Weight,再加上另外一个bias得到y ₃ y₃y₃。
这样就可以产生三组数字,所以你就可以Input一个feature的Vector,然后产生y ₁ y₁y₁ y ₂ y₂y₂ y ₃ y₃y₃,然后希望y ₁ y₁y₁ y ₂ y₂y₂ y ₃ y₃y₃,跟我们的目标越接近越好。

在做Classification的时候,我们往往会把y yy再通过一个叫做Soft-max的function得到y ′ y'y 

 ,然后我们才去计算y ′ y'y 

 和y ^ \hat{y} 
y
^
​    
 之间的距离。之所以采用softmax的简单原因可以理解成既然我们的目标只有0和1,但是y yy有任何值,我们就先把它Normalize到0到1之间,这样才好和 label 计算相似度。它会让大的值跟小的值的差距更大。

Soft-max的block如下图所示,输入y ₁ y₁y₁ y ₂ y₂y₂ y ₃ y₃y₃,它会产生y ₁ ′ y₁'y₁ 

  y ₂ ′ y₂'y₂ 

  y ₃ ′ y₃'y₃ 

 

具体公式如下:
有了这个式子以后,你就会发现y ₁ ′ y₁'y₁ 

  y ₂ ′ y₂'y₂ 

  y ₃ ′ y₃'y₃ 

 ,它们都是介于0到1之间,它们的和是1。
Soft-max的输入往往就叫它logit。

这边考虑了三个class的情况,当两个class用sigmoid和soft-max两个class,你如果推一下的话,会发现说这两件事情是等价的。

我们把x xx,丢到一个Network里,产生y yy以后,我们会通过soft-max得到y ′ y'y 

 ,再去计算y ′ y'y 

 和y ^ ŷ 
y
^
​    
 之间的距离,记作е ее,计算y ′ y'y 

 和y ^ ŷ 
y
^
​    
 之间的距离不只一种做法,举例来说,可以让这个距离是Mean Square Error:

更常用的做法叫做Cross-entropy:


五、批次标准化(Batch Normalization)
Batch Normalization的想法就是Changing Landscape,把山变平的想法。
举例来说,现在有一个非常简单的 model,它的输入是x 1 x_1x 
1
​    
 和x 2 x_2x 
2
​    
  ,对应的参数是w 1 w_1w 
1
​    
 和w 2 w_2w 
2
​    
  ,它是一个 linear 的 model,没有 activation function。

那么什么情况下会产生不好的error surface呢?
如下图:

当x 1 x_1x 
1
​    
 和x 2 x_2x 
2
​    
 不在一个scale的时候,比如x 1 x_1x 
1
​    
 为1,2等这些数,即便乘上的w 1 有 变 化 , w_1有变化,w 
1
​    
 有变化,相对应的y yy改变也很小,而x 2 x_2x 
2
​    
 为100,200等这些数,即便乘上的w 2 有 很 小 的 变 化 , w_2有很小的变化,w 
2
​    
 有很小的变化,相对应的y yy改变也很大, error surface 就会有很大的变化。

所以在这个 linear 的 model 里,当我们 input 的 feature,每一个 dimension 的值,它的 scale 差距很大的时候,我们就可能产生像这样子的 error surface,就可能产生不同方向,斜率非常不同,坡度非常不同的 error surface。

我们有没有可能给feature 里面不同的 dimension,让它有同样的数值的范围,其实有很多不同的方法,这些不同的方法,往往就合起来统称为Feature Normalization。
详情见Task 03误差和梯度下降Tip3 特征缩放

对每一个 dimension都做一样的 normalization,就会发现所有 feature 不同 dimension 的数值都在 0 上下,那样就可以制造比较好的 error surface。

所以像这样子 Feature Normalization 的方式,往往对你的 training 有帮助,它可以让你在做 gradient descent 的时候它的 Loss 收敛更快一点,可以让gradient descent的训练更顺利,这个是 Feature Normalization。

接下来,我们考虑深度学习,把通过Feature Normalization得到的x ~ \tilde x 
x
~
 丢到 deep network里,接着去做训练,如图所示,x ~ 1 \tilde x^1 
x
~
  
1
 经过第一层网络,得到z 1 z^1z 
1
 ,再经过激活函数得到a 1 a^1a 
1
 ,依次往下通过其他层网络,对于每个x ~ \tilde x 
x
~
 都做类似的事情,那么,对于w 2 w^2w 
2
 来说,a 1 a^1a 
1
 、z 1 z^1z 
1
 也属于一种input,虽然x ~ \tilde x 
x
~
 经过了Normalization,但z 1 z^1z 
1
 并没有没有做 normalize, z 1 z^1z 
1
 不同的 dimension 间,它的数值的分布仍然有很大的差异的话,那我们要 train w 2 w^2w 
2
 第二层的参数,会不会也有困难呢?

那怎么对 z zz 做 Feature Normalization 呢?
我们把 z zz 想象成另一种feature,这里有z 1 z^1z 
1
  z 2 z^2z 
2
  z 3 z^3z 
3
 ,算一下它们的平均值,放在μ \muμ这个向量里,再算一个 standard deviation σ \sigmaσ,这个 standard deviation也代表了一个 vector,用z 1 z^1z 
1
  z 2 z^2z 
2
  z 3 z^3z 
3
 把μ \muμ 减掉 ,然后取平方,做平均,然后再开根号。

接下来,让每一个z zz减去μ \muμ,再除以σ \sigmaσ,得到z ~ i \tilde z^i 
z
~
  
i
 
注: μ \muμ和σ \sigmaσ 都是向量,所以除的意思是element wise 的相除,就是z i z^iz 
i
  减μ \muμ ,它是一个向量,所以分子是一个向量,分母也是一个向量,把这个两个向量对应的 element 的值相除,得到z ~ i \tilde z^i 
z
~
  
i
 。

在实做的时候,我们不会让一个 network 考虑整个 training data 里面所有的 example,我们只会考虑一个 batch 里面的 example,举例来说,我们设 batch 为 64,那你这个巨大的 network,就是把 64 笔 data 读进去,算这 64 笔 data 的 μ \muμ和σ \sigmaσ,对这 64 笔 data 去做 normalization。

因为我们在实做的时候,只对一个 batch 里面的 data,做 normalization,所以这招叫做 Batch Normalization。batch要足够大,才能计算 μ \muμ和σ \sigmaσ,也许这个 batch size 里面的 data,就足以表示整个 corpus 的分布。

得到z ~ i \tilde z^i 
z
~
  
i
 之后,接下来我们会再乘一个向量γ \gammaγ,再加上β \betaβ,得到z ^ i \hat z^i 
z
^
  
i
 ,γ \gammaγ和β \betaβ可以看成是另外的参数来学习的。

那为什么要加γ \gammaγ和β \betaβ呢?

如果我们做normalization 以后,z ~ \tilde z 
z
~
 的平均一定为0,会给network带来一些限制,也许这个限制会带来负面影响,所以我们把γ \gammaγ和β \betaβ加回去。但是加回去之后,不同的dimension的range不是又不一样了吗?这是有可能的,但在实际训练时,我们会把γ \gammaγ和β \betaβ的初始值分别设为1 11 和 0 00。

所以当你的 network 在开始训练的时候,每一个 dimension 的分布是比较接近的,也许训练够长的一段时间,你就已经找到一个比较好的 error surface,走到一个比较好的地方以后,那再把γ \gammaγ和β \betaβ慢慢地加进去,所以加 Batch Normalization,往往对你的训练是有帮助的。

以上都是在将训练部分,那么到了测试阶段呢?
做测试时,没有一个一个的batch,要怎么计算 μ \muμ和σ \sigmaσ呢?
在实做时,如果你用到 PyTorch的话,它已经帮你做好了。
在训练时,如果你做了Batch Normalization,你每一个 batch 计算出来的 μ \muμ 和 σ \sigmaσ ,他都会拿出来算 moving average。


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值