Adam是如何做到自适应学习率的?
-
优化算法统一公式
- 待优化参数: w t w_t wt;
- 优化目标: f ( w t ) f(w_t) f(wt);
- 当前参数梯度: g t = ∇ f ( w t ) g_t=\nabla{f(w_t)} gt=∇f(wt);
- 一阶动量和二阶动量: η t = α ⋅ m t / v t \eta_t=\alpha· m_t/\sqrt{v_t} ηt=α⋅mt/vt;
- 统一的更新公式为: w t + 1 = w t − η t w_{t+1}=w_t-\eta_t wt+1=wt−ηt;
-
Adam时如何自适应调整学习率的?
-
首先,介绍SGD和带动量的SGD。SGD的更新公式如下: w t + 1 = w t − α ⋅ g t w_{t+1}=w_t-\alpha·g_t wt+1=wt−α⋅gt,相当于 m t = g t m_t=g_t mt=gt, v t = I 2 v_t=I^2 vt=I2。但由于其更新只依赖于当前的数据,使得其难以跳出局部最优。为利用历史的更新方向的趋势,使得其更新方向按照历史的 趋势进行,令 m t = β 1 ⋅ m t − 1 + ( 1 − β 1 ) g t m_t=\beta_1·m_{t-1}+(1-\beta_1)g_t mt=β1⋅mt−1+(1−β1)gt,这样有 β 1 \beta_1 β1比例的方向由历史方向决定,因此 w t + 1 = w t − α ⋅ m t w_{t+1}=w_t-\alpha·m_t wt+1=wt−α⋅mt;
-
使用SGD更新参数时,其参数的学习率是对于每一个 g t g_t gt都是相同的,即无论 g t g_t gt中的内容是大还是小,都是采用同样的步长进行更新,但我们希望对经常更新的参数不至于被单个样本影响太大,希望学习缓慢一些,对于偶尔更新的参数,模型了解的信息太少,希望梯度小的学习率大一些,以便于我们能够从少量信息中获取到信息。因此,引入二阶动量 v t = ∑ τ = 1 t g t 2 v_t=\sum_{\tau=1}^{t}g_t^2 vt=∑τ=1tgt2,将其作为学习率 α \alpha α的分母,可以动态调整学习率的大小,得到新的学习率 α / v t + ϵ \alpha/\sqrt{v_t+\epsilon} α/vt+ϵ,更新频率越大的则学习率越小,更新频率越小的,学习率越大。引入二阶动量的梯度更新法则之后, v t v_t vt可能很快就累积到很大。借鉴 m t m_t mt利用当前时间端前一段时间的梯度信息,使用指数滑动平均,得到 v t = β 1 ⋅ v t − 1 + ( 1 − β 1 ) g t 2 v_t=\beta_1·v_{t-1}+(1-\beta_1)g_t^2 vt=β1⋅vt−1+(1−β1)gt2,因此最终引入二阶动量的参数更新公式为: w t + 1 = w t − α ⋅ g t / v t + ϵ w_{t+1}=w_t-\alpha·g_t/{\sqrt{v_t+\epsilon}} wt+1=wt−α⋅gt/vt+ϵ;
-
结合两个动量的更新就是Adam算法了: w t + 1 = w t − α ⋅ m t / v t + ϵ w_{t+1}=w_t-\alpha·m_t/{\sqrt{v_t+\epsilon}} wt+1=wt−α⋅mt/vt+ϵ;
从上述可以看出,Adam自适应调整学习率是从二阶动量 v t v_t vt上进行的,目的是为了避免经常更新的参数被单个异常样本影响,同时能够学习到出现较少的样本信息。
-
参考: