首页 > 编程语言 >【深度学习】03-神经网络 3-3 梯度下降的优化方法-动量算法Momentum

【深度学习】03-神经网络 3-3 梯度下降的优化方法-动量算法Momentum

时间:2024-09-24 18:22:21浏览次数:3  
标签:03 optimizer 梯度 神经网络 更新 算法 动量 grad Momentum

常规的梯度下降算法中,会遇到平缓区域,碰到鞍点,碰到局部最小值(截止当前无解),因此为了解决这个问题,我们需要优化传统的梯度下降算法。

动量算法(Momentum) 是梯度下降算法的一种优化方法,旨在解决传统梯度下降容易陷入局部最小值或在鞍点附近震荡的问题。动量算法通过引入一个“动量”的概念,能够加速梯度下降的收敛,并帮助模型更快地找到全局最优解。

1. 梯度下降的基本问题

在常规的梯度下降中,模型通过计算损失函数的梯度,并根据这个梯度的方向更新参数。公式如下:

[ \theta = \theta - \eta \cdot \nabla_\theta J(\theta) ]

其中:

  • ( \theta ) 是模型的参数。

  • ( \eta ) 是学习率。

  • ( \nabla_\theta J(\theta) ) 是参数 ( \theta )  方向的梯度。

在简单的梯度下降中,如果损失函数的形状复杂,比如有很多曲率不同的区域,模型在某些方向上的更新会过快,导致在目标最小值附近震荡,或者更新速度过慢,导致收敛时间变长。

2. 动量算法(Momentum)概述

动量算法的关键思想是:不仅仅考虑当前梯度对参数更新的影响,还考虑之前梯度的影响。通过引入“动量”这一概念,算法能够“加速”向最优解的方向前进。

动量算法通过以下公式更新参数:

[ v_t = \gamma v{t-1} + \eta \nabla\theta J(\theta) ]

[ \theta = \theta - v_t ]

其中:

  • ( v_t )是第 ( t )步时的速度(或动量),表示之前梯度的累积方向。

  • ( \gamma )是动量项(通常取值为 0.9 左右),用于控制之前梯度对当前更新的影响,类似于惯性。

  • ( \eta ) 是学习率,用于控制每一步更新的幅度。

  • ( \nabla_\theta J(\theta) )是当前梯度。

3. 动量的作用

  • 平滑更新方向:通过将前几次更新方向上的“动量”引入当前更新,动量算法能够平滑梯度更新的方向,避免在陡峭区域产生剧烈的梯度更新,从而减少震荡。

  • 加速收敛:在平坦的区域或相对低曲率的地方,动量会使得更新步伐逐渐加快,加速收敛到最优解。

  • 帮助逃离局部最小值:由于动量带来的累积效果,模型可以更容易地摆脱局部最小值的困扰,帮助找到更好的全局最优解。

代码:

import torch

def momentum_optimization_example():
    # Step 1: 初始化一个可训练的张量 w,设置 requires_grad=True 表示 w 的梯度需要计算
    w = torch.tensor([1.0], requires_grad=True, dtype=torch.float32)  # 权重初始化为 1.0,类型为 float32

    # 定义一个简单的目标函数(损失函数): y = (w^2) / 2
    y = ((w ** 2) / 2.0).sum()

    # Step 2: 使用 SGD 优化器并带有动量(momentum=0.9)
    # - 学习率 lr = 0.01
    # - 动量系数 beta = 0.9
    optimizer = torch.optim.SGD([w], lr=0.01, momentum=0.9)

    # 梯度清零(非常重要,防止梯度累加)
    optimizer.zero_grad()

    # 计算目标函数 y 对 w 的梯度
    y.backward()  # 反向传播计算梯度

    # 使用带动量的 SGD 进行参数更新
    optimizer.step()  # 使用 optimizer.step() 更新参数 w
    
    # 打印更新后的梯度和 w 值
    print('Step 1: w 的梯度: %f, 更新后的 w 值: %f' % (w.grad.numpy(), w.detach().numpy())) 

    # Step 3: 继续第二轮的梯度更新
    # 重新计算损失函数,基于更新后的 w 值
    y = ((w ** 2) / 2.0).sum()

    # 在第二轮梯度计算前需要将之前的梯度清零
    optimizer.zero_grad()

    # 计算目标函数对新 w 的梯度
    y.backward()

    # 再次更新参数 w
    optimizer.step()

    # 打印第二次更新后的梯度和 w 值
    print('Step 2: w 的梯度: %f, 更新后的 w 值: %f' % (w.grad.numpy(), w.detach().numpy())) 

# 调用函数进行动量算法优化示例
momentum_optimization_example()

代码讲解:

        1. 初始化权重 w

