常用优化器(Adam SGD)算法
文章目录
- 概览
- SGD (Stochastic gradient descent)
- Momentum
- NAG(Nesterov accelerated gradient)
- AdaGrad
- RMSPro Adadelta
- Adam
概览
梯度下降算法
关于梯度下降算法的直观理解,我们以一个人下山为例。比如刚开始的初始位置是在红色的山顶位置,那么现在的问题是该如何达到蓝色的山底呢?按照梯度下降算法的思想,它将按如下操作达到最低点:
- 明确自己现在所处的位置
- 找到相对于该位置而言下降最快的方向
- 沿着第二步找到的方向走一小步,到达一个新的位置,此时的位置比原来低
- 回到第一步
- 终止于最低点
按照以上5步,最终达到最低点,这就是梯度下降的完整流程。当然你可能会说,上图不是有不同的路径吗?是的,因为上图并不是标准的凸函数,往往不能找到最小值,只能找到局部极小值。所以你可以用不同的初始位置进行梯度下降,来寻找更小的极小值点,因为网络的目标函数往往不满足 严格的凸函数,所以可能从不同的初始值出发可能达到不同的局部最小值。
pytorch 提供的优化器接口
from .adadelta import Adadelta # noqa: F401
from .adagrad import Adagrad # noqa: F401
from .adam import Adam # noqa: F401
from .adamw import AdamW # noqa: F401
from .sparse_adam import SparseAdam # noqa: F401
from .adamax import Adamax # noqa: F401
from .asgd import ASGD # noqa: F401
from .sgd import SGD # noqa: F401
from .rprop import Rprop # noqa: F401
from .rmsprop import RMSprop # noqa: F401
from .lbfgs import LBFGS # noqa: F401
SGD (Stochastic gradient descent)
θ=θ−∇θJ(θ)\theta = \theta - \nabla_\theta J(\theta)θ=θ−∇θJ(θ)
批量梯度下降
针对整个数据集进行梯度的计算,可以求得全局最优解,但是当数据集比较大时,计算开销大,计算速度慢随机梯度下降
每次只通过随机选取的数据对(xi,yi)(x^i,y^i)(xi,yi)来求梯度,计算速度快,但是由于每次只选取一个样本对进行更新,很可能导致 损失函数震荡的现象,不易收敛。小批量梯度下降
每次选择一个批量(btach)样本进行更新,折中方案 1. 减少了参数更新的变化,这可以带来更加稳定的收敛。2:可以充分利用矩阵优化,最终计算更加高效。
Momentum
通过使用动量,减缓目标函数的震荡,加快收敛速度。
pytorch实现
# dampening一般为0
for p in group['params']:if p.grad is None:continued_p = p.grad.dataif weight_decay != 0:d_p.add_(weight_decay, p.data)if momentum != 0:param_state = self.state[p]if 'momentum_buffer' not in param_state:buf = param_state['momentum_buffer'] = torch.clone(d_p).detach()else:buf = param_state['momentum_buffer']buf.mul_(momentum).add_(1 - dampening, d_p)if nesterov: # NAGd_p = d_p.add(momentum, buf)else:d_p = bufp.data.add_(-group['lr'], d_p)
Vt=Vt−1+∇θJ(θ)V_t = V_{t-1} + \nabla_\theta J(\theta)Vt=Vt−1+∇θJ(θ)
θ=θ−Vt\theta = \theta-V_tθ=θ−Vt
NAG(Nesterov accelerated gradient)
该优化器相对于Momentum,唯一不同的是计算反向梯度的时机。
Vt=Vt−1+∇θJ(θ+Vt−1)V_t = V_{t-1} + \nabla_\theta J(\theta+V_{t-1})Vt=Vt−1+∇θJ(θ+Vt−1)
θ=θ−Vt\theta = \theta-V_tθ=θ−Vt
Momentum 在当前位置上求梯度,但是NAG是在上个动量的方向上前进一小步,然后再计算梯度,相当于:
上次是往前走了10米,这次我先往前走上2米,然后再来观察下一步怎么走。可以认为是分两步更新了theta。
AdaGrad
Adagrad优化算法是一种自适应优化算法,针对高频特征更新步长较小,而低频特征更新较大。因此该算法适合应用在特征稀疏的场景。
先前的算法对每一次参数更新都是采用同一个学习率,而adagrad算法每一步采用不同的学习率进行更新,衰减系数是 历史所有梯度的平方和。我们计算梯度的公式如下:
state['sum'].addcmul_(1, grad, grad) # s = s + grad * grad
std = state['sum'].sqrt().add_(group['eps']) # d = sqrt( s + eps)
p.data.addcdiv_(-clr, grad, std) # p = p - lr/d * grad
Adagrad算法的主要优点是它避免了手动调整学习率的麻烦,大部分的实现都采用默认值0.01。
分析
- 从AdaGrad算法中可以看出,随着算法不断迭代,r会越来越大,整体的学习率会越来越小。所以,一般来说AdaGrad算法一开始是激励收敛,到了后面就慢慢变成惩罚收敛,速度越来越慢。
- 在SGD中,随着梯度的增大,我们的学习步长应该是增大的。但是在AdaGrad中,随着梯度g的增大,我们的r也在逐渐的增大,且在梯度更新时r在分母上,也就是整个学习率是减少的,这是为什么呢?
这是因为随着更新次数的增大,我们希望学习率越来越慢。因为我们认为在学习率的最初阶段,我们距离损失函数最优解还很远,随着更新次数的增加,越来越接近最优解,所以学习率也随之变慢。 - 经验上已经发现,对于训练深度神经网络模型而言,从训练开始时积累梯度平方会导致有效学习率过早和过量的减小。AdaGrade在某些深度学习模型上效果不错,但不是全部。
- dagrad算法主要的缺点在于,其分母梯度平方的累加和。因为每次加入的都是一个正数,随着训练的进行,学习率将会变得无限小,此时算法将不能进行参数的迭代更新。
RMSPro Adadelta
这两者都是基于Adagrad的基础进行改进,主要是通过不同的方法 解决adagrad导致的学习趋近于零**(学习率消失)**,网络不学习的问题 。
通过约束历史梯度累加来替代累加所有历史梯度平方。这里通过在历史梯度上添加衰减因子,并通过迭代的方式来对当前的梯度进行计算,最终距离较远的梯度对当前的影响较小,而距离当前时刻较近的梯度对当前梯度的计算影响较大,公式
St=m∗St−1+(1−m)∗grad∗gradS_t = m*S_{t-1} + (1-m)*grad*gradSt=m∗St−1+(1−m)∗grad∗grad
随着网络更新,之前保留的梯度对 当前的下降方向 影响已经很小了,所以将累加的 梯度和 乘以 衰减系数, 权重梯度基于最近量级的均值为每一个参数适应性地保留学习率。
square_avg.mul_(alpha).addcmul_(1 - alpha, grad, grad) # s = a*s + (1-a)*g*g
Adam
Adam 则是 结合了 自适应学习策略Adagrad 和 Momentum的更新思想
Adam 算法和传统的随机梯度下降不同。随机梯度下降保持单一的学习率(即 alpha)更新所有的权重,学习率在训练过程中并不会改变。而 Adam 通过计算梯度的一阶矩估计和二阶矩估计而为不同的参数设计独立的自适应性学习率 Adam 算法的提出者描述其为两种随机梯度下降扩展式的优点集合,即:
适应性梯度算法(AdaGrad)为每一个参数保留一个学习率以提升在稀疏梯度(即自然语言和计算机视觉问题)上的性能。
均方根传播(RMSProp)基于权重梯度最近量级的均值为每一个参数适应性地保留学习率。这意味着算法在非稳态和在线问题上有很有优秀的性能。
Adam 算法同时获得了 AdaGrad 和 RMSProp 算法的优点。Adam 不仅如 RMSProp 算法那样基于一阶矩均值计算适应性参数学习率,它同时还充分利用了梯度的二阶矩均值(即有偏方差/uncentered variance)。具体来说,算法计算了梯度的指数移动均值(exponential moving average),超参数 beta1 和 beta2 控制了这些移动均值的衰减率。移动均值的初始值和 beta1、beta2 值接近于 1(推荐值),因此矩估计的偏差接近于 0。该偏差通过首先计算带偏差的估计而后计算偏差修正后的估计而得到提升。
存在的问题:
- 可能不收敛
对于SGD和AdaGrad来说,其学习率都是单调的,即单调递减,因此,这两类算法会使得学习率不断递减,最终收敛到0,模型也得以收敛。
但是对于Adam和AdaDelta,其学习率二阶估计是取固定时间窗口内的动量累加,随着窗口和数据的变化,二阶动量可能会产生的波动,从而引起学习率震荡,导致模型无法收敛;
- 可能错过全局最优解
另外一篇是 ImproVing Generalization Performance by Switching from Adam to SGD,进行了实验验证。他们CIFAR-10数据集上进行测试,Adam的收敛速度比SGD要快,但最终收敛的结果并没有SGD好。他们进一步实验发现,主要是后期Adam的学习率太低,影响了有效的收敛。他们试着对Adam的学习率的下界进行控制,发现效果好了很多。
于是他们提出了一个用来改进Adam的方法:前期用Adam,享受Adam快速收敛的优势;后期切换到SGD,慢慢寻找最优解。这一方法以前也被研究者们用到,不过主要是根据经验来选择切换的时机和切换后的学习率。这篇文章把这一切换过程傻瓜化,给出了切换SGD的时机选择方法,以及学习率的计算方法,效果看起来也不错。
参考资料:
都9102年了,别再用Adam + L2 regularization了
优化方法总结以及Adam存在的问题
常用优化器(Adam SGD)算法相关推荐
- 深度学习中常用优化器算法Optimizer详解(BGD、SGD、MBGD、Momentum、NAG、Adagrad、Adadelta、RMSprop、Adam)
本文转载自:https://www.cnblogs.com/guoyaohua/p/8542554.html 在机器学习.深度学习中使用的优化算法除了常见的梯度下降,还有 Adadelta,Adagr ...
- 妈耶,讲得好详细,十分钟彻底看懂深度学习常用优化器SGD、RMSProp、Adam详解分析
深度学习常用优化器学习总结 常用优化器 SGD RMS Prop Adam 常用优化器 SGD 基本思想:通过当前梯度和历史梯度共同调节梯度的方向和大小 我们首先根据pytorch官方文档上的这个流程 ...
- 优化器,SGD+Momentum;Adagrad;RMSProp;Adam
Optimization 随机梯度下降(SGD): 当损失函数在一个方向很敏感在另一个方向不敏感时,会产生上面的问题,红色的点以"Z"字形梯度下降,而不是以最短距离下降:这种情况在 ...
- 优化器介绍—SGD、Adam、Adagrad
文章目录 深度学习中的优化器 介绍 随机梯度下降优化器 Adam 优化器 Adagrad 优化器 如何选择优化器 结论 深度学习中的优化器 介绍 在深度学习中,优化器是一个非常重要的组成部分,它通过调 ...
- Pytorch优化器全总结(四)常用优化器性能对比 含代码
目录 写在前面 一.优化器介绍 1.SGD+Momentum 2.Adagrad 3.Adadelta 4.RMSprop 5.Adam 6.Adamax 7.AdaW 8.L-BFGS 二.优化器对 ...
- Mysql 优化器内部JOIN算法hash join On-Disk Hash Join Grace Hash Join Hybrid hash join过程详解
Mysql 各种hash join算法讲解 hash join的概述 提到hash join之前自然得说Nest loop join,以两个表的关联为例,它其实是个双层循环,先遍历外层的表(n条),再 ...
- Pytorch基础(十)——优化器(SGD,Adagrad,RMSprop,Adam,LBFGS等)
一.概念 Pytorch中优化器的目的:将损失函数计算出的差值Loss减小. 优化过程:优化器计算网络参数的梯度,然后使用一定的算法策略来对参数进行计算,用新的参数来重新进行训练,最终降低Loss. ...
- 【TensorFlow自学2】基础语句+激活函数+损失函数+正则化缓解过拟合+优化器(SGD、Adam等)
2.1预备知识 tf.where()–条件语句真的话返回A,假的话返回B tf.where(条件语句,A(真-返回),B(假-返回)) import tensorflow as tfa=tf.cons ...
- PyTorch的十个优化器(SGD,ASGD,Rprop,Adagrad,Adadelta,RMSprop,Adam(AMSGrad),Adamax,SparseAdam,LBFGS)
本文截取自<PyTorch 模型训练实用教程>,获取全文pdf请点击:https://github.com/tensor-yu/PyTorch_Tutorial 文章目录 1 torch. ...
最新文章
- 第44课 角谷猜想 动动脑 第2题 阅读程序写结果
- Java基础入门笔记-整数+小数+字符串+打印
- ffmpeg.c(ffmpeg.exe)调试笔记一
- java 正则 pattern 线程安全_(一)Java Pattern类----java正则
- 程序员的量化交易之路(17)--Cointrader之Temporal实体(5)
- docker redis 删除集群_基于Docker的Redis集群实践
- Python 文件编码问题解决
- is 32-bit instead of 64-bit 亲测可用
- python窗口大小动态变化_python – 如何让tkinter画布动态调整窗口宽度?
- 华硕笔记本电脑突然失去WIFI功能
- 从HttpClient3迁移到HttpClient4
- 华为usg系列防火墙-密码重置
- Counting Stars 全中国最准确的翻译!
- 3月第1周易盾业务风控关注 | 治理升级,让“标题党”、流量造假等网络乱象走开
- 3步实现 华为云服务器IPV4-> IPV6改造方法
- flutter 斗音页面
- 服务器引擎制作,2.5D-GIS地图引擎设计
- VPC对等连接(VPC Peering)
- linux outb函数,outb_p()函数 Unix/Linux
- C++面向对象程序设计教程
热门文章
- Python通过Spleeter实现音唱人声(歌声)伴奏分离
- 【毕业设计_课程设计】基于深度学习网络模型训练的车型识别系统
- RK3399平台开发系列讲解(内存篇)15.31、内存调优参数
- 小菜鸡的html初步教程(第十三章 使用WEB字体)
- 2020年高级Java程序员面试题汇总,含答案总结
- 在计算机语言中go是什么意思,作为编程语言,go有什么不同?
- 湖北2020年最新CMMI3-CMMI5通过的企业名单,看看没有你们公司
- jsp70150宠物寄领养系统
- oracle创建索引占用表空间吗,oracle创建索引表空间
- matlab基本矩阵运算,MATLAB矩阵及其运算