Pytorch常用的函数(八)常见优化器SGD,Adagrad,RMSprop,Adam,AdamW总结

2024-04-24 11:52

本文主要是介绍Pytorch常用的函数(八)常见优化器SGD,Adagrad,RMSprop,Adam,AdamW总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Pytorch常用的函数(八)常见优化器SGD,Adagrad,RMSprop,Adam,AdamW总结

  • 在深度学习中,优化器的目标是通过调整模型的参数,最小化(或最大化)一个损失函数。

  • 优化器使用梯度下降等迭代方法来更新模型的参数,以使损失函数达到最优或接近最优。

在这里插入图片描述

  • 如下图,优化算法可分为一阶算法和二阶算法,常用的是一阶算法,今天主要介绍下一阶优化相关的优化器。

在这里插入图片描述

1 SGD优化算法

1.1 梯度下降法概述

1.1.1 梯度下降法概念

        梯度下降法(Gradient Descent)是一种常用的优化算法,用于最小化(或最大化)一个函数。在机器学习和深度学习中,梯度下降法被广泛应用于训练模型,通过调整模型的参数来最小化损失函数。

θ = θ − α ∗ Δ J ( θ ) θ = θ - α * \Delta J(θ) θ=θαΔJ(θ)

其中:

  • θ表示要更新的参数向量或矩阵。
  • α是学习率(learning rate),控制参数更新的步长。
  • ∇J(θ)是损失函数J关于参数θ的梯度向量。

1.2 梯度下降法三个变种

1.2.1 批量梯度下降BGD

        BGD是批量梯度下降(Batch Gradient Descent)的缩写,是一种基本的梯度下降优化算法。在批量梯度下降中,每次参数更新时使用整个训练数据集的梯度.

计算公式

在这里插入图片描述

图示

在这里插入图片描述

特点

  • 全局最优解:由于BGD使用整个训练数据集的梯度,它有潜力收敛到全局最优解(如果存在)。
  • 低效性:BGD的计算开销较大,因为在每次参数更新步骤中需要计算整个数据集的梯度。对于大规模系统和大型数据集,这可能会导致训练时间较长。
  • 稳定性:由于使用整个数据集的梯度,BGD的参数更新相对稳定,不容易受到单个样本或噪声的影响。
  • 需要注意的是,尽管BGD可能收敛到全局最优解,但它也可能陷入糟糕的局部最小值中。
1.2.2 随机梯度下降SGD

        随机梯度下降(Stochastic Gradient Descent,SGD)是一种基于随机采样的梯度下降优化算法。与批量梯度下降(BGD)每次都使用整个训练数据集的梯度相比,SGD每次仅使用单个样本或一小批样本的梯度进行参数更新。

计算公式

在这里插入图片描述

图示

在这里插入图片描述

特点

  • 更快的更新速度:由于每次更新只使用一个样本或一小批样本的梯度,SGD的参数更新速度比BGD更快。这使得SGD在大规模数据集上具有优势,特别是在迭代次数较少的情况下。
  • 可能陷入局部最小值:由于使用随机采样的梯度,SGD的参数更新在每次迭代中都具有一定的随机性。这可能导致SGD在搜索空间中陷入局部最小值,而无法达到全局最优解。
  • 然而,这种随机性也有助于SGD跳出局部最小值并继续搜索更好的解。
  • 由于其随机性采样和快速更新的特点,SGD能够在多个局部最小值之间进行搜索,有助于找到更好的局部最小值或接近全局最优解。
1.2.3 小批量梯度下降Mini-BGD

        Mini-Batch Gradient Descent(小批量梯度下降)是介于批量梯度下降(BGD)和随机梯度下降(SGD)之间的一种梯度下降优化算法。它在每次参数更新时使用一小批次的样本来计算梯度和更新参数.

计算公式

在这里插入图片描述

图示

在这里插入图片描述

