机器学习算法:随机梯度下降算法

目录

[动量法 是什么?](#动量法 是什么?)

从数学上理解

案例:寻找最佳学习节奏

公式推导与解析

[1. 基础梯度下降回顾](#1. 基础梯度下降回顾)

[2. 引入动量项](#2. 引入动量项)

[3. 物理意义与优势](#3. 物理意义与优势)

扩展:NAG (Nesterov Accelerated Gradient)

优缺点和适用场景

完整代码示例:在回归问题中对比SGD与动量法


有小伙伴在学优化算法时问,梯度下降已经有了随机版本,为什么还需要动量法?

它到底解决了什么问题?

今天,我们就来深入聊聊 动量法(Momentum),看看它是如何让梯度下降变得更"聪明"、更稳定的。

首先,动量法是一种在梯度下降基础上引入"惯性"思想的优化算法。它的目标是加速收敛,并减少优化过程中的振荡,让参数更新更加平滑。

下面,我们从一个生活化的比喻开始,逐步展开。

动量法 是什么?

想象你在下山,目标是尽快到达山谷最低处。

普通的下山方式是:看眼前最陡的方向,直接迈一步。

  • 普通梯度下降(GD/SGD): 就像每走一步都重新判断方向。如果地面坑洼不平(梯度有噪声),你的路径就会左摇右摆,走得很慢,甚至可能在沟壑里来回震荡。
  • 动量法(Momentum): 给你一个带轮子的滑板。你当前要前进的方向,不仅由这一步看到的坡度决定,还会受到之前速度(动量)的影响。这样,在平缓地带你会加速,遇到反向坡度时,惯性也能帮你冲过去一部分,减少摆动,整体路径更平滑、更快地指向山谷。

从数学上理解

动量法旨在最小化目标函数 L(θ),其更新规则在梯度下降的基础上增加了动量项:

  • θ:模型参数。

  • ∇θL(θt):当前时刻的梯度。

  • η:学习率,控制当前梯度的影响。

  • β:动量系数(通常取0.9左右),控制历史动量(速度)的保留比例。

  • vt:当前时刻的更新速度,它累积了历史梯度的方向。

核心思想:当前的更新方向是"历史方向"与"当前梯度方向"的加权组合。这有助于在梯度方向连续一致的方向上加速,在梯度方向频繁变化的方向上抑制振荡。

案例:寻找最佳学习节奏

假设你在调整学习计划中"每日做题数"和"每日复习小时数"两个参数,目标是让学习效率最高。效率损失函数为:

理想状态是 题=20, 时=3,此时损失最小。

模拟计算(对比SGD和动量法)

为了对比,我们先看SGD的更新过程(学习率 η=0.1η=0.1):

  1. 初始化:题 = 5, 时 = 1。

  2. 计算梯度:∂L∂题=2(5−20)=−30∂题∂L​=2(5−20)=−30,∂L∂时=2(1−3)=−4∂时∂L​=2(1−3)=−4。

  3. SGD更新:题 = 5 - 0.1*(-30) = 8.0, 时 = 1 - 0.1*(-4) = 1.4。

接下来,我们使用动量法(设 β=0.9,η=0.1β=0.9,η=0.1):

  1. 初始化参数:题 = 5, 时 = 1。

    初始化速度:v题=0,v时=0v题​=0,v时​=0。

  2. 计算当前梯度(同上):g题=−30,g时=−4g题​=−30,g时​=−4。

  3. 更新速度:

    v题=0.9∗0+0.1∗(−30)=−3.0v题​=0.9∗0+0.1∗(−30)=−3.0

    v时=0.9∗0+0.1∗(−4)=−0.4v时​=0.9∗0+0.1∗(−4)=−0.4

  4. 更新参数:

    题 = 5 - (-3.0) = 8.0

    时 = 1 - (-0.4) = 1.4

第一步结果看似与SGD相同,因为初始速度为0。

进行第二步 迭代:

当前参数:题=8.0, 时=1.4。

  1. 计算新梯度:

    g题=2(8.0−20)=−24.0g题​=2(8.0−20)=−24.0

    g时=2(1.4−3)=−3.2g时​=2(1.4−3)=−3.2

  2. SGD更新:题 = 8.0 - 0.1*(-24) = 10.4, 时 = 1.4 - 0.1*(-3.2) = 1.72。

  3. 动量法更新速度

    v题=0.9∗(−3.0)+0.1∗(−24.0)=−2.7−2.4=−5.1v题​=0.9∗(−3.0)+0.1∗(−24.0)=−2.7−2.4=−5.1

    v时=0.9∗(−0.4)+0.1∗(−3.2)=−0.36−0.32=−0.68v时​=0.9∗(−0.4)+0.1∗(−3.2)=−0.36−0.32=−0.68

  4. 动量法更新参数

    题 = 8.0 - (-5.1) = 13.1

    时 = 1.4 - (-0.68) = 2.08

对比可见:在第二步,动量法由于累积了第一步的梯度(速度-3.0),在参数"题"上的更新幅度(-5.1)远大于SGD的更新幅度(-2.4),从而更快地朝着最优值20靠近。这就是"动量"带来的加速效果。

公式推导与解析

1. 基础梯度下降回顾

标准梯度下降更新:

它只考虑当前时刻的梯度。

2. 引入动量项

为了模拟物理中的动量,我们引入速度变量 vt​,其更新是指数移动平均:

为了简化并与常见形式一致,令 α=η,并将(1−β)吸收进学习率或直接采用另一种常见表述:

参数更新为:

3. 物理意义与优势

将 vt 展开:

更新方向是当前梯度与历史梯度的加权和。越近的梯度权重越大。

  • 加速收敛:在损失函数曲面在某个方向持续下降(梯度方向一致)时,动量会不断累积,更新速度越来越快。

  • 抑制振荡:在梯度方向变化频繁(如峡谷形曲面)的方向上,正负梯度会部分抵消,使得更新幅度变小,路径更稳定。

扩展:NAG (Nesterov Accelerated Gradient)

动量法的一个改进版本是NAG,它"向前看"一步:

NAG先根据累积速度"预览"下一步的参数位置,然后计算该预览位置的梯度,再进行更新。

这使得它在面对即将变化的梯度时能更早地做出调整,理论上有更好的收敛性。

优缺点和适用场景

优点

  1. 加速收敛:在目标函数呈狭长峡谷状或存在平缓区域时,能显著加快训练速度。

  2. 减少振荡:平滑优化路径,使训练过程更稳定,有助于使用更大的学习率。

  3. 有助于跳出局部极小:动量带来的"惯性"可能帮助参数冲过一些狭窄的局部极小点。

缺点

  1. 引入超参数:需要调整动量系数 β,通常为0.9,但最优值可能因问题而异。

  2. 可能 overshooting:在极陡的梯度面前,过大的动量可能导致更新过头,在最优值附近震荡甚至发散。

适用场景

  1. 高维非凸优化:如深度学习,特别是网络层数较深时。

  2. 梯度噪声较大或方向不一致:当数据存在噪声或Mini-batch较小时,动量能起到平滑作用。

  3. 追求更快的训练速度:在资源有限的情况下,希望用更少的迭代次数达到可接受的损失。

完整代码示例:在回归问题中对比SGD与动量法

下面我们用一个简单的线性回归问题,来可视化对比普通SGD和带动量的SGD的优化轨迹。

python 复制代码
import numpy as np
import matplotlib.pyplot as plt

# 1. 生成模拟数据
np.random.seed(42)
# 真实参数:w_true = 2.5, b_true = 1.0
X = 2 * np.random.rand(100, 1)
y = 2.5 * X + 1.0 + np.random.randn(100, 1) * 0.5  # 添加噪声

# 2. 定义损失函数(均方误差)和梯度
def compute_gradients(X, y, w, b):
    m = len(X)
    y_pred = X * w + b
    dw = (-2/m) * np.sum(X * (y - y_pred))
    db = (-2/m) * np.sum(y - y_pred)
    return dw, db

# 3. 定义优化器
def sgd_optimizer(w, b, dw, db, lr):
    w_new = w - lr * dw
    b_new = b - lr * db
    return w_new, b_new

def momentum_optimizer(w, b, dw, db, lr, beta, v_w, v_b):
    v_w = beta * v_w + lr * dw
    v_b = beta * v_b + lr * db
    w_new = w - v_w
    b_new = b - v_b
    return w_new, b_new, v_w, v_b

# 4. 训练参数设置
lr = 0.1
beta = 0.9
n_iterations = 50

# 初始化参数(两者起点相同)
w_sgd, b_sgd = np.random.randn(2) * 5  # 随机初始化
w_mom, b_mom = w_sgd, b_sgd
v_w, v_b = 0, 0  # 动量速度初始化为0

# 用于记录轨迹
path_sgd = [(w_sgd, b_sgd)]
path_mom = [(w_mom, b_mom)]

# 5. 执行训练
for i in range(n_iterations):
    # 计算梯度(使用全量数据简化演示)
    dw, db = compute_gradients(X, y, w_sgd, b_sgd)
    # SGD 更新
    w_sgd, b_sgd = sgd_optimizer(w_sgd, b_sgd, dw, db, lr)
    path_sgd.append((w_sgd, b_sgd))

    # 动量法更新 (需要重新计算当前参数的梯度)
    dw_m, db_m = compute_gradients(X, y, w_mom, b_mom)
    w_mom, b_mom, v_w, v_b = momentum_optimizer(w_mom, b_mom, dw_m, db_m, lr, beta, v_w, v_b)
    path_mom.append((w_mom, b_mom))

# 转换为数组方便绘图
path_sgd = np.array(path_sgd)
path_mom = np.array(path_mom)

# 6. 可视化优化轨迹
plt.figure(figsize=(12, 5))

# 子图1:参数空间轨迹
plt.subplot(1, 2, 1)
# 绘制损失函数等高线(近似)
W_grid, B_grid = np.meshgrid(np.linspace(-5, 5, 100), np.linspace(-5, 5, 100))
Loss = np.zeros_like(W_grid)
for i in range(W_grid.shape[0]):
    for j in range(W_grid.shape[1]):
        Loss[i,j] = np.mean((y - X * W_grid[i,j] - B_grid[i,j])**2)
plt.contour(W_grid, B_grid, Loss, levels=30, alpha=0.5)
plt.scatter(2.5, 1.0, c='red', s=100, marker='*', label='True Optimum (w=2.5, b=1.0)')
plt.plot(path_sgd[:,0], path_sgd[:,1], 'o-', label='SGD Path', linewidth=2, markersize=4)
plt.plot(path_mom[:,0], path_mom[:,1], 's-', label='Momentum Path', linewidth=2, markersize=4)
plt.xlabel('Weight (w)')
plt.ylabel('Bias (b)')
plt.title('Optimization Path in Parameter Space')
plt.legend()
plt.grid(True, alpha=0.3)

# 子图2:损失下降曲线
plt.subplot(1, 2, 2)
loss_sgd = [np.mean((y - X * w - b)**2) for w, b in path_sgd]
loss_mom = [np.mean((y - X * w - b)**2) for w, b in path_mom]
plt.plot(range(len(loss_sgd)), loss_sgd, label='SGD Loss')
plt.plot(range(len(loss_mom)), loss_mom, label='Momentum Loss')
plt.xlabel('Iteration')
plt.ylabel('Mean Squared Error Loss')
plt.title('Loss Convergence Curve')
plt.legend()
plt.grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

代码说明与结果解读:

  1. 左图(参数空间轨迹)

    • 背景等高线代表损失函数值,中心红五星为全局最优点。

    • SGD(圆点线) 的更新路径曲折,呈"锯齿状"缓慢靠近最优点。

    • 动量法(方块线) 的路径明显更加平滑、直接,更快地指向最优点,体现了动量在一致梯度方向上的加速效果。

  2. 右图(损失下降曲线)

    • 动量法(橙色)的损失值下降速度整体快于普通SGD(蓝色),尤其是在初期,收敛更快。

通过这个对比实验,可以直观地看到动量法如何优化梯度下降的过程,使其更高效、更稳定

相关推荐
那个村的李富贵17 小时前
光影魔术师:CANN加速实时图像风格迁移,让每张照片秒变大师画作
人工智能·aigc·cann
腾讯云开发者18 小时前
“痛点”到“通点”!一份让 AI 真正落地产生真金白银的实战指南
人工智能
CareyWYR18 小时前
每周AI论文速递(260202-260206)
人工智能
hopsky19 小时前
大模型生成PPT的技术原理
人工智能
禁默20 小时前
打通 AI 与信号处理的“任督二脉”:Ascend SIP Boost 加速库深度实战
人工智能·信号处理·cann
心疼你的一切20 小时前
昇腾CANN实战落地:从智慧城市到AIGC,解锁五大行业AI应用的算力密码
数据仓库·人工智能·深度学习·aigc·智慧城市·cann
AI绘画哇哒哒20 小时前
【干货收藏】深度解析AI Agent框架:设计原理+主流选型+项目实操,一站式学习指南
人工智能·学习·ai·程序员·大模型·产品经理·转行
数据分析能量站20 小时前
Clawdbot(现名Moltbot)-现状分析
人工智能
那个村的李富贵20 小时前
CANN加速下的AIGC“即时翻译”:AI语音克隆与实时变声实战
人工智能·算法·aigc·cann
二十雨辰20 小时前
[python]-AI大模型
开发语言·人工智能·python