一、各优化算法简介
1. 批量梯度下降(Batch gradient descent,BGD)
每迭代一步,都要用到训练集所有的数据。
2. 随机梯度下降(Stochastic Gradient Descent,SGD)
通过每个样本来迭代更新一次,以损失很小的一部分精确度和增加一定数量的迭代次数为代价,换取了总体的优化效率的提升。增加的迭代次数远远小于样本的数量。
缺点:
- 对于参数比较敏感,需要注意参数的初始化
- 容易陷入局部极小值
- 当数据较多时,训练时间长
3. 小批量梯度下降(Mini Batch Gradient Descent,MBGD)
为了避免SGD和标准梯度下降中存在的问题,对每个批次中的n个训练样本,这种方法只执行一次更新。
4. Momentum
在参数更新时,一定程度上保留更新之前的方向。在训练的过程中,参数的更新方向十分依赖当前的batch,因此不稳定。加入momentum后,能够让参数一定程度上按照之前变化方向进行更新,使参数更稳定的更新。
优点:
- 下降初期时,使用上一次参数更新,下降方向一致,乘上较大的μ能够进行很好的加速
- 下降中后期时,在局部最小值来回震荡的时候,gradient→0,μ使得更新幅度增大,跳出陷阱
- 在梯度改变方向的时候,μ能够减少更新 总而言之,momentum项能够在相关方向加速SGD,抑制振荡,从而加快收敛
5. Nesterov(NAG)
NAG 法则首先(试探性地)在之前积累的梯度方向(棕色向量)前进一大步,再根据当前地情况修正,以得到最终的前进方向(绿色向量)。这种基于预测的更新方法,使我们避免过快地前进,并提高了算法地响应能力,大大改进了 RNN 在一些任务上的表现。
其实,momentum项和nesterov项都是为了使梯度更新更加灵活,对不同情况有针对性。但是,人工设置一些学习率总还是有些生硬。
6. Adagrad
Adagrad是一个基于梯度的优化算法,它的主要功能是:它对不同的参数调整学习率,具体而言,对低频出现的参数进行大的更新,对高频出现的参数进行小的更新。
优点:
- 适合处理稀疏梯度
缺点:
- 仍依赖于人工设置一个全局学习率
- η设置过大的话,会使regularizer过于敏感,对梯度的调节太大
- 中后期,分母上梯度平方的累加将会越来越大,使gradient→0,使得训练提前结束
7. Adadelta
Adadelta法是Adagrad法的一个延伸,它旨在解决它学习率不断单调下降的问题。相比计算之前所有梯度值的平方和,Adadelta 法只累加固定大小的项,并且也不直接存储这些项,仅仅是近似计算对应的平均值。
优点:
- 不用依赖于全局学习率了
- 训练初中期,加速效果不错,很快
- 避免参数更新时两边单位不统一的问题
缺点:
- 训练后期,反复在局部最小值附近抖动
8. RMSprop
RMSprop也将学习率除以了一个指数衰减的衰减均值。
优点:
- 适合处理非平稳目标(就是过程依赖于时间的) - 对于RNN效果很好,因为RMSprop的更新只依赖于上一时刻的更新,所以适合。
缺点:
- 其实RMSprop依然依赖于全局学习率
9. Adam
利用梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率,使学习率在每一次更新的时候都有一个固定范围的步长,让参数更新时保持稳定。
优点:
- 结合了Adagrad善于处理稀疏梯度和RMSprop善于处理非平稳目标的优点
- 对内存需求较小
- 为不同的参数计算不同的自适应学习率
- 也适用于大多非凸优化 - 适用于大数据集和高维空间
二、优化算法相关知识点补充
1. 训练优化器的目的
- 加速收敛 2. 防止过拟合 3. 防止局部最优
2. 选用优化器的目的
在构建神经网络模型时,选择出最佳的优化器,以便快速收敛并正确学习,同时调整内部参数,最大程度地最小化损失函数。
3. 该如何选取优化器
- Adam在实际应用中效果良好,超过了其他的自适应技术。
- 如果输入数据集比较稀疏,SGD、NAG和动量项等方法可能效果不好。因此对于稀疏数据集,应该使用某种自适应学习率的方法,且另一好处为不需要人为调整学习率,使用默认参数就可能获得最优值。
- 如果想使训练深层网络模型快速收敛或所构建的神经网络较为复杂,则应该使用Adam或其他自适应学习速率的方法,因为这些方法的实际效果更优。
- SGD通常训练时间更长,但是在好的初始化和学习率调度方案的情况下,结果更可靠。
4. 为什么神经网络的训练不采用二阶优化方法 (如Newton, Quasi Newton)?
- 最主要原因还是计算量太大。由于牛顿法使用了二阶导数,每次迭代式都要求海森矩阵的逆,计算复杂度太高,高维问题中几乎不可行。拟牛顿法不要求计算二阶导数,但是需要存储海森矩阵的近似逆矩阵,当数据维度高时,内存消耗大。【如果一个优化问题是n维的,那么单轮梯度下降的复杂度是O(n),Quasi-Newton是O(n^2),而Newton method是O(n^3)。在神经网络中,n是神经网络中参数的个数,此时n^3和n之间的差距将非常巨大,虽然牛顿法迭代次数远少于梯度法,但无法弥补单轮复杂度上的巨大劣势。】
- 考虑cost 和样本数量的关系。实际中,在相同的时间内使用更多的样本信息所得的效果比使用较少样本更好。对二阶优化算法来说,同样的计算时间中,BFGS只能在一个mini-batch上迭代一次,而SGD能在n个mini-batch上进行迭代,后者取得的cost improvement 比前者更好。这时候,使用二阶方法是不值得的。
- 稳定性。对于优化算法,梯度下降等一阶算法只要步长不选太大基本都不会出问题,但二阶方法遍地是坑,二阶导数不存在,数值稳定性啊等等。现在做训练深度神经网络很多动不动就要几天,我们很不希望看到的一点就训练到一半跑挂了。特别是工业界已经上线的一些实际产品,模型每天都要更新,不可能经常有人盯着,这时往往就要求训练中不会出现任何问题。
5. 优化SGD的其他手段
-
重排法(Shuffling)和递进学习(Curriculum Learning)
每次迭代后,对训练数据集中的样本进行重排(shuffling),然后按照一定的顺序遍历训练样本,可以避免引入偏差,改进学习效果及加快收敛速度。 -
批量标准化(Batch Normalization)
批量标准化对每小批数据都重新进行标准化,并也会在操作中逆传播(back-propgate)变化量。在模型中加入批量标准化后,我们能使用更高的学习率且不要那么在意初始化参数。此外,批量正则化还可以看作是一种正则化手段,能够减少(甚至去除)留出法的使用。 -
早停(Early Stopping)
在训练过程中,关注模型在验证集上的误差情况,并且在改误差没有明显改进的时候停止训练。 -
梯度噪声(Gradient Noise)
在每次梯度的更新中,向其中加入一个服从合高斯分布 N(0,σ^2) 的噪声值:
gt,i=gt,i+N(0,δ2t)
并按照如下的方式修正方差:
δ2t=η(1+t)γ
这种方式能够提升神经网络在不良初始化前提下的鲁棒性,并能帮助训练特别是深层、复杂的神经网络。他们发现,加入噪声项之后,模型更有可能发现并跳出在深度网络中频繁出现的局部最小值。
附录:
最优化算法对比
算法 | 优点 | 缺点 | 适用情况 |
---|---|---|---|
牛顿法 | 收敛速度快 | 靠近极小值时收敛速度减慢,求解Hessian矩阵的逆矩阵复杂,容易陷入鞍点 | 不适用于高维数据 |
拟牛顿法 | 收敛速度快,不用计算二阶导数,低运算复杂度 | 存储正定矩阵,内存消耗大 | 不适用于高维数据 |
批量梯度下降 | 目标函数为凸函数时,可以找到全局最优值 | 收敛速度慢,需要用到全部数据,内存消耗大 | 不适用于大数据集,不能在线更新模型 |
随机梯度下降 | 避免冗余数据的干扰,收敛速度加快,能够在线学习 | 更新值的方差较大,收敛过程会产生波动,可能落入极小值,选择合适的学习率比较困难 | 适用于需要在线更新的模型,适用于大规模训练样本情况 |
小批量梯度下降 | 降低更新值的方差,收敛较为稳定 | 选择合适的学习率比较困难 | |
Momentum | 能够在相关方向加速SGD,抑制振荡,从而加快收敛 | 需要人工设定学习率 | 适用于有可靠的初始化参数 |
Nesterov | 梯度在大的跳跃后,进行计算对当前梯度进行校正 | 需要人工设定学习率 | |
Adagrad | 不需要对每个学习率手工地调节 | 仍依赖于人工设置一个全局学习率,学习率设置过大,对梯度的调节太大。中后期,梯度接近于0,使得训练提前结束 | 需要快速收敛,训练复杂网络时;适合处理稀疏梯度 |
Adadelta | 不需要预设一个默认学习率,训练初中期,加速效果不错,很快,可以避免参数更新时两边单位不统一的问题。 | 训练后期,反复在局部最小值附近抖动 | 需要快速收敛,训练复杂网络时 |
RMSprop | 解决 Adagrad 激进的学习率缩减问题 | 依然依赖于全局学习率 | 需要快速收敛,训练复杂网络时;适合处理非平稳目标 - 对于RNN效果很好 |
Adam | 对内存需求较小,为不同的参数计算不同的自适应学习率 | 需要快速收敛,训练复杂网络时;善于处理稀疏梯度和处理非平稳目标的优点,也适用于大多非凸优化 - 适用于大数据集和高维空间 |