特点

  • 折中的更新速度:相比于BGD,Mini-Batch Gradient Descent的参数更新速度更快,因为每次使用的样本数量较少。这使得Mini-Batch Gradient Descent在大规模数据集上具有一定的优势。与SGD相比,Mini-Batch Gradient Descent的参数更新速度较慢,但相对更稳定。
  • 梯度估计的抖动减少:与SGD相比,Mini-Batch Gradient Descent的梯度估计具有更小的抖动。由于使用的是一小批次的样本,梯度计算的结果更加平滑,减少了随机性带来的波动。
  • 内存效率:相对于BGD需要存储整个训练数据集的梯度以及SGD需要存储单个样本的梯度,Mini-Batch Gradient Descent在内存使用方面更有效率。它只需存储每个小批量样本的梯度,使得在处理大型数据集时更加可行。
  • 可调节的更新步长:Mini-Batch Gradient Descent的学习率可以根据需要进行调整,以控制参数更新的步长。这使得算法能够更好地平衡快速收敛和避免震荡之间的权衡。

注意:下文SGD一般为小批量梯度下降Mini-BGD

1.2 带动量的SGD(常用)

        虽然随机梯度下降仍然是非常受欢迎的优化方法,但其学习过程有时会很慢。动量方法 (Polyak, 1964) 旨在加速学习, 特别是处理高曲率、小但一致的梯度, 或是带噪声的梯度。动量算法积累了之前梯度指数级衰减的移动平均, 并且继续沿该方向移动。

1.2.1 算法过程

在这里插入图片描述

实践中, α 的一般取值为0.5,0.9 和0.99。

1.2.2 算法图示

在这里插入图片描述

动态效果展示

在这里插入图片描述

1.2.3 特点

  1. 动量的积累:带动量的随机梯度下降利用一个动量变量来积累梯度的历史信息。在每次参数更新时,动量项会考虑前一次更新的方向和幅度。
  2. 加速参数更新:由于动量的引入,带动量的随机梯度下降可以加速参数更新的速度。当梯度在相同方向上持续增加时,动量项会逐渐增大,从而加速参数更新。这有助于在梯度方向上形成更大的动量,更快地接近最优解。
  3. 减少参数更新方向的震荡:动量项可以减少参数更新方向的震荡,特别是在存在噪声或不稳定梯度的情况下。通过考虑历史梯度的平均方向,动量可以平滑参数更新的路径,减少震荡现象。

1.2.4 作用

  • 加速收敛:带动量的随机梯度下降可以加速模型的收敛速度。通过积累历史梯度信息,它能够更快地朝着梯度下降的方向移动,从而加速参数的更新过程。
  • 跳出局部最小值:由于动量的引入,带动量的随机梯度下降能够在搜索空间中跳出局部最小值并继续寻找更好的解。通过考虑历史梯度的方向和幅度,动量项可以帮助算法在平坦区域上获得更大的动量,并有助于跳过局部极小点。
  • 平滑参数更新路径:动量项可以减少参数更新方向的震荡。通过考虑历史梯度的平均方向,带动量的随机梯度下降可以平滑参数更新的路径,使得参数更新更加稳定。

1.3 NAG

1.3.1 算法原理

        等价于 SGD with Nesterov Momentum,利用当前位置处先前的梯度值先做一个参数更新,然后在更新后的位置再求梯度,将此部分梯度然后跟之前累积下来的梯度值矢量相加,简单的说就是先根据之前累积的梯度方向模拟下一步参数更新后的值,然后将模拟后的位置处梯度替换动量方法中的当前位置梯度。

        现在有一个预测后一步位置梯度的步骤,所以当在山谷附近时,预测到会跨过山谷时(跨过山谷后梯度方向会发生变化),该项梯度就会对之前梯度有个修正,相当于阻止了其跨度太大。

1.3.2 算法原理图

SGD with Momentum

在这里插入图片描述

NAG

在这里插入图片描述

1.3.3 算法详述

