闲鱼技术01 发表于 2021-7-31 17:06

从 SGD 到 Adam —— 深度学习优化算法概览(一)

楔子

前些日在写计算数学课的期末读书报告,我选择的主题是「分析深度学习中的各个优化算法」。在此前的工作中,自己通常就是无脑「Adam 大法好」,而对算法本身的内涵不知所以然。一直希望能抽时间系统的过一遍优化算法的发展历程,直观了解各个算法的长处和短处。这次正好借着作业的机会,补一补课。
本文主要借鉴了 @Juliuszh 的文章思路,使用一个 general 的框架来描述各个梯度下降变种算法。实际上,本文可以视作对的重述,在此基础上,对原文描述不够详尽的部分做了一定补充,并修正了其中许多错误的表述和公式。
另一主要参考文章是 Sebastian Ruder 的综述。该文十分有名,大概是深度学习优化算法综述中质量最好的一篇了。建议大家可以直接阅读原文。本文许多结论和插图引自该综述。
对优化算法进行分析和比较的文章已有太多,本文实在只能算得上是重复造轮,旨在个人学习和总结。希望对优化算法有深入了解的同学可以直接查阅文末的参考文献。
引言

最优化问题是计算数学中最为重要的研究方向之一。而在深度学习领域,优化算法的选择也是一个模型的重中之重。即使在数据集和模型架构完全相同的情况下,采用不同的优化算法,也很可能导致截然不同的训练效果。
梯度下降是目前神经网络中使用最为广泛的优化算法之一。为了弥补朴素梯度下降的种种缺陷,研究者们发明了一系列变种算法,从最初的 SGD (随机梯度下降) 逐步演进到 NAdam。然而,许多学术界最为前沿的文章中,都并没有一味使用 Adam/NAdam 等公认“好用”的自适应算法,很多甚至还选择了最为初级的 SGD 或者 SGD with Momentum 等。
本文旨在梳理深度学习优化算法的发展历程,并在一个更加概括的框架之下,对优化算法做出分析和对比。
Gradient Descent

梯度下降是指,在给定待优化的模型参数 https://www.zhihu.com/equation?tex=%5Ctheta+%5Cin+%5Cmathbb%7BR%7D%5Ed 和目标函数后,算法通过沿梯度 https://www.zhihu.com/equation?tex=%5Cnabla_%5Ctheta+J%28%5Ctheta%29 的相反方向更新 https://www.zhihu.com/equation?tex=%5Ctheta 来最小化。学习率 https://www.zhihu.com/equation?tex=%5Ceta 决定了每一时刻的更新步长。对于每一个时刻 https://www.zhihu.com/equation?tex=t ,我们可以用下述步骤描述梯度下降的流程:
(1) 计算目标函数关于参数的梯度

https://www.zhihu.com/equation?tex=g_t+%3D+%5Cnabla_%5Ctheta+J%28%5Ctheta%29
(2) 根据历史梯度计算一阶和二阶动量

https://www.zhihu.com/equation?tex=m_t+%3D+%5Cphi%28g_1%2C+g_2%2C+%5Ccdots%2C+g_t%29

https://www.zhihu.com/equation?tex=v_t+%3D+%5Cpsi%28g_1%2C+g_2%2C+%5Ccdots%2C+g_t%29
(3) 更新模型参数

https://www.zhihu.com/equation?tex=%5Ctheta_%7Bt%2B1%7D+%3D+%5Ctheta_t+-+%5Cfrac%7B1%7D%7B%5Csqrt%7Bv_t+%2B+%5Cepsilon%7D%7D+m_t
其中, https://www.zhihu.com/equation?tex=%5Cepsilon 为平滑项,防止分母为零,通常取 1e-8。
Gradient Descent 和其算法变种

根据以上框架,我们来分析和比较梯度下降的各变种算法。
Vanilla SGD

朴素 SGD (Stochastic Gradient Descent) 最为简单,没有动量的概念,即

https://www.zhihu.com/equation?tex=m_t+%3D+%5Ceta+g_t

https://www.zhihu.com/equation?tex=v_t+%3D+I%5E2

https://www.zhihu.com/equation?tex=%5Cepsilon+%3D+0
这时,更新步骤就是最简单的

https://www.zhihu.com/equation?tex=%5Ctheta_%7Bi%2B1%7D%3D+%5Ctheta_t+-+%5Ceta+g_t
SGD 的缺点在于收敛速度慢,可能在鞍点处震荡。并且,如何合理的选择学习率是 SGD 的一大难点。
Momentum

SGD 在遇到沟壑时容易陷入震荡。为此,可以为其引入动量 Momentum,加速 SGD 在正确方向的下降并抑制震荡。

https://www.zhihu.com/equation?tex=m_t+%3D+%5Cgamma+m_%7Bt-1%7D+%2B+%5Ceta+g_t
SGD-M 在原步长之上,增加了与上一时刻步长相关的 https://www.zhihu.com/equation?tex=%5Cgamma+m_%7Bt-1%7D ,https://www.zhihu.com/equation?tex=%5Cgamma 通常取 0.9 左右。这意味着参数更新方向不仅由当前的梯度决定,也与此前累积的下降方向有关。这使得参数中那些梯度方向变化不大的维度可以加速更新,并减少梯度方向变化较大的维度上的更新幅度。由此产生了加速收敛和减小震荡的效果。
图 1(a): SGD
图 1(b): SGD with momentum
从图 1 中可以看出,引入动量有效的加速了梯度下降收敛过程。
Nesterov Accelerated Gradient

HuldaGnodim 发表于 2021-7-31 17:09

动态图很棒!

XGundam05 发表于 2021-7-31 17:15

动图是引用的别人工作。这两张图做的很棒,在很多讲解优化的文章里都能看到大家在用。提到的引文里的解读更为详尽,推荐阅读

Doris232 发表于 2021-7-31 17:21

不可以,这只是重复别人的工作

Ylisar 发表于 2021-7-31 17:25

看不懂在说什么

FeastSC 发表于 2021-7-31 17:26

最原始的GD和momentum没关系吧...

量子计算9 发表于 2021-7-31 17:29

这两个动图,是跑出来的,还是后期制作出来的呀?就是我跑一个梯度下降,然后能帮我生成一个这样的图,还是说借助动画工具只是简单的生成的?感觉很棒啊。好想自己也做一次试试。

TheLudGamer 发表于 2021-7-31 17:30

印象中是手工构造了数据,这个应该不只是示意图。文中有图源,感兴趣可以查看

fwalker 发表于 2021-7-31 17:36

支持一下好文章,看了Juliuszh的文章,存疑处和楼主相同,进而发现这篇。然后发现楼主也是那篇英文博客的受益者。。。

FeastSC 发表于 2021-7-31 17:39

请问前辈动态图怎么做出来的?有源码可以分享吗?谢谢前辈,比心!
页: [1] 2 3
查看完整版本: 从 SGD 到 Adam —— 深度学习优化算法概览(一)