一、AdaGrad
AdaGrad算法,即adaptive gradient,自适应梯度法。它通过记录每次迭代过程中的前进方向和距离,从而使得针对不同问题,有一套自适应调整学习率的方法,即不同的参数是需要不同的学习率的。具有损失较大偏导的参数相应地有一个快速下降的学习率,而具有小偏导的参数在学习率上有相对较小的下降。
AdaGrad旨在应用于凸问题时快速收敛,具体算法如下:
从上图可以看出,随着迭代的增加,我们的学习率是在逐渐变小的,这在“直观上”是正确的:当我们越接近最优解时,函数的“坡度”会越平缓,我们也必须走的更慢来保证不会穿过最优解。
AdaGrad的效果是:在参数空间中更为平缓的倾斜方向会取得更大的进步(因为平缓,所以历史梯度平方和较小,对应学习下降的幅度较小)。
优点:解决了SGD中学习率不能自适应调整的问题。
缺点:(1)对于训练深度神经网络模型而言,从训练开始时累积平方梯度值会越来越大,会导致学习率过早和过量的减少,从而导致迭代后期收敛及其缓慢。AdaGrad在某些深度学习模型上效果不错,但不是全部。(2)需要手动设置全局学习率
二、RMSProp
RMSProp算法,其实它就是Adadelta(Hinton, 2012),这里的RMS就是Adadelta中定义的RMS,也有人说它是一个特例, 的Adadelta。与Adadelta另一个不同是还是需要学习率的,建议默认值为:0.001。
RMSProp算法是AdaGrad算法的改进,修改AdaGrad以在非凸条件下效果更好,解决了AdaGrad所面临的问题。
RMSProp主要思想:使用指数加权移动平均的方法计算累积梯度,以丢弃遥远的梯度历史信息(让距离当前越远的梯度的缩减学习率的权重越小)。
再看看使用Nesterov动量的RMSProp算法,直观上理解就是:RMSProp改变了学习率,Nesterov引入动量改变了梯度,从两方面改进更新方式。
优点:完全自适应全局学习率,加速效果好。
缺点:后期容易在小范围内产生震荡。
代码如下:
import torch
optimizer = torch.optim.RMSprop(params, lr = lr, momentum = 0.9, weight_decay = weight_decay)
三、Adam
Adam算法可能是除了SGD算法之外大家最熟悉的了,如果你不知道用什么优化方法时,无脑用它就对了。
Adam算法的本质:其实就是Momentum+RMSProp的结合,然后再修正其偏差。Adam对梯度的一阶和二阶都进行了估计与偏差修正,使用梯度的一阶矩估计和二阶矩估计来动态调整每个参数的学习率(参数更新的幅度)。
Adam对学习率没有那么敏感,建议默认为0.001,实践中,也可以设置为 。Adam通常被认为对超参数的选择相当鲁棒,同时相比于Adagrad,不用存储全局所有的梯度,适合处理大规模数据。
Adam每次迭代参数的学习步长都有一个确定的范围,不会因为很大的梯度导致很大的学习步长,参数的值比较稳定,但是它也并非真的是参数不敏感的,学习率在训练的后期可仍然可能不稳定导致无法收敛到足够好的值,泛化能力较差。
代码如下:
import torch
optimizer = torch.optim.Adam(params, lr = lr, weight_decay = weight_decay)