在这里插入图片描述

        动量的方法,我们发现参数更新是基于两部分组成,一部分为当前位置的梯度,另一部分为前面累计下来的梯度值,参数更新方向就是将两者矢量相加的方向,但是我们会发现一个问题,当刚好下降到山谷附近时,如果这个时候继续以这样的方式更新参数,我们会有一个较大的幅度越过山谷,即:模型遇到山谷不会自动减弱更新的幅度。

  • 论文:On the importance of initialization and momentum in deep learning

1.4 Pytorch 中SGD的实现

torch.optim.SGD(params,          # 优化器要优化的参数lr=0.001,        # 初始学习率momentum=0,      # 动量,一般设置为0.9dampening=0, weight_decay=0,  # 权值衰减系数,也就是L2正则项的系数nesterov=False,  # 是否启用NAG*, maximize=False,  # 默认是最小化lossforeach=None, differentiable=False
)

在这里插入图片描述

  • SGD开启动量梯度时,额外的内存/显存消耗只有momentum_buffer,是1倍的模型参数量;
  • 不开启动量梯度则没有额外内存/显存消耗。

2 AdaGrad优化算法

2.1 自适应学习率

  • Adagrad(Adaptive Gradient)的核心思想是,深度模型带来的稀疏性,导致模型中一些参数可能频繁获得较大梯度,另一些参数偶尔获得较大梯度,若采用统一学习率导致后者的更新会非常缓慢。基于此,可以调节模型中不同参数的学习率,而不是用统一的学习率。
  • 如果一个参数的历史累计梯度更新量大,则降低该参数的学习率;如果一个参数的历史累计梯度更新量小,则增大该参数的学习率。

2.2 AdaGrad 算法

在这里插入图片描述

  • 因为梯度有正有负,所以对梯度的平方进行累计,然后再开根号。
  • 为了避免分母为0,加了一项随机扰动 δ \delta δ
  • 可以看成对每个参数分别调节学习率,也可以看成调节每个参数的梯度。

2.3 AdaGrad优缺点

优点:

  • 前期较小的时候, 分母较小,能够放大梯度;
  • 后期较大的时候, 分母较大,能够约束梯度;
  • 无需手动调整梯度;
  • 这一方法在稀疏数据场景下表现非常好。

缺点:

  • 仍依赖于人工设置一个全局学习率,一般采用默认值0.01;
  • 中后期,分母上梯度平方的累加将会越来越大,分母会不断积累使 Δ θ t Δθ_t Δθt趋近于0,学习率就会收缩并最终会变得非常小使得训练提前结束

2.6 pytorch 中AdaGrad的实现

torch.optim.Adagrad(params, lr=0.01,                     # 学习率lr_decay=0,                  # 学习率衰减系数weight_decay=0,              # 权重衰减系数initial_accumulator_value=0, eps=1e-10,                   # 添加到分母以提高数值稳定性foreach=None, *, maximize=False,              # 默认最小化lossdifferentiable=False
)

在这里插入图片描述

  • Adagrad优化器实现中加入了学习率衰减机制、权重衰减机制;
  • 该算法需要给每一个待更新的模型参数设置一个累计统计量 s t a t e _ s u m t − 1 state\_sum_{t-1} state_sumt1 ,所以额外的内存/显存消耗是1倍的模型参数量。
  • 论文:Adaptive Subgradient Methods for Online Learning and Stochastic Optimization

3 RMSProp优化算法

3.1 概述

  • RMSProp(root mean square propagation)优化算法是Hinton提出的,也属于自适应梯度范畴。
  • 指数移动平均EMA(Exponential Moving Average),是一种给予近期数据更高权重的平均方法。
  • 区别于Adagrad之处是它采用了EMA方式来统计每个参数的最近的累计梯度量,所以多次迭代后不会导致模型参数更新缓慢
  • RMSProp适合处理非平稳目标 - 对于RNN效果很好。
  • 不过,RMSProp依然依赖于全局学习率。