w = torch.tensor([1.0], requires_grad=True, dtype=torch.float32)
  1. w 是一个可训练的权重,初始化为 1.0。requires_grad=True 表示需要计算其梯度,dtype=torch.float32 指定了数据类型。

  2. 我们将优化这个 w,使其能够最小化损失函数  ( y = \frac{w^2}{2} )

  3. 2.定义损失函数 y

    • y = ((w ** 2) / 2.0).sum()

      损失函数 ( y = \frac{w^2}{2} ) 是我们要最小化的目标。在这个示例中,它是一个非常简单的二次函数。
    • 通过最小化这个损失函数,我们可以观察到参数更新过程中的动量算法。

  4. 3.优化器 optimizer

    optimizer = torch.optim.SGD([w], lr=0.01, momentum=0.9)
    • 使用了随机梯度下降(SGD)作为优化器,并设置了动量项 momentum=0.9。动量可以加速梯度下降过程,尤其是在复杂或有噪声的损失函数中。

    • 学习率 lr=0.01 控制每次更新的步长,动量系数 momentum=0.9 决定了累积历史梯度的影响。

  5. 4.梯度清零

    optimizer.zero_grad()
    • 在每次计算新的梯度之前,我们需要将前一步的梯度清零。否则,PyTorch 会将梯度累加。

  6. 5. 反向传播计算梯度

    y.backward()
    • backward() 函数会根据损失函数计算出参数 w 的梯度,即 y w 的偏导数。

  7. 6. 更新参数 w

    optimizer.step()
    • 调用 optimizer.step() 后,优化器会根据计算出的梯度和动量,更新权重 w 的值。

  8. 7. 打印梯度和更新后的参数

    print('Step 1: w 的梯度: %f, 更新后的 w 值: %f' % (w.grad.numpy(), w.detach().numpy()))
    • w.grad 表示当前权重 w 的梯度值。

    • w.detach() 返回的是更新后的权重值,并且从计算图中分离出来,不会再继续跟踪梯度。

动量算法原理简要说明:

动量算法在梯度下降的过程中,通过累积过去的梯度来加速优化。具体原理如下:

  1. 动量可以理解为模拟物理系统中物体的惯性,它在梯度下降过程中累积了之前的更新方向,使得参数更新更加平滑、稳定。

  2. 公式

    • 在动量算法中,每次更新时会引入历史梯度的影响:

    • [ v_t = \beta v{t-1} + (1 - \beta) \nabla\theta J(\theta) ]

    • 其中 ( v_t ) 是当前的动量值,( \beta )是动量系数,

    • 通常接近 1(例如 0.9)。动量项 ( v_t )  可以看作是梯度的指数加权平均。

    • 接着,使用 ( v_t )来更新参数:[ \theta = \theta - v_t ]

在代码中,momentum=0.9 就是使用了动量项,帮助梯度在下降的过程中减少震荡,加速收敛。

4. 动量算法的更新过程详解

每次迭代时,动量算法通过计算两个关键公式:

  1. 速度更新公式[ v_t = \gamma v{t-1} + \eta \nabla\theta J(\theta) ]

    • 这一步表示计算当前的动量,它是前一次动量 ( v_{t-1} )和当前梯度的加权和。这样可以保证之前的更新方向对当前更新有影响。

  2. 参数更新公式[ \theta = \theta - v_t ]

    • 这一步表示用更新后的动量 ( v_t ) 来调整参数\theta,这样可以使得模型在朝向最优解的方向上有更稳定和加速的更新。

5. 动量算法的直观理解

可以把动量算法想象成一个球沿着曲面滚动的过程。传统的梯度下降类似于每一步都按照曲面的斜率(梯度)前进,而动量算法则模拟了一个带有惯性的球滚动的行为:

  • 惯性作用:球滚动时不仅受到当前坡度的影响,还会受到前面滚动过程中积累的速度(动量)的影响,这样就能够滚得更远、更快。

  • 减少震荡:在复杂的损失函数表面,动量算法可以避免在凹凸不平的表面上来回振荡,而是保持一个平滑的轨迹。

6. 动量算法的优势

  • 减少震荡:动量算法能够减少梯度下降过程中在局部最优或鞍点附近的震荡。

  • 加速收敛:通过累积梯度方向上的动量,动量算法能够加快模型的收敛速度,特别是在长梯度路径上。

  • 对局部最优点的鲁棒性:动量算法能够有效避免模型陷入局部最优点,增加找到全局最优解的机会。

7. 动量算法的常见变种

  • Nesterov 动量(Nesterov Accelerated Gradient, NAG):Nesterov 动量是在标准动量算法的基础上做了改进,NAG 会先看一步未来的梯度,然后再进行更新,以达到更好的预见性。它的更新公式如下:[ v_t = \gamma v{t-1} + \eta \nabla\theta J(\theta - \gamma v_{t-1}) ]这种方法往往比标准动量更快收敛,尤其是在复杂的损失函数中。

8. 动量算法的应用

动量算法被广泛应用于神经网络训练中,尤其是在深度学习任务中,它可以有效提升训练速度并且提高模型的性能。它可以和其他优化方法(如自适应优化算法 Adam)结合使用,进一步优化模型的学习效果。

