深度学习优化算法经历了 SGD -> SGDM -> NAG ->AdaGrad -> AdaDelta -> Adam -> Nadam 这样的发展历程。我们结合CS231n课程中的讲解来比较一下这些优化算法的优缺点。
1 SGD 随机梯度下降
SGD示意图:

|
1 2 3 4 |
# SGD伪代码 while True: dx = gradient(x) x += learning_rate * dx |
缺点:
SGD最大的缺点是下降速度慢(下降速度固定),而且可能会在沟壑的两边持续震荡,停留在一个局部最小值。当遇到鞍点时,由于梯度为0而无法下降。
2 SGD+Momentum(SGDM) 带动量的SGD
|
1 2 3 4 5 6 |
# SGDM伪代码 vx = 0 while True: dx = gradient(x) vx = rho * vx + dx # rho表示“摩擦力”的作用,通常为0.9或0.99 x += learning_rate * vx |
由于加入了速度值,能够更快收敛,在鞍点虽然梯度为0,仍然可以下降。
SGD还有一个问题是困在局部最优的沟壑里面震荡,因此引入了Nesterov Acceleration来解决这个问题。
3 SGD with Nesterov Acceleration(NAG)
Nesterov Acceleration考虑到了动量的累积,当累积了足够的动量时就可以跳出局部最小点。由于累积动量的存在,NAG有时会忽略陡峭的局部最小值(类似于骑摩托车加速飞跃沟壑)。
|
1 2 3 4 5 |
# NAG伪代码 dx = gradient(x) old_v = v v = rho * v - learning_rate * dx x += -rho * old_v + (1 + rho) * v |
以上的几种优化方法都只用到了一阶动量。但是没有考虑到的是,对于经常更新的参数,我们希望学习率低一些,对于不经常更新的参数,我们希望学习率大一些,为此引入了自适应学习率的优化算法。
4 AdaGrad
AdaGrad优化算法记录梯度的累积值,梯度累积越大,学习率越小。
|
1 2 3 4 5 6 7 |
# AdaGrad伪代码 grad_squared = 0 while True: dx = gradient(x) grad_squared += dx * dx # 累积变化越大时,学习率越小 x -= learning_rate * dx / (np.sqrt(grad_squared + 1e-7)) |
缺点:
因为AdaGrad的学习率是单调递增的,会使得学习率逐渐趋向于0,可能会使得训练过程提前结束,即便后续还有数据也无法学到必要的知识。
5 AdaDelta / RMSProp
由于AdaGrad单调递减的特性导致后期学不到东西,AdaDelta只关注过去一段时间窗口的下降梯度,而不是累积全部的历史梯度。RMSProp在累积梯度的同时持续衰减累积值。这样就避免了二阶动量持续累积、导致训练过程提前结束的问题。
|
1 2 3 4 5 6 |
# RMSProp伪代码 grad_squared = 0 while True: dx = gradient(x) grad_squared = decay_rate * grad_squared + (1 - decay_rate)* dx * dx # decay_rate通常取0.9或0.99 x -= learning_rate * dx / (np.sqrt(grad_squared + 1e-7)) |

6 Adam
将以上的一阶动量与二阶动量结合,就产生了Adam优化算法。
|
1 2 3 4 5 6 7 8 9 10 |
# Adam伪代码 first_moment = 0 second_moment = 0 for t in range(num_iterations): dx = gradient(x) first_moment = beta1 * first_moment + (1 - beta1) * dx second_moment = beta2 * second_moment + (1 - beta2) * dx * dx first_unbias = first_moment / (1 - beta1 ^ t) second_unbias = second_moment / (1 - beta2 ^ t) # 防止刚开始训练时second_moment很小产生很大的学习率。 x -= learning_rate * first_unbias / (np.sqrt(second_unbias + 1e-7)) |
Adam优化算法一般取beta1=0.9,beta2=0.999,learning_rate=1e-3或5e-4。
7 Nadam
Nadam在Adam的基础上加入了一阶动量的累积,即Nesterov + Adam = Nadam。
8 总结
| 优化算法 | Momentum(动量) | Nesterov(动量累积) | 二阶动量累积 |
|---|---|---|---|
| SGD | × | × | × |
| SGDM | ○ | × | × |
| NAG | ○ | ○ | × |
| AdaGrad | × | × | 一直累积 |
| AdaDelta / RMSProp | × | × | 一段时间 |
| Adam | ○ | × | ○ |
| Nadam | ○ | ○ | ○ |
9 参考资料
CS231n Lecture7 https://www.bilibili.com/video/av13260183/?p=7
http://www.sohu.com/a/226332315_633698
https://blog.csdn.net/shuzfan/article/details/75675568#2-1-batch-gradient-descent-bgd




最新评论
博主好,路过留言交流一下~我在做源头中转 Twinkle Model(利益相关):GPT 1折、国模 1折(GLM/DeepSeek/Kimi)、满血 Claude,低价稳定。价格全在模型广场 https://big-model.smart-agi.com/model-plaza ,有兴趣可以看看。
博主分享的 Surge 增强模式接管应用分流思路很赞!确实,系统大版本升级后,老牌 Proxifier 由于底层驱动兼容性问题经常莫名崩溃。在 Mac 上有 Surge 这种神器接管,但是在 Windows 平台上,很多人又很难找到兼顾‘轻量分流+稳定不崩溃’的工具:ProxiFyre 依赖 WireSock 内核驱动容易蓝屏且纯命令行,开 TUN 虚拟网卡又会把开发网段和公司 VPN 改乱。 如果是 Windows 用户寻找 Proxifier 替代品,非常推荐关注 Ghost Proxifier Pro: - 纯用户态 Winsock API Hook:完全免安装内核驱动和虚拟网卡,零蓝屏隐患,不改动系统默认网关与路由表; - 智能递归子进程树:很多现代客户端(如播放器、流媒体套件、IDE)会派生子进程,它能自动递归识别并接管流量,杜绝漏代理; - 现代 Fluent 图形界面:直接拖入目标 exe 即可一键绑定 SOCKS5/HTTP 节点,比老版配置规则直观很多。 注:该工具为非开源的独立客户端软件。 - 官网主页:https://ghostproxifier.com - 项目发布:https://github.com/liliBestCoder/ghost-proxifier-pro
曾经最爱之一,还有emlog,zblog
感谢分享经验,谢谢站长!!已收藏
牛牛牛
同样
站长您好,亚马逊云咨询推广资源,望建立联系,可邮件,谢谢。
换友情链接吗?