【学习笔记】李宏毅2021春机器学习课程第2.3节:Adaptive Learning Rate

Training stuck ≠ Small Gradient


首先要明确的一点是,目前当我们用 gradient descend 来做optimization的时候,你真正应该要怪罪的对象往往不是critical point,而是其他的原因。

image-20210319093237570

我们之前常说,走到critical point的时候,意味着gradient非常小,但是你真的确认过,当**你的loss不再下降的时候,gradient真的很小吗?**事实上在上图这个例子中,当我们的loss不再下降的时候,gradient并没有真的变得很小,那为什么会出现这样的状况呢?

image-20210319094055839

上图是我们的error surface,而你现在每次更新model的参数,其实只是在error surface山谷的两个谷壁间不断的来回震荡,这个时候你的loss不会再下降,所以你会觉得它肯定卡在了critical point,但实际却不是的,它的gradient仍然很大,只是因为不断震荡,loss不能够再减小了

既然critical point不是主要问题的话,那为什么我们的training还是会卡住呢?这里举一个非常简单的例子,下图是一个非常简单的error surface:

image-20210319095748513

这个error surface的最低点黄叉×这个地方,可以观察到它的这个等高线是椭圆形的,只是它在横轴的地方坡度的变化非常小,所以这个椭圆的长轴非常长,短轴相对之下比较短,在纵轴的地方gradient的变化很大,error surface的坡度非常的陡峭。现在我们要从黑点这个地方来做gradient descend。

你可能会觉得,这个要做gradient descend应该很简单,不就是一路滑下来,然后再往左走过去嘛。但要是你实际上自己试一下,你就会发现即使是形状这么简单的error surface,用gradient descend都不见得能把它做好,举例来说:

image-20210319100229839

learning rate设为10⁻²的时候,参数在峡谷的两端不断震荡,loss始终掉不下去,但是gradient其实仍然是很大的,这与本文开头那个例子的情况相同。

那这时你可能说,肯定是因为learning rate设的太大,learning rate决定了我们update参数的时候步伐有多大,只要把learning rate设小一点,步伐小一点慢慢滑入山谷,不就可以解决这个问题了吗?

但事情没有想的那么简单,慢慢调整这个learning rate,从10⁻²一直调到10⁻⁷,调到10⁻⁷之后,震荡终于停下了。

image-20210319100647667

但是这个时候我们又发现,这个训练似乎永远走不到终点,因为learning rate已经太小了,竖直往上这一段因为坡度很陡,gradient的值很大,所以还能够前进一点,但左拐以后这个地方坡度已经非常的平滑了,这么小的learning rate,根本没有办法再让我们的训练前进

image-20210319102724035

事实上在左拐这个地方,可以看到有一大堆黑点,实际上这些黑点总共有十万个,可以看到即使我们update了十万次,还是没有让我们的训练前进多少,这个时候其实我们希望此时的learning rate能大一点,总的来说,我们希望模型的learning rate是能够自适应调整的

在之前我们使用的gradient descend里面,所有的参数都是设置同样的learning rate,这显然是不够的,我们应该要能为每一个参数定制learning rate,并且learning rate还能够根据训练的进度进行自适应的调整

Different parameters needs different learning rate


从刚才的例子里面,其实我们可以总结出一个简单的原则:如果在某一个方向上,我们的gradient的值很小,非常的平坦,那我们会希望learning rate调大一点;如果在某一个方向上gradient的值很大,坡度很大,那我们会希望learning rate可以设得小一点

image-20210319103709570

那我们要如何实现learning rate的自动调整呢

我们需要修改一下gradient descend原来的式子,这边为了简化问题,我们只看一个参数上的update,但是你完全可以把这个方法推广到所有参数的状况:
θ i t + 1 ← θ i t − η g i t {θ{_i}{^{t+1}}} ← {θ{_i}{^{t}}}-{\eta}{g{_i}{^{t}}} θit+1θitηgit
这个式子中的 η η η其实就是我们的learning rate,在这里我们看到这个 η η η的值是固定不变的,也就是说我们的learning rate是固定的

现在我们要有一个能随着参数而变化的learning rate,我们把原来learning rate η η η这一项呢,改写成 η σ ᵢ ᵗ \frac{η}{σᵢᵗ} ση
θ i t + 1 ← θ i t − η σ ᵢ ᵗ g i t {θ{_i}{^{t+1}}} ← {θ{_i}{^{t}}}-{\frac{η}{σᵢᵗ}}{g{_i}{^{t}}} θit+1θitσηgit
这个 σ ᵢ ᵗ σᵢᵗ σ你发现它有一个上标t,有一个下标i,这代表说这个σ这个参数,首先它是 depend on i 的不同的参数我们要给它不同的σ,同时它也是iteration dependent的,不同的iteration我们也会有不同的σ。接下来我们要看这个 σ ᵢ ᵗ σᵢᵗ σ有哪些常见的计算方式。

Root mean square
image-20210319150808494

第t + 1次update参数的时候,σᵢᵗ就是过去所有的gradient,gᵢᵗ从第一步到目前为止,所有算出来的gᵢᵗ的平方和求平均值再开根号得到σᵢᵗ,
σ ᵢ t = 1 t + 1 ∑ i = 0 t ( g i t ) 2 {σᵢ^t}=\sqrt{\frac{1}{t+1}\sum_{i=0}^{t}{(g{_i}{^{t}}})^2} σt=t+11i=0t(git)2
然后再用之前的learning rate除以σᵢᵗ,就得到了新的learning rate来更新你的参数。
θ i t + 1 ← θ i t − η σ ᵢ t g i t {θ{_i}{^{t+1}}} ← {θ{_i}{^{t}}}-{\frac{η}{σᵢ^t}}{g{_i}{^{t}}} θit+1θitσtηgit

Adagrad

刚刚的这一招被用在一个叫做Adagrad的方法里,因为我们的σᵢᵗ这一项在分母上,所以如果某个参数 θᵢ¹的坡度小,那么在θᵢ¹这个参数上面,算出来的gradient就小,所以算出来的σ就小,而σ小 learning rate就大。同理可以想到某个参数 θᵢ² 的坡度大,则最终的 learning rate就小。这就可以做到我们刚才讲的,坡度比较大的时候,learning rate就减小,坡度比较小的时候,learning rate就放大的效果

image-20210319160639783
RMSProp

在刚刚的Adagrad的方法中,如果对于同一个参数,它的gradient的大小,就会差不多是固定的值,但事实上并不一定是这样的,举例来说我们来看下面这个新月形的error surface:

image-20210319211518875

如果我们考虑横轴的话,你会发现在绿色箭头这个地方坡度比较陡峭,所以我们需要比较小的learning rate

image-20210319211631968

但是走到了中间这一段,到了红色箭头的时候呢,坡度又变得平滑了起来,这就需要比较大的learning rate,所以就算是同一个参数同一个方向,我们也希望learning rate是可以动态调整的,这也就是RMSProp要做的。

RMS Prop这个方法有点传奇,它传奇的地方在於它找不到论文,非常多年前应该是将近十年前,Hinton在Coursera上,开过deep learning的课程,那个时候他在他的课程裡面,讲了RMS Prop这个方法,然后这个方法没有论文,所以你要cite的话,你要cite那个影片的连结,这是个传奇的方法叫做RMS Prop

image-20210319212301760

刚才在Adagrad中算Root Mean Square的时候,每一个gradient都有同等的重要性,但在RMS Prop里面,是现在刚算出来的gᵢᵗ比较重要还是之前算出来的gradient比较重要,是通过调整这个α的值来决定的

这个α也就成为了一个hyperparameter

  • 如果把α设很小趋近于0,就代表我觉得现在刚算出来的gᵢᵗ比较重要
  • α设很大趋近于1,那就代表我觉得现在算出来的gᵢᵗ比较不重要,之前算出来的gradient比较重要

σ ᵢ t = α ( σ i t − 1 ) 2 + ( 1 − α ) ( g i t ) 2 {σᵢ^t}=\sqrt[]{\alpha(σ_i^{t-1})^2+(1-\alpha)(g_i^t)^2} σt=α(σit1)2+(1α)(git)2