总结

  • 动量算法 是一种改进的梯度下降方法,通过引入“动量”来减少震荡、加速收敛,并避免陷入局部最优解。

  • 通过结合当前和过去的梯度更新,动量算法能够有效改善传统梯度下降的缺陷,尤其在神经网络训练中表现优异。

  • Nesterov 动量 是动量算法的一种改进变种,能够进一步加速收敛,尤其在较为复杂的损失函数表面。

标签:03,optimizer,梯度,神经网络,更新,算法,动量,grad,Momentum
From: https://blog.csdn.net/weixin_41645791/article/details/142479168

相关文章

  • 日新月异 PyTorch - pytorch 基础: 通过卷积神经网络(Convolutional Neural Networks,
    源码https://github.com/webabcd/PytorchDemo作者webabcd日新月异PyTorch-pytorch基础:通过卷积神经网络(ConvolutionalNeuralNetworks,CNN)做图片分类-通过ResNet50做图片分类的学习(对cifar10数据集做训练和测试),保存训练后的模型,加载训练后的模型并评估指定的......
  • SpringBoot养老院管理系统 计算机专业毕业设计源码06036
    摘 要随着互联网趋势的到来,各行各业都在考虑利用互联网将自己推广出去,最好方式就是建立自己的互联网系统,并对其进行维护和管理。在现实运用中,应用软件的工作规则和开发步骤,采用Java技术建设养老院管理系统。本设计主要实现集人性化、高效率、便捷等优点于一身的养老院管理......
  • 多输入多输出 | Matlab实现SMA-BP黏菌算法优化BP神经网络多输入多输出预测
    多输入多输出|Matlab实现SMA-BP黏菌算法优化BP神经网络多输入多输出预测目录多输入多输出|Matlab实现SMA-BP黏菌算法优化BP神经网络多输入多输出预测预测效果基本介绍程序设计往期精彩参考资料预测效果基本介绍多输入多输出|Matlab实现SMA-BP黏菌算法优化BP神经网络多输入......
  • 多输入多输出 | Matlab实现FA-BP萤火虫算法优化BP神经网络多输入多输出预测
    多输入多输出|Matlab实现FA-BP萤火虫算法优化BP神经网络多输入多输出预测目录多输入多输出|Matlab实现FA-BP萤火虫算法优化BP神经网络多输入多输出预测预测效果基本介绍程序设计往期精彩参考资料预测效果基本介绍多输入多输出|Matlab实现FA-BP萤火虫算法优化BP神经网络多输......
  • Windows 2003系统的防护技巧,禁止IPC$空连接
    一、修改管理员帐号和新建“陷阱”帐号多年以来,微软一直在强调建议重命名Administrator账号并禁用Guest账号,提高计算机的安全性。WindowsServer 2003系统,Guest账号是默认禁用的,管理员账号默认是Administrator,修改用户名和定期修改密码,小林认为是非常必要的,入侵者暴力破解都......
  • MoNA:复用跨模态预训练模型,少样本模态的福音 | ICML'24
    跨模态转移旨在利用大型预训练模型来完成可能不属于预训练数据模态的任务。现有的研究在将经典微调扩展到跨模态场景方面取得了一定的成功,但仍然缺乏对模态差距对转移的影响的理解。在这项工作中,进行了一系列关于转移过程中源表示质量的实验,揭示了更大的模态差距与较少知识重用之......
  • 基于卷积神经网络的布料、布匹原料识别系统,resnet50,mobilenet模型【pytorch框架+pytho
       更多目标检测和图像分类识别项目可看我主页其他文章功能演示:基于卷积神经网络的布料、布匹原料识别系统,resnet50,mobilenet【pytorch框架,python,tkinter】_哔哩哔哩_bilibili(一)简介基于卷积神经网络的布料、布匹原料识别系统是在pytorch框架下实现的,这是一个完整的项目......
  • AdEMAMix: 一种创新的神经网络优化器
    这是9月发布的一篇论文,Pagliardini等人在其论文中提出了一种新的优化算法——AdEMAMix。这种算法旨在解决当前广泛使用的Adam及其变体(如AdamW)在利用长期梯度信息方面的局限性。研究者们通过巧妙地结合两个不同衰减率的指数移动平均(EMA),设计出了这种新的优化器,以更有效地利用历史梯......
  • 14.STM32F103C8T6+CUBEMX+循迹模块(定时器计数、测速)
        学习完b站keysking老师的视频后写了这篇笔记,主要是学习定时器外部时钟。    用的是TIM2(有ETR,TIM3和TIM4都没有)一、cubemx配置(没加无上限计数)1、开TIM2    选了外部时钟模式1,借助从模式ETR1;        下面改数值15是输入滤波器,因为抖动......
  • 备战软考03——体系结构,指令,流水线
    晚上9:391.体系结构分类文老师软考教育单指令流单数据流多指令流单数据流控制部分:各处理器以异主存模块:多个至少是不实际各级全面并行多处理机系约◆按处理机的数量进行分类:单处理系统(一个处理单元和其他设备集成)、并行处理系统(两个以上的处理机互联)分布式处理系统(物理上远距离且......