|
摘要:
本文主要是总结了深度学习中几种常用的优化器,介绍其设计道理,优错误谬误等。
<hr/>1.什么是优化器?
2.有哪些优化器?
3.优化算法的选择与使用策略
4.参考资料
<hr/>1 什么是优化器?
(1)解释
一言以蔽之,优化器就是在深度学习反向传布过程中,指引损掉函数(方针函数)的各个参数往正确的标的目的更新合适的大小,使得更新后的各个参数让损掉函数(方针函数)值不竭逼近全局最小。
(2)道理解释
优化问题可以看做是我们站在山上的某个位置(当前的参数信息),想要以最佳的路线去到山下(最长处)。首先,直不雅观的方式就是环顾四周,找到下山最快的标的目的走一步,然后再次环顾四周,找到最快的标的目的,直到下山——这样的方式便是朴素的梯度下降——当前的海拔是我们的方针函数值,而我们在每一步找到的标的目的便是函数梯度的反标的目的(梯度是函数上升最快的标的目的,所以梯度的反标的目的就是函数下降最快的标的目的)。
事实上,使用梯度下降进行优化,是几乎所有优化器的核心思想。当我们下山时,有两个方面是我们最关心的:
- 首先是优化标的目的,决定“前进的标的目的是否正确”,在优化器中反映为梯度或动量。
- 其次是步长,决定“每一步迈多远”,在优化器中反映为学习率。
所有优化器都在存眷这两个方面,但同时也有一些其他问题,比如应该在哪里出发、路线错误如何措置……这是一些最新的优化器存眷的标的目的。
(3)公式和定义
待优化参数: \omega ,方针函数: f(x) ,初始学习率: \alpha ,迭代epoch: t
参数更新法式如下:
Ⅰ.计算方针函数关于当前参数的梯度:Ⅱ. 按照历史梯度计算一阶动量和二阶动量:m_t = \phi(g_1, g_2, \cdots, g_t); V_t = \sum_{i=0}^{t}{x_{i}^{2}} Ⅲ. 计算当前时刻的下降梯度:\eta_t = \alpha \cdot m_t / \sqrt{V_t} Ⅳ. 按照下降梯度进行更新参数:法式Ⅲ、Ⅳ对于各个算法都是一致的,主要的分歧就表此刻法式Ⅰ、Ⅱ上。
2. 有哪些优化器?
2.1 随机梯度下降法(Stochastic Gradient Descent,SGD)
随机梯度下降算法每次从训练集中随机选择一个样本来进行学习,SGD没有动量的概念,因此代入法式Ⅲ,可以得到下降梯度\eta_t = \alpha \cdot g_t SGD参数更新公式如下,此中 \alpha 是学习率, g_{t} 是当前参数的梯度w_{t+1} = w_t - \eta_t=w_t - \alpha \cdot g_t 长处:
(1)每次只用一个样本更新模型参数,训练速度快
(2)随机梯度下降所带来的波动有利于优化的标的目的从当前的局部极小值点跳到另一个更好的局部极小值点,这样对于非凸函数,最终收敛于一个较好的局部极值点,甚至全局极值点。
错误谬误:
(1)当遇到局部最长处或鞍点时,梯度为0,无法继续更新参数
局部最长处
(2)沿陡峭标的目的震荡,而沿平缓维度进展迟缓,难以迅速收敛
2.2 SGD with Momentum
为了按捺SGD的震荡,SGDM认为梯度下降过程可以插手惯性。下坡的时候,如果发现是陡坡,那就操作惯性跑的快一些。SGDM全称是SGD with momentum,在SGD基础上引入了一阶动量:m_t = \beta_1 \cdot m_{t-1} + (1-\beta_1)\cdot g_t SGD-M参数更新公式如下,此中 \alpha 是学习率, g_{t} 是当前参数的梯度w_{t+1} = w_t -\alpha \cdot m_t = w_t -\alpha \cdot(\beta_1 \cdot m_{t-1} + (1-\beta_1)\cdot g_t) 一阶动量是各个时刻梯度标的目的的指数移动平均值,也就是说, t 时刻的下降标的目的,不仅由当前点的梯度标的目的决定,而且由此前累积的下降标的目的决定。 \beta_1 的经验值为0.9,这就意味着下降标的目的主要是此前累积的下降标的目的,并略微方向当前时刻的下降标的目的。想象高速公路上汽车转弯,在高速向前的同时略微方向,急转弯可是要出事的。
特点:
因为插手了动量因素,SGD-M缓解了SGD在局部最长处梯度为0,无法持续更新的问题和振荡幅渡过大的问题,但是并没有完全解决,当局部沟壑斗劲深,动量加持用完了,依然会困在局部最优里来回振荡。
2.3 SGD with Nesterov Acceleration
SGD 还有一个问题是困在局部最优的沟壑里面震荡。想象一下你走到一个盆地,四周都是略高的小山,你感觉没有下坡的标的目的,那就只能待在这里了。可是如果你爬上高地,就会发现外面的世界还很广阔。因此,我们不能逗留在当前位置去不雅察看未来的标的目的,而要向前一步、多看一步、看远一些。
NAG全称Nesterov Accelerated Gradient,是在SGD、SGD-M的基础上的进一步改良,改良点在于法式Ⅰ。我们知道在时刻 t 的主要下降标的目的是由累积动量决定的,本身的梯度标的目的说了也不算,那与其看当前梯度标的目的,不如先看看如果跟着累积动量走了一步,阿谁时候再怎么走。因此,NAG在法式Ⅰ,不计算当前位置的梯度标的目的,而是计算如果按照累积动量走了一步,阿谁时候的下降标的目的:g_t=\nabla f(w_t-\alpha \cdot m_{t-1} / \sqrt{V_{t-1}}) NAG参数更新公式如下,此中 \alpha 是学习率, g_{t} 是当前参数的梯度w_{t+1} =w_t - \alpha \cdot g_t =w_t - \alpha \ast(\nabla f(w_t-\alpha \cdot m_{t-1} / \sqrt{V_{t-1}})) 然后用下一个点的梯度标的目的,与历史累积动量相结合,计算法式Ⅱ中当前时刻的累积动量。
特点:
有利于跳出当前局部最优的沟壑,寻找新的最优值,但是收敛速度慢。
2.4 AdaGrad(自适应学习率算法)
SGD系列的都没有用到二阶动量。二阶动量的呈现,才意味着“自适应学习率”优化算法时代的到来。SGD及其变种以同样的学习率更新每个参数,但深度神经网络往往包含大量的参数,这些参数并不是总会用得到(想想大规模的embedding)。对于经常更新的参数,我们已经堆集了大量关于它的常识,不但愿被单个样本影响太大,但愿学习速率慢一些;对于偶尔更新的参数,我们了解的信息太少,但愿能从每个偶然呈现的样本身上多学一些,即学习速率大一些。
怎么样去度量历史更新频率呢?
那就是二阶动量——该维度上,记录到目前为止所有梯度值的平方和:V_t = \sum_{\tau=1}^{t} g_\tau^2 我们再回顾一下法式Ⅲ中的下降梯度:\eta_t = \alpha \cdot m_t / \sqrt{V_t} AdaGrad参数更新公式如下,此中 \alpha 是学习率, g_{t} 是当前参数的梯度w_{t+1} =w_t - \alpha \cdot m_t / \sqrt{V_t}=w_t - \alpha \cdot m_t / \sqrt{\sum_{\tau=1}^{t} g_\tau^2} 可以看出,此时本色上的学习率由 \alpha 变成了 \alpha / \sqrt{V_t} 。 一般为了避免分母为0,会在分母上加一个小的平滑项。因此\sqrt{V_t} 是恒大于0的,而且参数更新越频繁,二阶动量越大,学习率就越小。
长处:
(1)在稀疏数据场景下表示非常好
(2)此前的SGD及其变体的优化器主要聚焦在优化梯度前进的标的目的上,而AdaGrad初度使用二阶动量来存眷学习率(步长),开启了自适应学习率算法的里程。
错误谬误:
(1)因为\sqrt{V_t} 是单调递增的,会使得学习率单调递减至0,可能会使得训练过程提前结束,即便后续还有数据也无法学到必要的常识。
2.5 AdaDelta / RMSProp
由于AdaGrad单调递减的学习率变化过于激进,考虑一个改变二阶动量计算方式的策略:不累积全部历史梯度,而只存眷过去一段时间窗口的下降梯度。这也就是AdaDelta名称中Delta的来历。
改削的思路很简单。前面讲到,指数移动平均值大约就是过去一段时间的平均值,因此我们用这一方式来计算二阶累积动量:V_t = \beta_2 \cdot V_{t-1} + (1-\beta_2) g_t^2 AdaDelta / RMSProp参数更新公式如下,此中 \alpha 是学习率, g_{t} 是当前参数的梯度\begin{align}w_{t+1} &=w_t - \alpha \cdot m_t / \sqrt{V_t}\\&=w_t - \alpha \cdot m_t / \sqrt{ \beta_2 \cdot V_{t-1} + (1-\beta_2) g_t^2} \end{align} 长处:
避免了二阶动量持续累积、导致训练过程提前结束的问题了。
2.6 Adam
谈到这里,Adam和Nadam的呈现就很自然而然了——它们是前述方式的集大成者。SGD-M在SGD基础上增加了一阶动量,AdaGrad和AdaDelta在SGD基础上增加了二阶动量。把一阶动量和二阶动量都用起来,就是Adam了——Adaptive + Momentum。
SGD的一阶动量:
m_t = \beta_1 \cdot m_{t-1} + (1-\beta_1)\cdot g_t
加上AdaDelta的二阶动量:
V_t = \beta_2 \cdot V_{t-1} + (1-\beta_2) g_t^2
Adam参数更新公式如下,此中 \alpha 是学习率, g_{t} 是当前参数的梯度\begin{align} w_{t+1} &=w_t - \alpha \cdot m_t / \sqrt{V_t}\\&=w_t - \alpha \cdot (\beta_1 \cdot m_{t-1} + (1-\beta_1)\cdot g_t) / \sqrt{ \beta_2 \cdot V_{t-1} + (1-\beta_2) g_t^2} \end{align} 优化算法里最常见的两个超参数 \beta_1, \beta_2 就都在这里了,前者控制一阶动量,后者控制二阶动量。
长处:
(1)通过一阶动量和二阶动量,有效控制学习率步长和梯度标的目的,防止梯度的振荡和在鞍点的静止。
错误谬误:
(1)可能不收敛:
二阶动量是固按时间窗口内的累积,随着时间窗口的变化,遇到的数据可能发生巨变,使得V_t可能会时大时小,不是单调变化。这就可能在训练后期引起学习率的震荡,导致模型无法收敛。
修正的方式。由于Adam中的学习率主要是由二阶动量控制的,为了保证算法的收敛,可以对二阶动量的变化进行控制,避免上下波动。
V_t = max(\beta_2 * V_{t-1} + (1-\beta_2) g_t^2, V_{t-1})
通过这样改削,就保证了 ||V_t|| \geq ||V_{t-1}|| ,从而使得学习率单调递减。
(2)可能错过全局最优解:
自适应学习率算法可能会对前期呈现的特征过拟合,后期才呈现的特征很难改正前期的拟合效果。后期Adam的学习率太低,影响了有效的收敛。
2.7 Nadam
最后是Nadam。我们说Adam是集大成者,但它居然遗漏了Nesterov,这还能忍?必需给它加上,按照NAG的法式:g_t=\nabla f(w_t-\alpha \cdot m_{t-1} / \sqrt{V_t}) 这就是Nesterov + Adam = Nadam了。
2.8 总结
SGD参数更新公式如下,此中 \alpha 是学习率, g_{t} 是当前参数的梯度w_{t+1} =w_t - \alpha \cdot g_t 优化器千变万化,八门五花,其实主要还是在步长( \alpha )和梯度标的目的( g_{t} )两个层面进行改良,都是SGD带分歧的learning rate scheduler。
3 优化算法的选择与使用策略
优化算法的常用tricks
(1)首先,各大算法孰优孰劣并无定论。如果是刚入门,优先考虑SGD+Nesterov Momentum或者Adam。
(2)选择你熟悉的算法——这样你可以更加熟练地操作你的经验进行调参。
(3)充实了解你的数据——如果模型长短常稀疏的,那么优先考虑自适应学习率的算法。
(4)按照你的需求来选择——在模型设计尝试过程中,要快速验证新模型的效果,可以先用Adam进行快速尝试优化;在模型上线或者成果发布前,可以用精调的SGD进行模型的极致优化。
(5)先用小数据集进行尝试。有论文研究指出,随机梯度下降算法的收敛速度和数据集的大小的关系不大。因此可以先用一个具有代表性的小数据集进行尝试,测试一下最好的优化算法,并通过参数搜索来寻找最优的训练参数。
(6)考虑分歧算法的组合。先用Adam进行快速下降,尔后再换到SGD进行充实的调优。切换策略可以参考本文介绍的方式。
(7)数据集必然要充实的打散(shuffle)。这样在使用自适应学习率算法的时候,可以避免某些特征集中呈现,而导致的有时学习过度、有时学习不足,使得下降标的目的呈现偏差的问题。
(8)训练过程中持续监控训练数据和验证数据上的方针函数值以及精度或者AUC等指标的变化情况。对训练数据的监控是要保证模型进行了充实的训练——下降标的目的正确,且学习率足够高;对验证数据的监控是为了避免呈现过拟合。
(9)制定一个合适的学习率衰减策略。可以使用按期衰减策略,比如每过多少个epoch就衰减一次;或者操作精度或者AUC等性能指标来监控,当测试集上的指标不变或者下跌时,就降低学习率。
参考资料:
[1]梯度下降(Gradient Descent)小结
[2]一个框架看懂优化算法之异同 SGD/AdaGrad/Adam
[3] 神经网络中的反向传布法
[4] An overview of gradient descent optimization algorithms
[5] 聊一聊深度学习中的优化器 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|