深度学习优化算法_深度学习 机器学习 算法区别 优化 - CSDN
精华内容
参与话题
  • 深度学习优化算法总结1、SGD2、SGD with Momentum3、SGD with Nesterov Acceleration 在深度学习领域,优化算法的选择是重中之重。梯度下降算法是目前神经网络中使用最广泛的优化算法之一。为了弥补朴素梯度下降的...


    在深度学习领域,优化算法的选择是重中之重。梯度下降算法是目前神经网络中使用最广泛的优化算法之一。为了弥补朴素梯度下降的缺陷,又出现了SGD、SGD with Momentum、Adam、NAdam等。
    深度学习优化算法经历了SGD->SGDM->NAG->AdaGrad->AdaDelta->Adam->Nadam 这样的发展历程。

    优化模型的大体框架如下:
    在这里插入图片描述

    1、SGD

    SGD没有动量的概念,也就是说:
    mt=gt;Vt=I2m_t=g_t; V_t=I^2
    带入步骤3,可以看到下降梯度就是最简单的:
    ηt=αgt\eta_t=\alpha \cdot g_t

    SGD最大的缺点是下降速度慢,而且可能会在沟壑的两边持续震荡,陷入局部最优点。

    2、SGD with Momentum

    为了抑制SGD的震荡,SGDM认为梯度下降过程可以加入惯性。下坡的时候如果发现是陡坡,就可以利用惯性跑的更快一些。SGDM在SGD的基础上引入了一阶动量。
    mt=β1mt1+(1β1)gtm_t=\beta_1 \cdot m_{t-1}+(1-\beta_1) \cdot g_t

    一阶动量是各个时刻梯度方向的指数移动平均值,约等于最近 个时刻的梯度向量和的平均值。
    也就是说,tt时刻的下降方向,不仅由当前点的梯度方向决定,而且由此前累积的下降方向决定。 β1\beta_1的经验值为0.9,这就意味着下降方向主要是此前累积的下降方向,并略微偏向当前时刻的下降方向。想象高速公路上汽车转弯,在高速向前的同时略微偏向,急转弯可是要出事的。

    3、SGD with Nesterov Acceleration

    除了下降速度慢,SGD还有一个问题是困在局部最优的沟壑里震荡。

    想象一下你走到一个盆地,四周都是略高的小山,你觉得没有下坡的方向,那就只能待在这里了。可是如果你爬上高地,就会发现外面的世界还很广阔。因此,我们不能停留在当前位置去观察未来的方向,而要向前一步、多看一步、看远一些。

    NAG 全称为 Nesterov Accelerated Gradient,是在SGD、SGD-M的基础上进一步改进,改进点在于步骤1。

    我们知道在时刻t的主要下降方向是由累积动量决定的,自己的梯度方向说了也不算,那与其看当前梯度方向,不如先看看如果跟着累积动量走了一步,那个时候再怎么走。因此,NAG在步骤1,不计算当前位置的梯度方向,而是计算如果按照累积动量走了一步,那个时候的下降方向:

    gt=f(wtαmt1(Vt1))g_t=\nabla f(w_t- \frac{\alpha \cdot m_{t-1}}{\sqrt(V_{t-1})})

    然后用下一个点的梯度方向,与历史累积动量相结合,计算步骤2中当前时刻的累积动量。

    4、AdaGrad

    二阶动量的出现,才意味着“自适应学习率”优化算法时代的到来。SGD及其变种都是以同样的学习率更新参数,但深度神经网络往往包含大量的参数,对于经常更新的参数,我们已经积累了大量关于它的知识,不希望被单个样本影响太大,希望学习速率慢一些;对于偶尔更新的参数,我们了解它的信息太少,希望能从每个偶然出现的样本身上多学一些,即学习速率大一些。

    二阶动量可以度量历史更新频率,二阶动量为迄今为止所有梯度值的平方和:
    Vt=τ=1tgτ2V_t=\sum^t_{\tau=1}g_\tau^2

    由步骤3中的下降梯度:
    ηt=αmt/Vt\eta_t=\alpha \cdot m_t / \sqrt{V_t}

    可知,此时的学习率实际上变成了α/Vt\alpha/\sqrt{V_t},一般为了避免分母为0,会在分母上加一个小的平滑项。当参数更新越频繁,二阶动量越大,学习率就越小。

    这一方法在稀疏数据场景下表现非常好。但也存在一些问题:因为 Vt\sqrt{V_t} 是单调递增的,会使得学习率单调递减至0,可能会使得训练过程提前结束,即便后续还有数据也无法学到必要的知识。

    5、AdaDelta / RMSProp

    由于AdaGrad单调递减的学习率变化过于激进,我们考虑一个改变二阶动量计算方法的策略:不累积全部历史梯度,而只关注过去一段时间窗口的下降梯度。这也就是AdaDelta名称中Delta的来历。
    前面我们讲到,指数移动平均值大约就是过去一段时间的平均值,因此我们用这一方法来计算二阶累积动量:

    Vt=β2Vt1+(1β2)gt2V_t=\beta_2*V_{t-1}+(1-\beta_2)g_t^2

    这就避免了二阶动量持续累积、导致训练过程提前结束的问题了。

    6、Adam

    Adam 和 Nadam 是前述方法的集大成者。我们看到,SGD-M在SGD基础上增加了一阶动量,AdaGrad和AdaDelta在SGD基础上增加了二阶动量。把一阶动量和二阶动量都用起来,就是Adam了——Adaptive+Momentum。
    在这里插入图片描述

    7、Nadam

    在这里插入图片描述

    在这里插入图片描述

    参考文献:
    [1] 一个框架看懂优化算法之异同 SGD/AdaGrad/Adam
    [2] Gradient Descent with Momentum

    展开全文
  • 深度学习常用优化算法

    万次阅读 2017-06-03 16:51:36
    深度解读最流行的优化算法:梯度下降 【本文转载自机器之心 翻译:沈泽江 原文地址:http://www.jiqizhixin.com/article/1857】 梯度下降法,是当今最流行的优化(optimization)算法,亦是至今最常用的优化...

    深度解读最流行的优化算法:梯度下降

    【本文转载自机器之心   翻译:沈泽江 原文地址:http://www.jiqizhixin.com/article/1857】

    梯度下降法,是当今最流行的优化(optimization)算法,亦是至今最常用的优化神经网络的方法。本文旨在让你对不同的优化梯度下降法的算法有一个直观认识,以帮助你使用这些算法。我们首先会考察梯度下降法的各种变体,然后会简要地总结在训练(神经网络或是机器学习算法)的过程中可能遇到的挑战。(本文的中文版 PDF 下载地址

    目录

    • 梯度下降的各种变体

    1. 批量梯度下降(Batch gradient descent)

    2. 随机梯度下降(Stochastic gradient descent)

    3. 小批量梯度下降(Mini-batch gradient descent)

    • 面临的挑战

    • 梯度下降的优化算法

    1. Momentum法

    2. Nesterov加速梯度法

    3. Adagrad法

    4. Adadelta法

    5. RMSprop法

    6. 适应性动量估计法(Adam)

    7. 几种算法的可视化

    8. 该选择哪种优化器

    • 对SGD进行平行或分布式运算

    1. Hogwild!

    2. Downpour SGD

    3. 容忍延迟的SGD算法

    4. TensorFlow

    5. 弹性平均梯度下降法(Elastic Averaging SGD)

    • 优化SGD的其他手段

    1. 重排(Shuffling )和递进学习(Curriculum Learning)

    2. 批量标准化(Batch normalization)

    3. 早停(Early Stopping)

    4. 梯度噪声(Gradient noise)

    • 结论

    • 参考资料


    梯度下降法,是当今最流行的优化(optimization)算法,亦是至今最常用的优化神经网络的方法。与此同时,最新的深度学习程序库都包含了各种优化梯度下降的算法(可以参见如 lasagne、caffe 及 Kera 等程序库的说明文档)。但它们的算法则不被公开,都作为黑箱优化器被使用,这也就是为什么它们的优势和劣势往往难以被实际地解释。

    本文旨在让你对不同的优化梯度下降法的算法有一个直观认识,以帮助你使用这些算法。我们首先会考察梯度下降法的各种变体,然后会简要地总结在训练(神经网络或是机器学习算法)的过程中可能遇到的挑战。接着,我们将会讨论一些最常见的优化算法,研究它们的解决这些挑战的动机及推导出更新规律(update rules)的过程。我们还会简要探讨一下,在平行计算或是分布式处理情况下优化梯度下降法的算法和架构。最后,我们会考虑一下其他有助于优化梯度下降法的策略。

    梯度下降法的核心,是最小化目标函数 J(θ),其中θ是模型的参数,θ∈Rd。它的方法是,在每次迭代中,对每个变量,按照目标函数在该变量梯度的相反方向,更新对应的参数值。其中,学习率η决定了函数到达(局部)最小值的迭代次数。换句话说,我们在目标函数的超平面上,沿着斜率下降的方向前进,直到我们遇到了超平面构成的「谷底」。如果你不熟悉梯度下降法的话,你可以在这里找到一个很好的关于优化神经网络的介绍。

    梯度下降法变体

    本文讨论了三种梯度下降法的变体——它们的不同之处在于,一次性使用多少数据来计算目标函数的梯度。对于不同的数据量,我们需要在参数更新准确性和参数更新花费时间两方面做出权衡。

    批量梯度下降法(Batch Gradient Descent)

    Vanilla 梯度下降法(译者注:Vanilla 是早期机器学习算法相关的名词,也是如今一个机器学习 python 程序库的名字,在该处指的是后者,参见:https://github.com/vinhkhuc/VanillaML),也就是大家所熟知的批量梯度下降法,在整个数据集上(求出罚函数 J(θ 并)对每个参数 θ 求目标函数 J(θ) 的偏导数:

    blob.png

    在该方法中,每次更新我们都需要在整个数据集上求出所有的偏导数。因此批量梯度下降法的速度会比较慢,甚至对于较大的、内存无法容纳的数据集,该方法都无法被使用。同时,梯度下降法不能以「在线」的形式更新我们的模型,也就是不能再运行中加入新的样本进行运算。

    批量梯度下降法的实现代码,如下所示:

    for i in range(nb_epochs):
      params_grad = evaluate_gradient(loss_function, data, params)
      params = params - learning_rate * params_grad

    对于给定的迭代次数,我们首先基于输入的罚函数 loss_function 对输入的参数向量 params 计算梯度向量 params_grad。注意,最新的深度学习程序库中,提供了自动求导的功能,能够高效、快速地求给定函数对于特定参数的导数。如果你希望自己写代码求出梯度值,那么「梯度检查」会是一个不错的注意。(你可以参考这里,了解关于如何检查梯度的相关建议。)

    然后,我们对参数减去梯度值乘学习率的值,也就是在反梯度方向,更新我们参数。当目标函数 J(θ) 是一凸函数时,则批量梯度下降法必然会在全局最小值处收敛;否则,目标函数则可能会局部极小值处收敛。

    随机梯度下降法(Stochastic Gradient Descent)

    相比批量梯度下降法,随机梯度下降法的每次更新,是对数据集中的一个样本(x,y)求出罚函数,然后对其求相应的偏导数:

    blob.png

    因为批量梯度下降法在每次更新前,会对相似的样本求算梯度值,因而它在较大的数据集上的计算会有些冗余(redundant)。而随机梯度下降法通过每次更新仅对一个样本求梯度,去除了这种冗余的情况。因而,它的运行速度被大大加快,同时也能够「在线」学习。

    随机梯度下降法更新值的方差很大,在频繁的更新之下,它的目标函数有着如下图所示的剧烈波动。

    deep-learning-pic.png


    SGD 函数波动,来源:Wikipedia

    相比批量梯度下降法的收敛会使目标函数落入一个局部极小值,SGD 收敛过程中的波动,会帮助目标函数跳入另一个可能的更小的极小值。另一方面,这最终会让收敛到特定最小值的过程复杂化,因为该方法可能持续的波动而不停止。但是,当我们慢慢降低学习率的时候,SGD 表现出了与批量梯度下降法相似的收敛过程,也就是说,对非凸函数和凸函数,必然会分别收敛到它们的极小值和最小值。

    相比批量梯度下降法的代码,在如下的代码中,我们仅仅加入了一个循环,用以遍历所有的训练样本并求出相应的梯度值。注意,如这里所说,在每次迭代中,我们会打乱训练数据集。

    for i in range(nb_epochs):
      np.random.shuffle(data)
      for example in data:
        params_grad = evaluate_gradient(loss_function, example, params)
        params = params - learning_rate * params_grad

    小批量梯度下降法(Mini-Batch Gradient Descent)

    小批量梯度下降法集合了上述两种方法的优势,在每次更新中,对 n 个样本构成的一批数据,计算罚函数 J(θ),并对相应的参数求导:

    blob.png

    这种方法,(a) 降低了更新参数的方差(variance),使得收敛过程更为稳定;(b) 能够利用最新的深度学习程序库中高度优化的矩阵运算器,能够高效地求出每小批数据的梯度。通常一小批数据含有的样本数量在 50 至 256 之间,但对于不同的用途也会有所变化。小批量梯度下降法,通常是我们训练神经网络的首选算法。同时,有时候我们也会使用随机梯度下降法,来称呼小批量梯度下降法(译者注:在下文中,我们就用 SGD 代替随机梯度下降法)。注意:在下文对于随机梯度法优化的介绍中,为方便起见,我们会省略式子中的参数 x(i:i+n),y(i:i+n)。

    如下的代码所示,我们不再对每个样本进行循环,而是对每批带有 50 个样本的小批数据进行循环:

    for i in range(nb_epochs):
      np.random.shuffle(data)
      for batch in get_batches(data, batch_size=50):
        params_grad = evaluate_gradient(loss_function, batch, params)
        params = params - learning_rate * params_grad

    面临的挑战

    由于 Vanilla 小批量梯度下降法并不能保证良好地收敛,这给我们留下了如下待解决的挑战:

    • 选择适当的学习率是一个难题。太小的学习率会导致较慢的收敛速度,而太大的学习率则会阻碍收敛,并会引起罚函数在最小值处震荡,甚至有可能导致结果发散;

    • 我们可以设置一个关于学习率地列表,通过如退火的方法,在学习过程中调整学习率——按照一个预先定义的列表、或是当每次迭代中目标函数的变化小于一定阈值时来降低学习率。但这些列表或阈值,需要根据数据集地特性,被提前定义。

    • 此外,我们对所有的参数都采用了相同的学习率。但如果我们的数据比较稀疏,同时特征有着不同的出现频率,那么我们不希望以相同的学习率来更新这些变量,我们希望对较少出现的特征有更大的学习率。

    在对神经网络最优化非凸的罚函数时,另一个通常面临的挑战,是如何避免目标函数被困在无数的局部最小值中,以导致的未完全优化的情况。Dauphin 及其他人 [19] 认为,这个困难并不来自于局部最小值,而是来自于「鞍点」,也就是在一个方向上斜率是正的、在一个方向上斜率是负的点。这些鞍点通常由一些函数值相同的面环绕,它们在各个方向的梯度值都为 0,所以 SGD 很难从这些鞍点中脱开。

    梯度下降的优化算法

    在如下的讨论中,我们将会列举一些应对上述问题的算法,它们被广泛应用于深度学习社区。同时,我们不会讨论那些不能应用于高维数据集的方法,例如牛顿法等针对二阶问题的方法。


       

    动量法

    SGD 很难在陡谷——一种在一个方向的弯曲程度远大于其他方向的表面弯曲情况——中找到正确更新方向。而这种陡谷,经常在局部极值中出现。在这种情况下,如图 2 所示,SGD 在陡谷的周围震荡,向局部极值处缓慢地前进。

    blob.png

    动量法 [2],如图 3 所示,则帮助 SGD 在相关方向加速前进,并减少它的震荡。他通过修改公式中,在原有项前增加一个折损系数γ,来实现这样的功能:

    blob.png

    注意:在其他的一些算法实现中,公式中的符号也许有所不同。动量项 γ 往往被设置为 0.9 或为其他差不多的值。

    从本质上说,动量法,就仿佛我们从高坡上推下一个球,小球在向下滚动的过程中积累了动量,在途中他变得越来越快(直到它达到了峰值速度,如果有空气阻力的话,γ<1)。在我们的算法中,相同的事情发生在我们的参数更新上:动量项在梯度指向方向相同的方向逐渐增大,对梯度指向改变的方向逐渐减小。由此,我们得到了更快的收敛速度以及减弱的震荡。

    Nesterov 加速梯度法

    但当一个小球从山谷上滚下的时候,盲目的沿着斜率方向前行,其效果并不令人满意。我们需要有一个更「聪明」的小球,它能够知道它再往哪里前行,并在知道斜率再度上升的时候减速。

    Nesterov 加速梯度法(NAG)是一种能给予梯度项上述「预测」功能的方法。我们知道,我们使用动量项γvt-1 来「移动」参数项θ。通过计算θ-γvt-1,我们能够得到一个下次参数位置的近似值——也就是能告诉我们参数大致会变为多少。那么,通过基于未来参数的近似值而非当前的参数值计算相得应罚函数 J(θ-γvt-1) 并求偏导数,我们能让优化器高效地「前进」并收敛:

    blob.png

    在该情况下,我们依然设定动量系数γ 在 0.9 左右。如下图 4 所示,动量法首先计算当前的梯度值(小蓝色向量),然后在更新的积累向量(大蓝色向量)方向前进一大步。但 NAG 法则首先(试探性地)在之前积累的梯度方向(棕色向量)前进一大步,再根据当前地情况修正,以得到最终的前进方向(绿色向量)。这种基于预测的更新方法,使我们避免过快地前进,并提高了算法地响应能力(responsiveness),大大改进了 RNN 在一些任务上的表现 [8]。

    jqzx (88).png


    Nesterov Update 法,来源:G. Hinton's lecture 6c

    参考这里,以查看 Ilya Sutskever 在它博士论文中,对 NAG 机理的更为详尽的解释 [9]。

    因为我们现在能根据我们罚函数的梯度值来调整我们的更新,并能相应地加速 SGD,我们也希望能够对罚函数中的每个参数调整我们的更新值,基于它们的重要性以进行或大或小的更新。

    Adagrad 法

    Adagrad[3] 是一个基于梯度的优化算法,它的主要功能是:它对不同的参数调整学习率,具体而言,对低频出现的参数进行大的更新,对高频出现的参数进行小的更新。因此,他很适合于处理稀疏数据。Dean 等人 [14] 发现,Adagrad 法大大提升了 SGD 的鲁棒性,并在谷歌使用它训练大规模的神经网络,其诸多功能包括识别 Youtube 视频中的猫。此外,Pennington 等人 [5] 使用它训练 GloVe 单词向量映射(Word Embedding),在其中不频繁出现的词语需要比频繁出现的更大的更新值。

    在这之前,我们对于所有的参数使用相同的学习率进行更新。但 Adagrad 则不然,对不同的训练迭代次数 t,adagrad 对每个参数都有一个不同的学习率。我们首先考察 adagrad 每个参数的的更新过程,然后我们再使之向量化。为简洁起见,我们记在迭代次数 t 下,对参数θi 求目标函数梯度的结果为 gt,i:

    blob.png

    那么普通 SGD 的更新规则为:

    blob.png

    而 adagrad 将学习率η进行了修正,对迭代次数 t,基于每个参数之前计算的梯度值,将每个参数的学习率η按如下方式修正:

    blob.png

    其中 是一个对角阵,其中对角线上的元素是从一开始到 时刻目标函数对于参数 梯度的平方和。是一个平滑项,以避免分母为 0 的情况,它的数量级通常在。有趣的是,如果不开方的话,这个算法的表现会变得很糟。

    因为 在其对角线上,含有过去目标函数对于参数 梯度的平方和,我们可以利用一个元素对元素的向量乘法,将我们的表达式向量化:

    blob.png

    Adagrad 主要优势之一,是它不需要对每个学习率手工地调节。而大多数算法,只是简单地使用一个相同地默认值如 0.1,来避免这样地情况。

    Adagrad 地主要劣势,是他在分母上的项中积累了平方梯度和。因为每次加入的项总是一个正值,所以累积的和将会随着训练过程而增大。因而,这会导致学习率不断缩小,并最终变为一个无限小值——此时,这个算法已经不能从数据中学到额外的信息。而下面的算法,则旨在解决这个问题。

    Adadelta 法

    Adadelta 法 [6] 是 Adagrad 法的一个延伸,它旨在解决它学习率不断单调下降的问题。相比计算之前所有梯度值的平方和,Adadelta 法仅计算在一个大小为 的时间区间内梯度值的累积和。

    但该方法并不会存储之前 个梯度的平方值,而是将梯度值累积值按如下的方式递归地定义:它被定义为关于过去梯度值的衰减均值(decade average),当前时间的梯度均值是基于过去梯度均值和当前梯度值平方的加权平均,其中是类似上述动量项的权值。

    blob.png

    与动量项的设定类似,我们设定 为以 0.9 左右的值。为明确起见,我们将我们的 SGD 更新规则写为关于参数更新向量 的形式:

    blob.png

    由此,我们刚刚在 Adagrad 法中推导的的参数更新规则的向量表示,变为如下形式:

    blob.png

    我们现在将其中的对角矩阵 用上述定义的基于过去梯度平方和的衰减均值 替换:

    blob.png

    因为分母表达式的形式与梯度值的方均根(root mean squared,RMS)形式类似,因而我们使用相应的简写来替换:

    blob.png

    作者还注意到,在该更新中(在 SGD、动量法或者 Adagrad 也类似)的单位并不一致,也就是说,更新值的量纲与参数值的假设量纲并不一致。为改进这个问题,他们定义了另外一种指数衰减的衰减均值,他是基于参数更新的平方而非梯度的平方来定义的:

    blob.png

    因此,对该问题的方均根为:

    blob.png

    因为 值未知,所以我们使用 时刻的方均根来近似。将前述规则中的学习率 替换为,我们最终得到了 Adadelta 法的更新规则:

    blob.png

    借助 Adadelta 法,我们甚至不需要预设一个默认学习率,因为它已经从我们的更新规则中被删除了。

    RMSprop 法

    RMSprop 是由 Geoff Hinton 在他 Coursera 课程中提出的一种适应性学习率方法,至今仍未被公开发表。

    RMSprop 法和 Adadelta 法几乎同时被发展出来。他们 解决 Adagrad 激进的学习率缩减问题。实际上,RMSprop 和我们推导出的 Adadelta 法第一个更规则相同:

    blob.png

    RMSprop 也将学习率除以了一个指数衰减的衰减均值。Hinton 建议设定 为 0.9,对 而言,0.001 是一个较好的默认值。

    Adam

    适应性动量估计法(Adam)[15] 是另一种能对不同参数计算适应性学习率的方法。除了存储类似 Adadelta 法或 RMSprop 中指数衰减的过去梯度平方均值 外,Adam 法也存储像动量法中的指数衰减的过去梯度值均值 :

    blob.png

    和 分别是梯度的一阶矩(均值)和二阶矩(表示不确定度的方差),这也就是该方法名字的来源。因为当 和 一开始被初始化为 0 向量时,Adam 的作者观察到,该方法会有趋向 0 的偏差,尤其是在最初的几步或是在衰减率很小(即 和 接近 1)的情况下。

    他们使用偏差纠正系数,来修正一阶矩和二阶矩的偏差:

    blob.png

    他们使用这些来更新参数,更新规则很我们在 Adadelta 和 RMSprop 法中看到的一样,服从 Adam 的更新规则:blob.png

    作者认为参数的默认值应设为:0.9 for 

    β1, 0.999 for β2, and 108 for ϵ.    。他们的经验表明,Adam 在实践中表现很好,和其他适应性学习算法相比也比较不错。

    算法可视化

    如下的两个动画(图像版权:Alec Radford)给了我们关于特定优化算法在优化过程中行为的直观感受。你可以参见这里,以获取 Karpathy 对相同图像的一些描述,及另关于一些相关算法的细致讨论。

    在图 5 中,我们可以看到,在罚函数的等高线图中,优化器的位置随时间的变化情况。注意到,Adagrad、 Adadelta 及 RMSprop 法几乎立刻就找到了正确前进方向并以相似的速度很快收敛。而动量法和 NAG 法,则找错了方向,如图所示,让小球沿着梯度下降的方向前进。但 NAG 法能够很快改正它的方向向最小指出前进,因为他能够往前看并对前面的情况做出响应。

    图 6 展现了各算法在鞍点附近的表现。如上面所说,这对对于 SGD 法、动量法及 NAG 法制造了一个难题。他们很难打破」对称性「带来的壁垒,尽管最后两者设法逃脱了鞍点。而 Adagrad 法、RMSprop 法及 Adadelta 法都能快速的沿着负斜率的方向前进。

    Black_box_AI_nature.gif

    图5:SGD optimization on loss surface contours

    Synced (5).gif

    图6:SGD optimization on saddle point108

    如我们所见,适应性学习率方法,也就是 Adagrad 法、Adadelta 法 、RMSprop 法及 Adam 法最适合处理上述情况,并有最好的收敛效果。

    如何选择优化器?

    那么,我们该如何选择优化器呢?如果你的输入数据较为稀疏(sparse),那么使用适应性学习率类型的算法会有助于你得到好的结果。此外,使用该方法的另一好处是,你在不调参、直接使用默认值的情况下,就能得到最好的结果。

    总的来说,RMSprop 法是一种基于 Adagrad 法的拓展,他从根本上解决学习率骤缩的问题。Adadelta 法于 RMSprop 法大致相同,除了前者使用了。而 Adam 法,则基于 RMSprop 法添加了偏差修正项和动量项。在我们地讨论范围中,RMSprop、Adadelta 及 Adam 法都是非常相似地算法,在相似地情况下都能做的很好。Kingma 及其他人 [15] 展示了他们的偏差修正项帮助 Adam 法,在最优化过程快要结束、梯度变得越发稀疏的时候,表现略微优于 RMSprop 法。总的来说,Adam 也许是总体来说最好的选择。

    有趣的是,很多最新的论文,都直接使用了(不带动量项的)Vanilla SGD 法,配合一个简单的学习率(退火)列表。如论文所示,这些 SGD 最终都能帮助他们找到一个最小值,但会花费远多于上述方法的时间。并且这些方法非常依赖于鲁棒的初始化值及退火列表。因此,如果你非常在你的模型能快速收敛,或是你需要训练一个深度或复杂模型,你可能需要选择上述的适应性模型。

    对 SGD 进行平行计算或分布式计算

    现如今,大规模数据集随处可见、小型计算机集群也易于获得。因而,使用分布式方法进一步加速 SGD 是一个惯常的选择。

    SGD 它本事是序列化的:通过一步一步的迭代,我们最终求到了最小值。运行它能够得到不错的收敛结果,但是特别是对于大规模的数据集,它的运行速度很慢。相比而言,异步 SGD 的运行速度相对较快,但在不同的工作机之间的关于非完全优化的沟通可能会导致较差的收敛结果。此外,我们能够对 SGD 进行平行运算而不需要一个计算机集群。下文讨论了相关的算法或架构,它们或关于平行计算或者对其进行了分布式优化。

    Hogwild!

    Niu 等人提出了一种叫做 Hogwild! 的更新规则,它允许在平行 GPU 上进行 SGD 更新。处理器。这仅能在输入数据集是稀疏的时起效,在每次更新过程中仅会修正一部分的参数值。他们展示了,在这种情况下,这个更新规则达到了最优化的收敛速度,因为处理器不太会覆盖有用的信息。

    Downpour SGD

    Downpour SGD 是一个异步的 SGD 法变体,它被 Dean 等人 [4] 用在了谷歌的 DistBelief 架构中(它是 TensorFlow 的前身)。他对训练集地子集同步地运行模型的多个副本。这些模型将它们的更新值发送到参数服务器,服务器被分为了许多台主机。每一台主机都负责存储和上载模型的一部分参数。但是,副本之间却没有相互的通信——例如,共享权重值或者更新值——其参数面临着发散的风险,会阻止收敛。

    容忍延迟的 SGD 算法

    McMahan 和 Streeter [12] 改良了 AdaGrad 法使之能够用于平行运算的场景。通过实现延迟容忍的算法,它不仅能能够适应于过去的梯度,还能够适应于更新的延迟。在实践中,它的表现很好。

    TensorFlow

    TensorFlow[13] 是谷歌最近开源的一个实现和部署大规模机器学习模型的架构。它基于他们之前对于使用 DistBelief 的经验,并已在内部被部署在一系列的移动设备及大规模的分布式系统上进行计算。为了分布式执行,一个计算图被分为了许多子图给不同的设备,设备之间的通信使用了发送和接受节点对。2016 年 4 月 13 日更新:一个分布式 TensorFlow 的版本已经被发布。

    弹性平均梯度下降法(Elastic Averaging SGD)

    张等人 [14] 提出了弹性平均梯度下降法(EASGD),他使不同工作机之间不同的 SGD 以一个「弹性力」连接,也就是一个储存于参数服务器的中心变量。这允许局部变量比中心变量更大地波动,理论上允许了对参数空间更多的探索。他们的经验表明,提高的探索能力有助于在寻找新的局部极值中提升(优化器的)表现。

    优化 SGD 的其他手段

    最后,我们将讨论一些其他手段,他们可以与前述的方法搭配使用,并能进一步提升 SGD 的效果。你可以参考 [22],以了解一些其他常用策略。

    重排法(Shuffling)和递进学习(Curriculum Learning)

    总体而言,我们希望避免训练样本以某种特定顺序传入到我们的学习模型中,因为这会向我们的算法引入偏差。因此,在每次迭代后,对训练数据集中的样本进行重排(shuffling),会是一个不错的注意。

    另一方面,在某些情况下,我们会需要解决难度逐步提升的问题。那么,按照一定的顺序遍历训练样本,会有助于改进学习效果及加快收敛速度。这种构建特定遍历顺序的方法,叫做递进学习(Curriculum Learning)[16]。*这个词目前没有标准翻译,我根据表意和意义翻译成这个。

    Zaremba 和 Sutskever [17] 仅使用了递进学习法训练 LSTMs 来学习简单的项目,但结果表明,递进学习法使用的混合策略的表现好于朴素策略——后者不断地重排数据,反而增加了学习过程的难度。

    批量标准化(Batch Normalization)

    我们通常设置我们参数初值的均值和方差分别为 0 和单位值,以帮助模型进行学习。随着学习过程的进行,每个参数被不同程度地更新,相应地,参数的正则化特征也随之失去了。因此,随着训练网络的越来越深,训练的速度会越来越慢,变化值也会被放大。

    批量标准化 [18] 对每小批数据都重新进行标准化,并也会在操作中逆传播(back-propgate)变化量。在模型中加入批量标准化后,我们能使用更高的学习率且不要那么在意初始化参数。此外,批量正则化还可以看作是一种正则化手段,能够减少(甚至去除)留出法的使用。

    早停(Early Stopping)

    诚如 Geoff Hinton 所言:「Early stopping (is) beautiful free lunch(早停是美妙的免费午餐,又简单效果又好)」(NIPS 2015 Tutorial Sildes, Slide 63)。在训练过程中,你应该时刻关注模型在验证集上的误差情况,并且在改误差没有明显改进的时候停止训练。

    梯度噪声(Gradient Noise)

    Neelakentan 等人 [21] 在每次梯度的更新中,向其中加入一个服从合高斯分布 N(0,σ^2) 的噪声值:

    blob.png

    并按照如下的方式修正方差:

    blob.png

    他们指出,这种方式能够提升神经网络在不良初始化前提下的鲁棒性,并能帮助训练特别是深层、复杂的神经网络。他们发现,加入噪声项之后,模型更有可能发现并跳出在深度网络中频繁出现的局部最小值。

    结论

    在本文中,我们首先分析了梯度下降法的三个变体,在其中小批量梯度下降法最受欢迎。接着,我们研究了常用的优化 SGD 的算法,包括:动量法、Nesterov accelerated gradient 法、Adagrad 法、Adadelta 法、RMSprop 法、Adam 法及其他优化异步 SGD 的算法。最终,我们讨论了另外一些改进 SGD 的策略,包括样本重排法(shuffling)、递进学习(curriculum learning)、批量标准化(Batch Normali·zation)及早停(early stopping)等。

    我希望本文能增进读者关于这些优化算法的认识,能对这些算法的行为与动机有一个了解。也许我遗漏了一些常用的优化 SGD 的算法,或是你有一些自己使用 SGD 训练的技巧。如果有的话,请在下方留言区留言让我知道。

    原文连接查看参考文献:http://sebastianruder.com/optimizing-gradient-descent/

    展开全文
  • 深度学习总结(一)各种优化算法

    万次阅读 多人点赞 2018-07-03 20:11:11
    参考博文: 码农王小呆:...深度学习最全优化方法总结: https://blog.csdn.net/u012759136/article/details/52302426 超级详细每个算法的讲解,可参考: https://blog.csdn.net/tsyccnh/articl...

    参考博文:
    码农王小呆:https://blog.csdn.net/manong_wxd/article/details/78735439
    深度学习最全优化方法总结:
    https://blog.csdn.net/u012759136/article/details/52302426
    超级详细每个算法的讲解,可参考:
    https://blog.csdn.net/tsyccnh/article/details/76673073

    一.优化算法介绍

    1.批量梯度下降(Batch gradient descent,BGD)

    θ=θ−η⋅∇θJ(θ)
    每迭代一步,都要用到训练集的所有数据,每次计算出来的梯度求平均
    η代表学习率LR

    2.随机梯度下降(Stochastic Gradient Descent,SGD)

    θ=θ−η⋅∇θJ(θ;x(i);y(i))
    通过每个样本来迭代更新一次,以损失很小的一部分精确度和增加一定数量的迭代次数为代价,换取了总体的优化效率的提升。增加的迭代次数远远小于样本的数量。

    缺点:

    对于参数比较敏感,需要注意参数的初始化
    容易陷入局部极小值
    当数据较多时,训练时间长
    每迭代一步,都要用到训练集所有的数据。

    3. 小批量梯度下降(Mini Batch Gradient Descent,MBGD)

    θ=θ−η⋅∇θJ(θ;x(i:i+n);y(i:i+n))
    为了避免SGD和标准梯度下降中存在的问题,对每个批次中的n个训练样本,这种方法只执行一次更新。【每次更新全部梯度的平均值】

    4.指数加权平均的概念

    这里写图片描述
    这里写图片描述
    从这里我们就可已看出指数加权平均的名称由来,第100个数据其实是前99个数据加权和,而前面每一个数的权重呈现指数衰减,即越靠前的数据对当前结果的影响较小
    这里写图片描述

    缺点:存在开始数据的过低问题,可以通过偏差修正,但是在深度学习的优化算法中一般会忽略这个问题
    这里写图片描述
    当t不断增大时,分母逐渐接近1,影响就会逐渐减小了

    优点:【相较于滑动窗口平均】
    1.占用内存小,每次覆盖即可
    2.运算简单

    5.Momentum(动量梯度下降法)

    momentum是模拟物理里动量的概念,积累之前的动量来替代真正的梯度。公式如下:
    这里写图片描述
    然而网上更多的是另外一种版本,即去掉(1-β)
    这里写图片描述
    相当于上一版本上本次梯度的影响权值*1/(1-β)
    两者效果相当,只不过会影响一些最优学习率的选取
    优点

    • 下降初期时,使用上一次参数更新,下降方向一致,乘上较大的μ能够进行很好的加速
    • 下降中后期时,在局部最小值来回震荡的时候,gradient→0,β得更新幅度增大,跳出陷阱
    • 在梯度改变方向的时候,μ能够减少更新

    即在正确梯度方向上加速,并且抑制波动方向张的波动大小,在后期本次计算出来的梯度会很小,以至于无法跳出局部极值,Momentum方法也可以帮助跳出局部极值
    参数设置
    β的常用值为0.9,即可以一定意义上理解为平均了前10/9次的梯度。
    至于LR学习率的设置,后面所有方法一起总结吧

    6.Nesterov accelerated gradient (NAG)

    Momentum图解
    NAG图解
    这里写图片描述
    优点:
    这种基于预测的更新方法,使我们避免过快地前进,并提高了算法地响应能力,大大改进了 RNN 在一些任务上的表现【为什么对RNN好呢,不懂啊】
    没有对比就没有伤害,NAG方法收敛速度明显加快。波动也小了很多。实际上NAG方法用到了二阶信息,所以才会有这么好的结果。先按照原来的梯度走一步的时候已经求了一次梯度,后面再修正的时候又求了一次梯度,所以是二阶信息。
    参数设置:
    同Momentum

    其实,momentum项和nesterov项都是为了使梯度更新更加灵活,对不同情况有针对性。但是,人工设置一些学习率总还是有些生硬,接下来介绍几种自适应学习率的方法

    7.Adagrad

    前面的一系列优化算法有一个共同的特点,就是对于每一个参数都用相同的学习率进行更新。但是在实际应用中各个参数的重要性肯定是不一样的,所以我们对于不同的参数要动态的采取不同的学习率,让目标函数更快的收敛。
    adagrad方法是将每一个参数的每一次迭代的梯度取平方累加再开方,用基础学习率除以这个数,来做学习率的动态更新。【这样每一个参数的学习率就与他们的梯度有关系了,那么每一个参数的学习率就不一样了!也就是所谓的自适应学习率
    这里写图片描述

    优点:

    • 前期Gt较小的时候, regularizer较大,能够放大梯度
    • 后期Gt较大的时候,regularizer较小,能够约束梯度
    • 适合处理稀疏梯度:相当于为每一维参数设定了不同的学习率:压制常常变化的参数,突出稀缺的更新。能够更有效地利用少量有意义样本

    参数设置:
    只需要设置初始学习率,后面学习率会自我调整,越来越小

    缺点:
    Adagrad的一大优势时可以避免手动调节学习率,比如设置初始的缺省学习率为0.01,然后就不管它,另其在学习的过程中自己变化。当然它也有缺点,就是它计算时要在分母上计算梯度平方的和,由于所有的参数平方【上述公式推导中并没有写出来是梯度的平方,感觉应该是上文的公式推导忘了写】必为正数,这样就造成在训练的过程中,分母累积的和会越来越大。这样学习到后来的阶段,网络的更新能力会越来越弱,能学到的更多知识的能力也越来越弱,因为学习率会变得极其小【就会提前停止学习】,为了解决这样的问题又提出了Adadelta算法。

    8.Adadelta

    Adagrad会累加之前所有的梯度平方,而Adadelta只累加固定大小的项【其实就是相当于指数滑动平均,只用了前多少步的梯度平方平均值】,并且也不直接存储这些项,仅仅是近似计算对应的平均值【这也就是指数滑动平均的优点】
    这里写图片描述
    优点:
    不用依赖于全局学习率了
    训练初中期,加速效果不错,很快
    避免参数更新时两边单位不统一的问题
    缺点:
    训练后期,反复在局部最小值附近抖动

    9.RMSprop

    这里写图片描述
    特点:

    • 其实RMSprop依然依赖于全局学习率
    • RMSprop算是Adagrad的一种发展,和Adadelta的变体,效果趋于二者之间
    • 适合处理非平稳目标(也就是与时间有关的)
    • 对于RNN效果很好,因为RMSprop的更新只依赖于上一时刻的更新,所以适合。???

    10.Adam

    Adam = Adaptive + Momentum,顾名思义Adam集成了SGD的一阶动量和RMSProp的二阶动量。
    这里写图片描述
    特点:

    • 结合了Adagrad善于处理稀疏梯度和RMSprop善于处理非平稳目标的优点
    • 对内存需求较小
    • 为不同的参数计算不同的自适应学习率
    • 也适用于大多非凸优化
    • 适用于大数据集和高维空间

    11.Adamax

    这里写图片描述

    12.Nadam

    这里写图片描述

    13.总结

    提速可以归纳为以下几个方面:
    - 使用momentum来保持前进方向(velocity);
    - 为每一维参数设定不同的学习率:在梯度连续性强的方向上加速前进;
    - 用历史迭代的平均值归一化学习率:突出稀有的梯度;

    Keras中的默认参数

    optimizers.SGD(lr=0.001,momentum=0.9)
    
    optimizers.Adagrad(lr=0.01,epsilon=1e-8)
    
    optimizers.Adadelta(lr=0.01,rho=0.95,epsilon=1e-8)
    
    optimizers.RMSprop(lr=0.001,rho=0.9,epsilon=1e-8)
    
    optimizers.Adam(lr=0.001,beta_1=0.9,beta_2=0.999,epsilon=1e-8)

    14.牛顿法——二阶优化方法【待补充】

    二.相关注意问题

    1.关于批量梯度下降的batch_size选择问题

    训练集较小【<2000】:直接使用batch梯度下降,每次用全部的样本进行梯度更新
    训练集较大:batch_size一般设定为[64,512]之间,设置为2的n次方更符合电脑内存设置,代码会运行快一些
    此外还要考虑GPU和CPU的存储空间和训练过程的波动问题
    这里写图片描述
    batch_size越小,梯度的波动越大,正则化的效果也越强,自然训练速度也会变慢,实验时应该多选择几个batch_size进行实验,以挑选出最优的模型。

    2.关于批量梯度下降的weight_decay【似乎与L2正则有关系,待补充】

    3.关于优化算法选择的经验之谈

    1. Adam在实际应用中效果良好,超过了其他的自适应技术。
    2. 如果输入数据集比较稀疏,SGD、NAG和动量项等方法可能效果不好。因此对于稀疏数据集,应该使用某种自适应学习率的方法,且另一好处为不需要人为调整学习率,使用默认参数就可能获得最优值。
    3. 如果想使训练深层网络模型快速收敛或所构建的神经网络较为复杂,则应该使用Adam或其他自适应学习速率的方法,因为这些方法的实际效果更优。
    4. SGD通常训练时间更长,但是在好的初始化和学习率调度方案的情况下,结果更可靠。
    5. Adadelta,RMSprop,Adam是比较相近的算法,在相似的情况下表现差不多。在想使用带动量的RMSprop,或者Adam的地方,大多可以使用Nadam取得更好的效果

    4.训练优化器的目的

    加速收敛 2. 防止过拟合 3. 防止局部最优

    5.选用优化器的目的

    在构建神经网络模型时,选择出最佳的优化器,以便快速收敛并正确学习,同时调整内部参数,最大程度地最小化损失函数。

    6.为什么神经网络的训练不采用二阶优化方法 (如Newton, Quasi Newton)?

    这里写图片描述

    7. 优化SGD的其他手段

    这里写图片描述
    这里写图片描述
    这里写图片描述

    附录

    这里写图片描述

    展开全文
  • 深度学习训练模型的时候需要使用到优化算法,最终我们都是在求解代价函数的最小化问题来求解模型的参数。有的时候,训练一个神经网络模型可能需要几百上千台机器同时训练几个月,通过使用优化算法可以节省训练的...

    在训练神经网络模型的时候需要使用到优化算法,最终我们都是通过求解代价函数的最优化问题来求解模型的参数。有的时候,训练一个神经网络模型可能需要几百上千台机器同时训练几个月,通过使用优化算法可以节省训练的时间加快模型的收敛。本篇文章主要介绍一下常用的优化算法

    • 梯度下降算法
    • 指数加权平均算法
    • 动量梯度下降
    • RMSprop算法
    • Adam优化算法

    常用的优化算法在面试的时候也会经常被问到。

    一、梯度下降算法

    在训练模型之前会先定义一个代价函数,然后通过不停的迭代训练数据利用梯度下降算法来减少每次迭代的误差,从而使得代价函数最小化。梯度下降算法主要包括三种,随机梯度下降batch梯度下降mini-batch梯度下降。最常用的是mini-batch梯度下降算法。

    • 随机梯度下降
      随机梯度下降算法是指在训练模型的时候,每次迭代只从训练数据中随机抽取一个数据来计算梯度更新模型的参数。随机梯度下降算法永远无法收敛,容易受到噪声的干扰,训练时间长,代价函数最终会围绕全局最小值或者局部极小值震荡。
    • batch梯度下降
      batch梯度下降算法是指在训练模型的时候,每次迭代时使用所有的训练数据来计算梯度更新模型的参数。batch梯度下降算法适用于小数据集的训练,对于大数据集(大于2000)不太适应,因为每次训练的时候都要使用所有的训练数据,会导致需要消耗大量的内存,增加电脑的计算量,计算时间长。batch梯度下降不容易受到噪声数据的干扰,在迭代的时候能够保证向全局最小值或局部极小值的方向进行收敛。
      在这里插入图片描述
    • mini-batch梯度下降
      mini-batch梯度下降算法是指在训练模型的时候,每次迭代时会使用一个mini-batch数据来计算梯度更新模型的参数,这个mini-batch通常取64、128、256、512,通常采用2^n作为一个mini-batch,符合电脑的内存结构在一定程度上可以加快计算机的计算速度,从而减少训练的时间。mini-batch梯度下降算法是最常用的梯度下降算法,mini-batch对计算机的内存要求不高,收敛速度相对较快,在迭代的时候不能保证每次迭代都像全局最小值进行收敛,但是整体的趋势是向全局最小值进行收敛的。当mini-batch取1时,就变成了随机梯度下降算法,当mini-batch的大小为整个训练数据集的大小时就变成了batch梯度下降。
      在这里插入图片描述

    二、指数加权平均值

    指数加权平均值,也被称为移动平均值,从名字可以看出来它其实也是一种求平均值的算法,在后面介绍动量、RMSProp和Adam的时候都需要用到它。

    • 指数加权平均值计算方法
      公式:vn=βvn1+(1β)θnv_{n}=\beta*v_{n-1}+(1-\beta)*\theta_{n},其中β\beta指的是系数通常取0.9,vnv_{n}表示的是当前的指数加权平均值,θ\theta表示的是当前的值,下面用一个例子来详细介绍一下指数加权平均值的计算:
      我们有一组网站的访问量数据:
      在这里插入图片描述
      其中θ\theta表示的是每天的访问量(万),下面我们来计算一下指数加权平均值,其中β\beta取0.9
      v0v_{0}=0
      v1v_{1}=βv0\beta*v_{0}+(1β)θ1(1-\beta)*\theta_{1}=0.9 * 0+ 0.1 * 5=0.5
      v2v_{2}=βv1\beta*v_{1}+(1β)θ2(1-\beta)*\theta_{2}=0.9 * 0.5+ 0.1 * 6=1.05
    • β\beta系数对于加权平均值的影响
      指数加权平均值的计算公式:vn=βvn1+(1β)θnv_{n}=\beta*v_{n-1}+(1-\beta)*\theta_{n}
      从公式可以看出,当β\beta越大时结果与上一时刻的指数加权平均值vn1v_{n-1}的相关性越大,与当前时刻θn\theta_{n}相关性越小,导致的结果就是指数加权平均值无法更好的反映当前的变化趋势,可能会导致曲线右移,曲线更平滑。如果当β\beta越小时,指数加权平均值能够及时的反映出当前的变化趋势,但是曲线的变化幅度会比较大。如下图所示
      在这里插入图片描述
      上图中,横轴表示的是天数,纵轴表示的是温度。通过上图可以发现,其中红色曲线β\beta为0.9,黄色曲线β\beta小于0.9,绿色曲线β\beta大于0.9,当β\beta越来越大时,指数加权平均值曲线会慢慢的向右移动,反映温度的变化会延时,曲线会越来平滑
      指数加权平均算法相对于直接求平均值算法的优势在于,指数加权平均值只需要极小的空间就可以计算出近似平均值,而直接使用平均值算法需要保存以前所有的数据,相对而言指数加权平均值的计算出来平均值的精度没有那么高,它是牺牲了一定的精度来换取空间和速度的。由于它在空间上具有极大的优势,所以应用范围还是很广泛。
    • 为什么叫指数加权平均值
      vn=βvn1+(1β)θn=β(βvn2+(1β)θn1)+(1β)θn=β2vn2+β(1β)θn1+(1β)θn=βnv0+βn1(1β)θ1+...+(1β)θn \begin{aligned} v_{n} &amp;= \beta*v_{n-1}+(1-\beta)*\theta_{n} \\&amp;= \beta*( \beta*v_{n-2}+(1-\beta)*\theta_{n-1})+(1-\beta)*\theta_{n} \\&amp;= \beta^2*v_{n-2} + \beta*(1-\beta)*\theta_{n-1}+(1-\beta)*\theta_{n} \\&amp;= \beta^n*v_{0}+\beta^{n-1}*(1-\beta)*\theta_{1}+...+(1-\beta)*\theta_{n} \end{aligned}
      通过上面的公式可以发现,θ\theta的权重系数呈现出一个指数的变化趋势。
      在这里插入图片描述
      在计算vnv_{n}的时候看起来好像用到了所有的θ\theta平均了之前所有的天数,实际上只平均了一部分,当系数下降到峰值(1-β)的1/e(0.3678)时可以忽略不计,其中e(2.71828)表示的是自然常数,即当权重系数小于峰值的0.3678时,就可以认为它对于结果没有影响(1ϵ)1/ϵ=1/e(1-\epsilon)^{1/\epsilon}=1/e,其中ϵ=(1β)\epsilon=(1-\beta),所以当β\beta等于0.9时,ϵ\epsilon等于0.1,所以0.9^10=1/e。所以十天以前的θ\theta的影响可以忽略不计,就相当于平均了十天的温度。
    • 偏差修正
      在使用指数加权平均算法计算的时候存在一个问题就是,刚开始使用指数加权算法计算的时候初始值都是非常小的,偏差修正就是用于修正初始值的。如果你对于初始值不太关注,就可以不用使用偏差修正
      偏差修正公式:vn=vn1βnv_{n}^{&#x27;}=\frac{v_{n}}{1-\beta^{n}}
      当n越来越大时,βn\beta^n趋于0,vn=vnv_{n}^{&#x27;}=v_{n},所以偏差修正的作用仅在n较小的时候有用,即初始化的时候。

    三、动量梯度下降算法

    动量梯度下降算法梯度下降算法的基础上做了一些优化,梯度下降算法的收敛如下图所示
    在这里插入图片描述
    其中黑点表示的是起点,红点表示的是终点。通过梯度下降算法不停的迭代,慢慢的从黑点移动到红点的位置,通过上图可以发现黑点的移动轨迹在y方向上一直存在上下波动,而这个对于黑点移动到红点的位置没有任何的帮助,反而是在浪费时间,因为我们更希望减少这种不必要的计算,加速x轴方向上的移动步伐,如下图所示
    在这里插入图片描述
    而上图正是动量梯度下降算法所追求的效果,那么它到底是如何实现的呢?

    • 梯度下降算法
      优化参数权重ww偏置bb,梯度下降算法参数更新公式如下:
      w=wαdww=w-\alpha*d{w}
      b=bαdbb=b-\alpha*d{b}
      动量梯度下降算法参数更新公式如下:
      vw=βvw+(1β)dwv_{w}=\beta*v_w+(1-\beta)*dw
      bb=βvb+(1β)dbb_b=\beta*v_b+(1-\beta)*db
      w=wαvww=w-\alpha*v_w
      b=bαvbb=b-\alpha*v_b
      上式中α\alpha表示学习率,通过上式可以发现,动量梯度下降算法在更新参数的时候并不是直接使用的梯度,它还利用到以前的梯度,具体到多少,与β\beta的大小有关,β\beta越大使用到以前的梯度越多,β\beta越小使用到以前的梯度越小。
      因为在y轴方向上梯度是有正有负的,所以均值就近似为0,即在y轴方向上不会有太大的变化。而x轴方向上的梯度都是一致的,所以能够为x轴方向上提供动量加速更新。由于动量梯度下降算法,在更新参数的时候不仅使用到了当前的梯度还使用到了以前梯度的均值作为动量,当陷入到局部极小值(梯度接近于0),在更新的时候动量梯度下降算法还可以利用以前梯度的均值来跳出局部极小值,而梯度下降算法只会陷入到局部极小值。在使用动量梯度下降算法的时候β\beta通常可以取0.9。

    四、RMSprop算法

    RMSprop算法全称root mean square prop,RMSprop算法的思想和Moment算法的思想是一致的都是通过减少在y轴方向上的抖动,加大x轴方向上的移动步长。而在实现上略有不同,Moment主要是利用累积以前的梯度来实现加速,而RMSprop算法的思想是利用梯度下降算法在y轴方向上的梯度比较大,而在x轴方向上的梯度相对较小。在进行参数更新的时候,让y轴方向上的梯度除以一个大的数,这样y轴更新的幅度就小。而x轴方向上的梯度除以一个小的数,这样x轴更新的幅度就大。从而实现了,减小了y轴方向上的更新步长,增大了x轴方向上的更新步长,使得算法能够更快的收敛。更新公式如下:
    Sdw=βSdw+(1β)dw2S_{dw}=\beta *S_{dw} +(1-\beta)*dw^2
    Sdb=βSdb+(1β)db2S_{db}=\beta * S_{db} + (1-\beta)*db^2
    w=wαdwSdw+ϵw=w-\alpha * \frac{dw}{\sqrt{S_{dw}}+\epsilon}
    b=bαdbSdb+ϵb=b-\alpha * \frac{db}{\sqrt{S_{db}}+\epsilon}
    为了避免在更新参数的时候,分母为0,所以需要在分母上加上一个极小的数ϵ\epsilon,通常取10810^{-8}dw2dw^2表示的是参数ww的梯度的平方也称为微分的平方

    五、Adam算法

    Adam算法全称Adaptive Moment Estimation,主要是结合了Moment算法和RMSprop算法。公式如下:
    vdw=0,vdb=0,Sdw=0,Sdb=0v_{dw}=0,v_{db}=0,S_{dw}=0,S_{db}=0
    vdw=β1vdw+(1β)dwv_{dw}=\beta_{1}*v_{dw}+(1-\beta)*dw
    vdb=β1bvdb+(1β)dbv_{db}=\beta_{1}b*v_{db}+(1-\beta)*db
    Sdw=βSdw+(1β)dw2S_{dw}=\beta *S_{dw} +(1-\beta)*dw^2
    Sdb=βSdb+(1β)db2S_{db}=\beta * S_{db} + (1-\beta)*db^2
    参数的更新:
    w=wαvdwSdw+ϵw=w-\alpha * \frac{v_{dw}}{\sqrt{S_{dw}}+\epsilon}
    b=bαvdbSdb+ϵb=b-\alpha * \frac{v_{db}}{\sqrt{S_{db}}+\epsilon}
    在使用指数加权平均值算法的时候,可能存在初始化的偏差比较大的情况,可以通过下面的方法进行偏差修正:
    vdw=vdw1βtv_{dw}^{&#x27;}=\frac{v_{dw}}{1-\beta^{t}}
    Sdw=Sdw1βtS_{dw}^{&#x27;}=\frac{S_{dw}}{1-\beta^{t}}
    上式中的t表示的是迭代的次数,通常情况下我们都不会太注意初始化值,因为函数收敛通常都需要迭代很多次。β1\beta_{1}指的是Moment的参数通常取0.9,β2\beta_{2}指的是RMSprop的参数,通常取0.999,ϵ\epsilon主要是用来避免分母为0的情况取10810^{-8}

    六、总结

    最后我们用两张图来比较一下算法的表现,这张图表示的是在同样的等高线的情况下各个算法的收敛情况
    在这里插入图片描述
    下面这张图表示的是不同算法在遇到鞍点时的表现
    在这里插入图片描述

    展开全文
  • 深度学习优化算法总结

    千次阅读 2018-03-14 09:40:22
    1 深度学习中的优化算法  优化算法之前讨论两个问题:  (1) 局部最小值问题  在深度学习中,最优化问题其实并不容易困在局部最小值点。在高维度空间时(如20000维),局部最小值点需要在所有维度上都取得...
  • 深度学习——优化算法

    万次阅读 2018-01-03 15:19:28
    为什么需要优化算法优化算法可以加快收敛速度(未加入优化的神经网络训练时间比加入优化后时间更短),甚至得到一个更好更小的损失函数值。优化算法能帮你快速高效地训练模型。有哪些优化算法 Mini-Batch 梯度下降 ...
  • 批量算法和小批量算法 使用小批量的原因 n个样本均值的标准差是σn√σn,其中σσ是样本值真实的标准差。分母n−−√n表明使用更多的样本来估计梯度的方法的回报是低于线性的。 另一个促使从小数目样本中获得...
  • 深度学习优化方法-AdaGrad

    万次阅读 2018-06-21 10:16:54
    “微信公众号” 梯度下降算法、随机梯度下降算法(SGD)、小批量梯度下降算法(mini-batch SGD)、动量法(momentum)、Nesterov动量法有一个共同的特点是:对于每一个参数都用相同的学习率进行更新。 但是在实际...
  • 深度学习最常用的学习算法:Adam优化算法

    万次阅读 多人点赞 2018-01-27 10:36:40
    听说你了解深度学习最常用的学习算法:Adam优化算法?-深度学习世界。深度学习常常需要大量的时间和机算资源进行训练,这也是困扰深度学习算法开发的重大原因。虽然我们可以采用分布式并行训练加速模型的学习,但所...
  • 在调整模型更新权重和偏差参数的方式时,你是否考虑过哪种优化算法能使模型产生更好且更快的效果?应该用梯度下降,随机梯度下降,还是Adam方法? 这篇文章介绍了不同优化算法之间的主要区别,以及如何选择最佳的...
  • Adam 优化算法学习率衰减、局部最优的问题
  • 激活函数、损失函数、优化函数都分别是什么?有什么作用? 下面,就以激活函数、损失函数、优化函数在神经网络中的作用,浅析一二。 利用神经网络进行分类、检测、分割等任务的关键,就是利用反向传播算法,求解...
  • hjimce算法类博文目录

    万次阅读 多人点赞 2018-07-07 12:43:32
    hjimce算法类博文目录个人博客:http://blog.csdn.net/hjimce个人qq:1393852684知乎:https://www.zhihu.com/people/huang-jin-chi-28/activities一、深度学习深度学习(七十三)pytorch学习笔记深度学习(七十二)...
  • 概述 机器学习应用包括模型构建、求解和评估,对于深度模型而言也是类似,根据... 深度学习优化算法 深度学习中的特殊策略 另外,关于更多数值优化技术可以参考。数值优化技术 深度学习优化挑战 机器学习
  • 机器学习

    千次阅读 多人点赞 2018-04-18 21:01:12
    分类算法NSGA2算法粒子群优化算法(PSO)聚类算法蚁群算法(ACO)其它算法 前沿算法 NSGA2算法前沿PSO算法差分分组算法其它算法 演化计算算法协同进化/演化python机器学习深度学习神经网络特征选择算法 ...
  • 人工智能 之 自然语言处理(NLP)算法分类总结

    万次阅读 多人点赞 2020-01-13 13:14:48
    人工智能算法大体上来说可以分类两类:基于统计的机器学习算法(Machine Learning)和深度学习算法(Deep Learning) 总的来说,在sklearn中机器学习算法大概的分类如下: 1. 纯算法类 (1).回归算法 (2)....
  • 深度学习之自适应学习率算法

    万次阅读 2018-06-08 18:29:07
    前言 神经网络研究员早就意识到学习率肯定是难以设置的超参数之一,因为它...如果我们相信方向敏感度在某种程度是轴对齐的,那么每个参数设置不同的学习率,在整个学习过程中自动适应这些学习率是有道理的。Delta-b...
  • Adam优化算法详细解析

    万次阅读 2019-05-21 18:09:51
    Adam优化算法是一种对随机梯度下降法的扩展,最近在计算机视觉和自然语言处理中广泛应用于深度学习应用。在引入该算法时,OpenAI的Diederik Kingma和多伦多大学的Jimmy Ba在他们的2015 ICLR发表了一篇名为“Adam: A ...
  • 目前来说,流行且使用较广泛的优化算法有随机梯度下降,具动量的随机梯度下降,RMSProp算法,具动量的RMSProp,AdaDelta和Adam等,以下会选择几种进行具体说明,大部分抄自《深度学习》和tensorflow官方文档。...
  • 怎样成为一名优秀的算法工程师

    万次阅读 多人点赞 2019-10-21 15:04:01
    其它机器学习、深度学习算法的全面系统讲解可以阅读《机器学习-原理、算法与应用》,清华大学出版社,雷明著,由SIGAI公众号作者倾力打造。 书的购买链接 书的勘误,优化,源代码资源 原创声明:本文为 SIGAI 原创...
1 2 3 4 5 ... 20
收藏数 124,308
精华内容 49,723
关键字:

深度学习优化算法