在上一篇文章里,我们介绍了SGD这个最朴素的梯度下降方法,以及其Momentum和NAG的优化改进方法。我们现在又回过头来看这个没加Momentum的图,可以看到在垂直方向上的梯度较大,走得很快,而水平方向上的位移较小,走的很慢,看着就很急!但你先别急,那么能不能不使用Momentum就让水平方向上的位移大一点,垂直方向上的位移小一点呢?
我们想要迄今为止梯度大的参数(即垂直方向)更新得慢一点,梯度小的参数(即水平方向)更新得快一点,这个就是二阶动量的定义:
其中,为当前时刻的二阶动量,是某一时刻的梯度,表示迄今所有梯度的平方和。AdaGrad就是在SGD的基础上,把二阶动量加入到参数更新的过程中:
其中,为模型参数,为学习率,这时学习速率就会根据二阶动量来自适应进行调整。
我们现在再从上述的二维图扩展到整个深度学习模型中,并不是所有模型参数都会被频繁更新。对于频繁更新的参数,由于我们已经积累了大量的先验信息,所以不希望被单个样本影响的太大,所以希望学习速率慢一点;对于偶尔更新的参数,我们想要它从偶尔出现的样本上尽可能获取更多得信息,所以希望学习速率快一点。
因此二阶动量可以在数据稀疏的情况下表现很好,因为稀疏数据中0占大多数,此时二阶动量累积梯度和较大,可以有效降低重复数据的学习速度。但是由于会随着训练过程不断增大,所以学习率最终会逼近于0,可能会造成训练的提前终止。
AdaGrad的伪代码流程如下,重点在最后两行,不考虑weight_decay的情况下,把梯度的平方累加到state_sum中,再用当前梯度除以state_sum乘以学习率来更新参数:
以下代码为pytorch官方AdaGrad代码。
业务合作/学习交流+v:lizhiTechnology
?如果想要了解更多优化器相关知识,可以参考我的专栏和其他相关文章:
【优化器】(一) SGD原理 & pytorch代码解析_sgd优化器-CSDN博客
【优化器】(二) AdaGrad原理 & pytorch代码解析_adagrad优化器-CSDN博客
【优化器】(三) RMSProp原理 & pytorch代码解析_rmsprop优化器-CSDN博客
【优化器】(四) AdaDelta原理 & pytorch代码解析_adadelta里rho越大越敏感-CSDN博客
【优化器】(五) Adam原理 & pytorch代码解析_adam优化器-CSDN博客
【优化器】(六) AdamW原理 & pytorch代码解析-CSDN博客
【优化器】(七) 优化器统一框架 & 总结分析_mosec优化器优点-CSDN博客
如果想要了解更多深度学习相关知识,可以参考我的其他文章:
电 话:400-123-4567
传 真:+86-123-4567
手 机:13800000000
邮 箱:admin@eyoucms.com
地 址:广东省广州市天河区88号