通俗易懂讲透动量法(Momentum)优化算法

通俗易懂讲透动量法(Momentum)优化算法(本科生/研究生都能看懂)

本文用大白话+下山比喻+公式拆解+完整代码+对比总结,把动量法从原理、流程、优缺点到适用场景讲得清清楚楚,适合深度学习入门、面试复习、课程笔记。


一、先搞懂:我们为什么需要动量法?

普通梯度下降(SGD)有两个致命问题:

  1. 遇到狭长山谷会疯狂震荡,走不进谷底
  2. 收敛太慢,每一步只看当前坡度,不看历史方向

于是就有了动量法(Momentum)

给梯度下降加上惯性,顺着趋势走,不被小波动晃来晃去。

一句话总结:
动量法 = 带惯性的梯度下降,更快、更稳、不震荡。


二、动量法是什么?(超形象比喻)

把优化看成骑自行车下山找谷底

  • 普通梯度下降:每步只看脚下坡度,一遇到坑就晃,下坡不敢加速
  • 动量法:车轮带惯性,下坡自动加速,小坑小坎直接碾过去,方向更稳

核心逻辑:
记住之前往哪走,顺着历史方向继续冲,平滑震荡、加速收敛。


三、动量法核心思想(不用公式也能懂)

  1. 维护一个速度变量 v:记录过去梯度的“惯性”
  2. 梯度方向一致时加速:下坡越走越快
  3. 梯度方向变化时减速:左右晃动被抵消,更平稳
  4. 不计算二阶信息:比牛顿法简单,比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=γvt1+ηgt

  • γ\gammaγ:动量系数,一般取 0.9
  • vt−1v_{t-1}vt1:上一步速度
  • η\etaη:学习率
  • gtg_tgt:当前梯度
第2步:更新参数(顺着速度走)

θt+1=θt−vt\theta_{t+1} = \theta_t - v_tθt+1=θtvt

✅ 直白解释:

  • 速度 = 历史惯性 + 新梯度
  • 顺着速度方向更新,而不是只看当前梯度

五、Nesterov 动量法(升级版)

Nesterov 是动量法的加强版,先看路再走

  1. 先按惯性走一步
  2. 在“预判位置”算梯度
  3. 再修正方向

公式:
vt=γvt−1+η∇J(θ−γvt−1)v_t = \gamma v_{t-1} + \eta \nabla J(\theta - \gamma v_{t-1})vt=γvt1+ηJ(θγvt1)
θt+1=θt−vt\theta_{t+1} = \theta_t - v_tθt+1=θtvt

通常比普通动量法更快更准


六、动量法完整算法流程(4步背会)

  1. 初始化:θ\thetaθ、速度 v=0v=0v=0
  2. 计算当前梯度 gtg_tgt
  3. 更新速度 vt=γvt−1+ηgtv_t = \gamma v_{t-1} + \eta g_tvt=γvt1+ηgt
  4. 用速度更新参数 θt+1=θt−vt\theta_{t+1} = \theta_t - v_tθt+1=θtvt
  5. 重复直到收敛

七、代码实战:动量法 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()

八、动量法优点(面试必背)

  1. 加速收敛:同向梯度叠加,下坡自动加速
  2. 抑制震荡:抵消方向冲突的梯度,平稳穿越峡谷
  3. 抵抗噪声:对梯度噪声更鲁棒
  4. 实现简单:只多一个速度变量,计算量小
  5. 兼容性强:可与学习率衰减、自适应算法结合

九、动量法缺点(必须知道)

  1. 超参数敏感γ\gammaγη\etaη 需要调
  2. 可能冲过最优解:惯性太大容易“飞过”谷底
  3. 无自适应学习率:各维度用同一个步长
  4. 稀疏梯度一般:不如 Adam/RMSProp

十、优化算法对比表(速记)

算法惯性自适应速度适用场景
SGD简单场景
Momentum复杂非凸、震荡大
RMSPropRNN、不稳定梯度
Adam最快深度学习通用

十一、什么时候用动量法?

推荐用动量法

  • 损失函数呈狭长山谷形状
  • 梯度震荡大、噪声多
  • 深度学习网络(CNN、DNN)
  • 想要简单、快速、稳定的优化器

不推荐用

  • 稀疏数据/NLP → 用 Adam/RMSProp
  • 超参数不想调 → 直接用 Adam
  • 极小数据集 → 用 SGD 即可

十二、一句话总结

动量法通过给梯度下降加上“惯性”,有效平滑震荡、加速收敛,是深度学习最基础、最实用的优化思想之一。Nesterov 是它的更强版本。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DeepModel

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值