深度学习优化算法经历了 SGD -> SGDM -> NAG ->AdaGrad -> AdaDelta -> Adam -> Nadam这样的发展历程。
优化算法通用框架:
首先定义:待优化参数:w ,目标函数: f(w),初始学习率 α。而后,开始进行迭代优化。在每个epoch t:1)计算目标函数关于当前参数的梯度;2)根据历史梯度计算一阶动量和二阶动量;3)计算当前时刻的下降梯度;4)根据下降梯度进行更新。各个优化算法在步骤3、4上都是一致的,主要的差别就体现在1和2上。优化算法分为固定学习率和自适应学习率。固定学习率优化策略有SGD、SGDM、NAG;自适应学习率优化策略有AdaGrad、AdaDe;ta、Adam、Nadam。
SGD算法没有动量的概念,它的,,其中是梯度。SGD最大的缺点是下降速度慢,而且可能会在沟壑的两边持续震荡,停留在一个局部最优点,对学习率要求严格。
SGDM是后来为了抑制SGD震荡,在SGD的基础上引入了动量,也就是常说的“惯性”,t时刻的下降方向不仅仅有当前时刻的梯度方向所决定,还收累积的动量方向的影响。。它的优点是下降初期,梯度方向与动量方向一直,可以起到很好的加速作用;下降中后期,在局部最小值震荡,此时梯度趋近于0,累积的动量能是权重更新幅度加大,容易跳过局部最优值。
NAG算法在梯度更新是做了一个矫正,避免了前进太快,同时提高灵敏度。
SGDM的更新公式。可以看出累积的动量并没有改变t时刻的梯度。而NAG改进点就是让累积的动量影响当前动量,NAG步骤:1)不计算当前位置的梯度方向,而是计算如果按照累积动量走了一步,那个时候的下降方向:,然后用下一个点的梯度方向,与历史累积动量相结合,计算步骤 2 中当前时刻的累积动量:。
momentum首先计算一个梯度(短的蓝色向量),然后在加速更新梯度的方向进行一个大的跳跃(长的蓝色向量),nesterov项首先在之前加速的梯度方向进行一个大的跳跃(棕色向量),计算梯度然后进行校正(绿色梯向量)
自适应学习率策略
以上的算法都是在SGD的基础上几添加一阶动量,后来在一阶动量的基础上添加二阶动量便是我们说的自适应学习率优化算法。
Adagrad Adagrad其实是对学习率加了一个约束。首先去度量历史梯度的更新频率:,所以实际的学习率:,是极小整数,防止分母为0。由公式看出,如果设置过大,会使敏感,对梯度调节过大;参数更新越频繁,二阶动量越大,学习率越小。但是二阶动量是单调递增的,会导致学习率最终递减为0,可能会使训练过程提前结束,即使后面还有数据也无法学习。适合处理稀疏梯度。
Adadelta 由于AdaGrad单调递减的学习率变化过于激进,我们考虑一个改变二阶动量计算方法的策略:不累积全部历史梯度,而只关注过去一段时间窗口的下降梯度。这也就是AdaDelta名称中Delta的来历。,这样就避免了Adagrad中二阶动量持续累积,导致训练过程提前结束的问题。但是Adadelta是度量某一时间窗口内的二阶动量,在这一窗口内可能存在巨变的数据,是学习率上升,造成训练无法收敛。Adadelta容易在训练后期在局部最小值附近震荡。
Adam SGD-M在SGD基础上增加了一阶动量,AdaGrad和AdaDelta在SGD基础上增加了二阶动量。把一阶动量和二阶动量都用起来,就是Adam了——Adaptive + Momentum。它利用梯度的一阶动量和二阶动量动态调整每个参数的学习率。Adam的优点主要在于经过偏置校正后,每一次迭代学习率都有个确定范围,使得参数比较平稳。
Nadam Nesterov + Adam = Nadam,步骤1如同Nesterov :。
现在用的最多的算法是SGD和Adam,两者各有好坏。SGD能够到达全局最优解,而且训练的最佳精度也要高于其他优化算法,但它对学习率的调节要求非常严格,而且容易停在鞍点;Adam是傻瓜式的优化算法,它很容易的跳过鞍点,而且不需要人为的干预学习率的调节,但是它很容易在局部最小值处震荡,存在在特殊的数据集下出现学习率突然上升,造成不收敛的情况,也就是说它有其他优化算法的所有优点和所有不足。
算法 | 优点 | 缺点 | 适用情况 |
牛顿法 | 收敛速度快 | 靠近极小值时收敛速度减慢,求解Hessian矩阵的逆矩阵复杂,容易陷入鞍点 | 不适用于高维数据 |
拟牛顿法 | 收敛速度快,不用计算二阶导数,低运算复杂度 | 存储正定矩阵,内存消耗大 | 不适用于高维数据 |
批量梯度下降 | 目标函数为凸函数时,可以找到全局最优值 | 收敛速度慢,需要用到全部数据,内存消耗大 | 不适用于大数据集,不能在线更新模型 |
随机梯度下降 | 避免冗余数据的干扰,收敛速度加快,能够在线学习 | 更新值的方差较大,收敛过程会产生波动,可能落入极小值,选择合适的学习率比较困难 | 适用于需要在线更新的模型,适用于大规模训练样本情况 |
小批量梯度下降 | 降低更新值的方差,收敛较为稳定 | 选择合适的学习率比较困难 |
|
Momentum | 能够在相关方向加速SGD,抑制振荡,从而加快收敛 | 需要人工设定学习率 | 适用于有可靠的初始化参数 |
Nesterov | 梯度在大的跳跃后,进行计算对当前梯度进行校正 | 需要人工设定学习率 |
|
Adagrad | 不需要对每个学习率手工地调节 | 仍依赖于人工设置一个全局学习率,学习率设置过大,对梯度的调节太大。中后期,梯度接近于0,使得训练提前结束 | 需要快速收敛,训练复杂网络时;适合处理稀疏梯度 |
Adadelta | 不需要预设一个默认学习率,训练初中期,加速效果不错,很快,可以避免参数更新时两边单位不统一的问题。 | 训练后期,反复在局部最小值附近抖动 | 需要快速收敛,训练复杂网络时 |
RMSprop | 解决 Adagrad 激进的学习率缩减问题 | 依然依赖于全局学习率 | 需要快速收敛,训练复杂网络时;适合处理非平稳目标 - 对于RNN效果很好 |
Adam | 对内存需求较小,为不同的参数计算不同的自适应学习率 |
| 需要快速收敛,训练复杂网络时;善于处理稀疏梯度和处理非平稳目标的优点,也适用于大多非凸优化 - 适用于大数据集和高维空间 |