Adam

目前最常用的optimization的策略就是Adam

image-20210319220458633

Adam就是RMSProp加上Momentum,技术的进步,使得傻瓜式操作(Adam)就可以得到不错的效果,但是在特定的场景下,要拍出最好的效果,依然需要深入地理解光线、理解结构、理解器材(SGD慢慢调优)。

Learning Rate Scheduling


image-20210319221134976

重新回到我们最开始的例子上来,现在我们来看一下加上Adaptive Learning Rate 以后,能不能把这个网络训练起来。这里采用Adagrad的做法,结果如下:

image-20210319221217246

可以看到使用Adagrad以后,我们的训练可以继续走下去,走到非常接近终点的位置,这是因为当我们走到之前gradient太小而导致参数update不动的地方时,在使用Adagrad的情况下learning rate会自动变大,所以我们的步伐就可以变大,就可以继续前进

但是接下来你又会发现,为什么快走到终点的时候训练的轨迹在纵轴上突然爆炸了呢?

原因是这样的,我们在计算σ的时候,是把过去所有看到的gradient,都拿来做平均:

  • 所以在纵轴的方向,起初的坡度很陡,gradient很大,导致算出的σ很大,learning rate就比较小。

  • 但在转向向左走以后,在纵轴的方向gradient算出来都很小,而我们的σ是把过去所有看到的gradient都拿来做平均,所以纵轴这个方向就累积了很小的σ,累积到一个地步以后,learning rate就变得很大,导致step就变很大,因此在纵轴上就喷发出去了。

  • 喷出去也没有关系,有办法修正回来,这是因为喷出去以后,就走到了在纵轴的方向gradient比较大的地方,于是这个σ又慢慢的变大,σ慢慢变大以后,step又会慢慢变小,使得我们慢慢回到之前的道路上来。

如果说你不想看到这个训练的轨迹隔一段时间就喷发一次,你希望它能够稳定一些,有一个方法也许可以解决这个问题,这个方法就是learning rate的scheduling。

image-20210319221921888

learning rate scheduling的意思就是说,我们不要把η当一个常数,我们让它成为跟时间有关的一个变量。

最常见的策略叫做Learning Rate Decay,也就是说,随着时间的不断地进行,随着参数不断的update,我们让这个η越来越小。

这个做法的合理性如下:因为一开始我们距离终点很远,随着参数不断update,我们离终点越来越近,所以我们把learning rate减小,让我们参数的更新踩了一个刹车,让我们参数的更新能够慢下来,这样应该就能避免之前那个喷发的状况。

image-20210319222132512

可以看到加上Learning Rate Decay之后,我们就可以很平顺的走到终点。除了Learning Rate Decay以外,还有另外一个常用的Learning Rate Scheduling的方式,叫做Warm Up

image-20210319222229363

Warm Up是让learning rate先变大后变小,至于变大要变到多大,变大速度要多快,变小速度要多快,这些都是这个方法的hyperparameter,这个方法听起来很神奇,其实就是一个黑科技这样,这个黑科技出现在很多远古时代的论文里面,举例来说,Residual Network里面就是有Warm Up的:

image-20210319222727186

这个Residual Network里面说我们先用learning rate 0.01来Warm Up,再把learning rate改成0.1。

此外在有名的Transformer里面也用一个式子提到了它:

image-20210319222922951

为什么需要warm Up呢,这个仍然是今天一个可以研究的问题

image-20210319223155277

有一个可能的解释是说:当我们在用Adam,RMSProp,或者Adagrad的时候,我们需要计算一个σ,它是一个统计的结果,而这个统计的结果要看到足够多笔数据以后,这个统计才精准,所以一开始我们的统计是不精准的。所以我们一开始不要让我们的参数变化的太快,先让它在初始点附近做一些小的探索,所以一开始learning rate比较小,是让它探索收集一些有关error surface的情报等σ统计得比较精准以后,再让learning rate慢慢地变大

所以这是一个可能的解释,想要进一步了解有关warm up的东西的话,可以看一下RAdam,这是对Adam的一个改进,论文里对warm up有更多的理解。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值