3.2 算法流程

  • RMSProp算法是AdaGrad算法的改进,修改AdaGrad以在非凸条件下效果更好,解决了AdaGrad所面临的问题。
  • RMSProp主要思想:使用指数加权移动平均的方法计算累积梯度,以丢弃遥远的梯度历史信息。
  • 不累积全部历史梯度,而只关注过去一段时间窗口的下降梯度。

RMSProp 的标准形式

在这里插入图片描述

带Nesterov 动量的形式

在这里插入图片描述

  • Hinton 建议设定 γ 为 0.9, 学习率 η 为 0.001。

3.3 pytorch 实现

torch.optim.RMSprop(params, lr=0.01,        # 学习率alpha=0.99,     # 平滑常数eps=1e-08,      # 添加到分母以提高数值稳定性weight_decay=0, # 权重衰减momentum=0,     # 动量因子centered=False, # 如果为True,则计算中心化的RMSProp,梯度将通过其方差的估计进行归一化foreach=None,maximize=False, differentiable=False
)

在这里插入图片描述

  • RMSProp优化器实现中还加入了权重衰减机制、动量梯度机制;
  • centered参数,其主要是通过估计方差来对梯度进行归一化,主要操作就是让二阶动量去减去平均梯度的平方,这样会使得结果更加平稳;
  • 该算法需要给每一个待更新的模型参数设置一个累计梯度统计量 v t v_t vt 、一个自适应梯度的动量 b t b_t bt ,所以额外的内存/显存消耗是2倍的模型参数量。

4 Adadelta

4.1 概述及算法流程

  • 从时间线上来看,AdaGrad算法是由John Duchi等人在2011年提出的。RMSProp算法是由Hinton在2012年提出的,Adadelta算法由Matthew D. Zeiler同样在2012年提出。

  • 我们已经知道,RMSProp是在AdaGrad的基础上引入了衰减量,从而解决不断地累加二阶动量导致最终学习率会接近于零以及训练提前终止的问题。

  • RMSProp优化器虽然可以对不同的权重参数自适应的改变学习率,但仍依赖于全局学习率。AdaDelta优化器对RMSProp算法进一步优化:AdaDelta算法额外维护一个状态变量 Δ x t Δx_t Δxt,并使用 R M S [ Δ x ] t RMS[Δx]_t RMS[Δx]t代替 RMSProp 中的学习率参数,使AdaDelta优化器不需要指定学习率这个超参数

    在这里插入图片描述

  • Adadelta在训练初中期,加速效果不错,很快;但是训练后期,反复在局部最小值附近抖动

算法流程如下:

在这里插入图片描述

4.2 pytorch 实现

  • 可以看到与RMSProp的区别就是加入了 u t u_t ut

在这里插入图片描述

  • 论文:ADADELTA: An Adaptive Learning Rate Method

4.3 不同优化算法效果对比

在这里插入图片描述

  • 从上图展现了不同算法在鞍点处的表现。
  • 这里,SGD、SGD-M、NAG 都受到了鞍点的严重影响,尽管后两者最终还是逃离了鞍点;
  • 而 Adagrad、RMSprop、Adadelta 都很快找到了正确的方向。

在这里插入图片描述

  • 从上图中可以看到不同算法在损失面等高线图中的学习过程,它们均同同一点出发,但沿着不同路径达到最小值点。
  • 其中 Adagrad、Adadelta、RMSprop 从最开始就找到了正确的方向并快速收敛;
  • SGD 找到了正确方向但收敛速度很慢;
  • SGD-M 和 NAG 最初都偏离了航道,但也能最终纠正到正确方向,SGD-M 偏离的惯性比 NAG 更大。

5 Adam 优化器(常用)

