通俗易懂讲透动量法(Momentum)优化算法(本科生/研究生都能看懂)
本文用大白话+下山比喻+公式拆解+完整代码+对比总结,把动量法从原理、流程、优缺点到适用场景讲得清清楚楚,适合深度学习入门、面试复习、课程笔记。
一、先搞懂:我们为什么需要动量法?
普通梯度下降(SGD)有两个致命问题:
- 遇到狭长山谷会疯狂震荡,走不进谷底
- 收敛太慢,每一步只看当前坡度,不看历史方向
于是就有了动量法(Momentum):
给梯度下降加上惯性,顺着趋势走,不被小波动晃来晃去。
一句话总结:
动量法 = 带惯性的梯度下降,更快、更稳、不震荡。
二、动量法是什么?(超形象比喻)
把优化看成骑自行车下山找谷底:
- 普通梯度下降:每步只看脚下坡度,一遇到坑就晃,下坡不敢加速
- 动量法:车轮带惯性,下坡自动加速,小坑小坎直接碾过去,方向更稳
核心逻辑:
记住之前往哪走,顺着历史方向继续冲,平滑震荡、加速收敛。
三、动量法核心思想(不用公式也能懂)
- 维护一个速度变量 v:记录过去梯度的“惯性”
- 梯度方向一致时加速:下坡越走越快
- 梯度方向变化时减速:左右晃动被抵消,更平稳
- 不计算二阶信息:比牛顿法简单,比SGD强
四、动量法公式一步步拆解(详细易懂)
1. 普通梯度下降(对照)
θt+1=θt−η gt\theta_{t+1} = \theta_t - \eta \, g_tθt+1=θt−ηgt
只看当前梯度,没有记忆。
2. 动量法核心公式(2步)
第1步:更新速度(累积惯性)
vt=γ vt−1+η gtv_t = \gamma \, v_{t-1} + \eta \, g_tvt=γvt−1+ηgt
- γ\gammaγ:动量系数,一般取 0.9
- vt−1v_{t-1}vt−1:上一步速度
- η\etaη:学习率
- gtg_tgt:当前梯度
第2步:更新参数(顺着速度走)
θt+1=θt−vt\theta_{t+1} = \theta_t - v_tθt+1=θt−vt
✅ 直白解释:
- 速度 = 历史惯性 + 新梯度
- 顺着速度方向更新,而不是只看当前梯度
五、Nesterov 动量法(升级版)
Nesterov 是动量法的加强版,先看路再走:
- 先按惯性走一步
- 在“预判位置”算梯度
- 再修正方向
公式:
vt=γvt−1+η∇J(θ−γvt−1)v_t = \gamma v_{t-1} + \eta \nabla J(\theta - \gamma v_{t-1})vt=γvt−1+η∇J(θ−γvt−1)
θt+1=θt−vt\theta_{t+1} = \theta_t - v_tθt+1=θt−vt
通常比普通动量法更快更准。
六、动量法完整算法流程(4步背会)
- 初始化:θ\thetaθ、速度 v=0v=0v=0
- 计算当前梯度 gtg_tgt
- 更新速度 vt=γvt−1+ηgtv_t = \gamma v_{t-1} + \eta g_tvt=γvt−1+ηgt
- 用速度更新参数 θt+1=θt−vt\theta_{t+1} = \theta_t - v_tθt+1=θt−vt
- 重复直到收敛
七、代码实战:动量法 vs Nesterov 优化香蕉函数
直接复制可运行,包含标准动量法 + Nesterov + 可视化对比。
import numpy as np
import matplotlib.pyplot as plt
# ===================== 1. 定义 Rosenbrock 香蕉函数 =====================
def rosenbrock(X):
x, y = X[0], X[1]
return (1 - x)**2 + 100 * (y - x**2)**2
def grad_rosenbrock(X):
x, y = X[0], X[1]
dx = -2*(1 - x) - 400*x*(y - x**2)
dy = 200*(y - x**2)
return np.array([dx, dy])
# ===================== 2. 标准动量法 =====================
def momentum(grad_func, init, lr=0.001, gamma=0.9, max_iter=10000, tol=1e-6):
theta = init.copy()
v = np.zeros_like(theta)
path = [theta.copy()]
loss = [rosenbrock(theta)]
for i in range(max_iter):
g = grad_func(theta)
if np.linalg.norm(g) < tol:
print(f"动量法收敛于迭代:{i}")
break
v = gamma * v + lr * g
theta = theta - v
path.append(theta.copy())
loss.append(rosenbrock(theta))
return np.array(path), np.array(loss)
# ===================== 3. Nesterov 动量法 =====================
def nesterov(grad_func, init, lr=0.001, gamma=0.9, max_iter=10000, tol=1e-6):
theta = init.copy()
v = np.zeros_like(theta)
path = [theta.copy()]
loss = [rosenbrock(theta)]
for i in range(max_iter):
look_ahead = theta - gamma * v
g = grad_func(look_ahead)
if np.linalg.norm(g) < tol:
print(f"Nesterov收敛于迭代:{i}")
break
v = gamma * v + lr * g
theta = theta - v
path.append(theta.copy())
loss.append(rosenbrock(theta))
return np.array(path), np.array(loss)
# ===================== 4. 运行优化 =====================
init_point = np.array([-1.5, 2.0])
path_mom, loss_mom = momentum(grad_rosenbrock, init_point)
path_nag, loss_nag = nesterov(grad_rosenbrock, init_point)
# ===================== 5. 可视化 =====================
plt.figure(figsize=(12,5))
# 等高线+路径
plt.subplot(121)
X, Y = np.meshgrid(np.linspace(-2,2,400), np.linspace(-1,3,400))
Z = (1-X)**2 + 100*(Y-X**2)**2
plt.contourf(X,Y,Z,50,cmap='jet',alpha=0.7)
plt.plot(path_mom[:,0], path_mom[:,1], 'r-', label='Momentum')
plt.plot(path_nag[:,0], path_nag[:,1], 'lime', label='Nesterov')
plt.title('优化路径对比')
plt.legend()
# 损失曲线
plt.subplot(122)
plt.semilogy(loss_mom, label='Momentum')
plt.semilogy(loss_nag, label='Nesterov')
plt.title('损失收敛曲线')
plt.legend()
plt.grid()
plt.show()
八、动量法优点(面试必背)
- 加速收敛:同向梯度叠加,下坡自动加速
- 抑制震荡:抵消方向冲突的梯度,平稳穿越峡谷
- 抵抗噪声:对梯度噪声更鲁棒
- 实现简单:只多一个速度变量,计算量小
- 兼容性强:可与学习率衰减、自适应算法结合
九、动量法缺点(必须知道)
- 超参数敏感:γ\gammaγ 和 η\etaη 需要调
- 可能冲过最优解:惯性太大容易“飞过”谷底
- 无自适应学习率:各维度用同一个步长
- 稀疏梯度一般:不如 Adam/RMSProp
十、优化算法对比表(速记)
| 算法 | 惯性 | 自适应 | 速度 | 适用场景 |
|---|---|---|---|---|
| SGD | ❌ | ❌ | 慢 | 简单场景 |
| Momentum | ✅ | ❌ | 快 | 复杂非凸、震荡大 |
| RMSProp | ❌ | ✅ | 快 | RNN、不稳定梯度 |
| Adam | ✅ | ✅ | 最快 | 深度学习通用 |
十一、什么时候用动量法?
✅ 推荐用动量法
- 损失函数呈狭长山谷形状
- 梯度震荡大、噪声多
- 深度学习网络(CNN、DNN)
- 想要简单、快速、稳定的优化器
❌ 不推荐用
- 稀疏数据/NLP → 用 Adam/RMSProp
- 超参数不想调 → 直接用 Adam
- 极小数据集 → 用 SGD 即可
十二、一句话总结
动量法通过给梯度下降加上“惯性”,有效平滑震荡、加速收敛,是深度学习最基础、最实用的优化思想之一。Nesterov 是它的更强版本。
优化算法&spm=1001.2101.3001.5002&articleId=160005336&d=1&t=3&u=49343b3ed14e4e95b2b6940e56aa9acf)
1450

被折叠的 条评论
为什么被折叠?