5.1 概述及算法实现流程

  • Adam是前述方法的集大成者。SGD-M在SGD基础上增加了一阶动量,AdaGrad和AdaDelta在SGD基础上增加了二阶动量。把一阶动量和二阶动量都用起来,就是Adam了。

  • Adam 算法即自适应矩估计(Adaptive Moment Estimation)方法。Adam算法的本质:其实就是Momentum+RMSProp的结合,然后再修正其偏差

  • Adam通常被认为对超参数的选择相当鲁棒,同时相比于AdaGrad,不用存储全局所有的梯度,适合处理大规模数据

  • 特点:

    • 结合了AdaGrad善于处理稀疏梯度和RMSProp善于处理非平稳目标的优点
    • 对内存需求较小
    • 为不同的参数计算不同的自适应学习率
    • 也适用于大多非凸优化
    • 适用于大数据集和高维空间
  • 论文:ADAM: A METHOD FOR STOCHASTIC(随机) OPTIMIZATION
    在这里插入图片描述

5.2 pytorch 实现

torch.optim.Adam(params, lr=0.001,              # 学习率betas=(0.9, 0.999),    # 平滑常数eps=1e-08,             # 添加到分母以提高数值稳定性weight_decay=0,        # 权重衰减,注意:这里加到梯度上amsgrad=False,         # 如果amsgrad为True,保留历史最大的,记为v_{max},每次计算都是用最大的v_{max},否则是用当前v_t*, foreach=None, maximize=False,capturable=False, differentiable=False, fused=None)

在这里插入图片描述

5.3 效果展示

在这里插入图片描述

6 AdamW(常用)

6.1 算法原理

  • 我们已经知道Adam是集成一阶动量和二阶动量的优化器。AdamW是在Adam的基础上加入了weight decay正则化,但是Adam中已经有正则化,那么两者有什么区别呢?

  • 其实AdamW和Adam唯一的区别,就是weight decay的加入方式

    • 在Adam当中,weight decay是直接加入到梯度当中(如下图紫色部分);
    • AdamW直接在权重上进行衰减(如下图绿色)。
  • 人们发现,理论上更优的Adam算法,有时表现并不如SGD momentum好,尤其是在模型泛化性上。

    • 我们知道,L2范数(也叫权重衰减,weight decay)有助于提高模型的泛化性能。

    • 但是AdamW的作者证明,Adam算法弱化了L2范数的作用,所以导致了用Adam算法训练出来的模型泛化能力较弱。

    • 具体来说,在Adam中,权重衰减的梯度是直接加在 g t g_t gt 上的,这就导致权重衰减的梯度也会随着 g t g_t gt 去除以分母。当梯度的平方和累积过大时,权重衰减的作用就会被大大削弱。

在这里插入图片描述

在这里插入图片描述

  • 论文:DECOUPLED(解耦) WEIGHT DECAY REGULARIZATION

6.2 pytorch实现

torch.optim.AdamW(params, lr=0.001,betas=(0.9, 0.999), eps=1e-08, weight_decay=0.01, # 这里直接在权重上进行衰减amsgrad=False, *, maximize=False, foreach=None, capturable=False,differentiable=False, fused=None
)

在这里插入图片描述

6.3 Optimizer 收敛趋势对比图

在这里插入图片描述

参考:

  • Optimization Algorithms
  • github optimize demo
  • 论文:An overview of gradient descent optimization algorithms
  • Machine Learning Optimization Methods : Mechanics, Pros, And Cons

这篇关于Pytorch常用的函数(八)常见优化器SGD,Adagrad,RMSprop,Adam,AdamW总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/931680

相关文章

关于C++中的虚拟继承的一些总结(虚拟继承,覆盖,派生,隐藏)

1.为什么要引入虚拟继承 虚拟继承是多重继承中特有的概念。虚拟基类是为解决多重继承而出现的。如:类D继承自类B1、B2,而类B1、B2都继承自类A,因此在类D中两次出现类A中的变量和函数。为了节省内存空间,可以将B1、B2对A的继承定义为虚拟继承,而A就成了虚拟基类。实现的代码如下: class A class B1:public virtual A; class B2:pu

嵌入式软件常见的笔试题(c)

找工作的事情告一段落,现在把一些公司常见的笔试题型整理一下,本人主要是找嵌入式软件方面的工作,笔试的也主要是C语言、数据结构,大体上都比较基础,但是得早作准备,才会占得先机。   1:整型数求反 2:字符串求反,字符串加密,越界问题 3:字符串逆序,两端对调;字符串逆序,指针法 4:递归求n! 5:不用库函数,比较两个字符串的大小 6:求0-3000中含有9和2的全部数之和 7

uniapp接入微信小程序原生代码配置方案(优化版)

uniapp项目需要把微信小程序原生语法的功能代码嵌套过来,无需把原生代码转换为uniapp,可以配置拷贝的方式集成过来 1、拷贝代码包到src目录 2、vue.config.js中配置原生代码包直接拷贝到编译目录中 3、pages.json中配置分包目录,原生入口组件的路径 4、manifest.json中配置分包,使用原生组件 5、需要把原生代码包里的页面修改成组件的方

十五.各设计模式总结与对比

1.各设计模式总结与对比 1.1.课程目标 1、 简要分析GoF 23种设计模式和设计原则,做整体认知。 2、 剖析Spirng的编程思想,启发思维,为之后深入学习Spring做铺垫。 3、 了解各设计模式之间的关联,解决设计模式混淆的问题。 1.2.内容定位 1、 掌握设计模式的"道" ,而不只是"术" 2、 道可道非常道,滴水石穿非一日之功,做好长期修炼的准备。 3、 不要为了

【操作系统】信号Signal超详解|捕捉函数

🔥博客主页: 我要成为C++领域大神🎥系列专栏:【C++核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞👍收藏⭐评论✍️ 本博客致力于知识分享,与更多的人进行学习交流 ​ 如何触发信号 信号是Linux下的经典技术,一般操作系统利用信号杀死违规进程,典型进程干预手段,信号除了杀死进程外也可以挂起进程 kill -l 查看系统支持的信号

java中查看函数运行时间和cpu运行时间

android开发调查性能问题中有一个现象,函数的运行时间远低于cpu执行时间,因为函数运行期间线程可能包含等待操作。native层可以查看实际的cpu执行时间和函数执行时间。在java中如何实现? 借助AI得到了答案 import java.lang.management.ManagementFactory;import java.lang.management.Threa

React+TS前台项目实战(十七)-- 全局常用组件Dropdown封装

文章目录 前言Dropdown组件1. 功能分析2. 代码+详细注释3. 使用方式4. 效果展示 总结 前言 今天这篇主要讲全局Dropdown组件封装,可根据UI设计师要求自定义修改。 Dropdown组件 1. 功能分析 (1)通过position属性,可以控制下拉选项的位置 (2)通过传入width属性, 可以自定义下拉选项的宽度 (3)通过传入classN

人工智能机器学习算法总结神经网络算法(前向及反向传播)

1.定义,意义和优缺点 定义: 神经网络算法是一种模仿人类大脑神经元之间连接方式的机器学习算法。通过多层神经元的组合和激活函数的非线性转换,神经网络能够学习数据的特征和模式,实现对复杂数据的建模和预测。(我们可以借助人类的神经元模型来更好的帮助我们理解该算法的本质,不过这里需要说明的是,虽然名字是神经网络,并且结构等等也是借鉴了神经网络,但其原型以及算法本质上还和生物层面的神经网络运行原理存在

Java注解详细总结

什么是注解?         Java注解是代码中的特殊标记,比如@Override、@Test等,作用是:让其他程序根据注解信息决定怎么执行该程序。         注解不光可以用在方法上,还可以用在类上、变量上、构造器上等位置。 自定义注解  现在我们自定义一个MyTest注解 public @interface MyTest{String aaa();boolean bbb()

SQL Server中,isnull()函数以及null的用法

SQL Serve中的isnull()函数:          isnull(value1,value2)         1、value1与value2的数据类型必须一致。         2、如果value1的值不为null,结果返回value1。         3、如果value1为null,结果返回vaule2的值。vaule2是你设定的值。        如