0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

PyTorch教程-12.4。随机梯度下降

jf_pJlTbmA9 来源:PyTorch 作者:PyTorch 2023-06-05 15:44 次阅读

在前面的章节中,我们一直在训练过程中使用随机梯度下降,但是没有解释它为什么有效。为了阐明它,我们刚刚在第 12.3 节中描述了梯度下降的基本原理。在本节中,我们将继续 更详细地讨论随机梯度下降。

%matplotlib inline
import math
import torch
from d2l import torch as d2l

%matplotlib inline
import math
from mxnet import np, npx
from d2l import mxnet as d2l

npx.set_np()

%matplotlib inline
import math
import tensorflow as tf
from d2l import tensorflow as d2l

12.4.1。随机梯度更新

深度学习中,目标函数通常是训练数据集中每个示例的损失函数的平均值。给定训练数据集n例子,我们假设 fi(x)是关于 index 训练样例的损失函数i, 在哪里x是参数向量。然后我们到达目标函数

(12.4.1)f(x)=1n∑i=1nfi(x).

目标函数的梯度在x被计算为

(12.4.2)∇f(x)=1n∑i=1n∇fi(x).

如果使用梯度下降,每次自变量迭代的计算成本为O(n), 线性增长 n. 因此,当训练数据集较大时,每次迭代的梯度下降代价会更高。

随机梯度下降 (SGD) 减少了每次迭代的计算成本。在随机梯度下降的每次迭代中,我们统一采样一个索引i∈{1,…,n}随机获取数据示例,并计算梯度∇fi(x)更新x:

(12.4.3)x←x−η∇fi(x),

在哪里η是学习率。我们可以看到每次迭代的计算成本从O(n) 梯度下降到常数O(1). 此外,我们要强调的是随机梯度 ∇fi(x)是完整梯度的无偏估计∇f(x)因为

(12.4.4)Ei∇fi(x)=1n∑i=1n∇fi(x)=∇f(x).

这意味着,平均而言,随机梯度是对梯度的良好估计。

现在,我们将通过向梯度添加均值为 0 和方差为 1 的随机噪声来模拟随机梯度下降,将其与梯度下降进行比较。

def f(x1, x2): # Objective function
  return x1 ** 2 + 2 * x2 ** 2

def f_grad(x1, x2): # Gradient of the objective function
  return 2 * x1, 4 * x2

def sgd(x1, x2, s1, s2, f_grad):
  g1, g2 = f_grad(x1, x2)
  # Simulate noisy gradient
  g1 += torch.normal(0.0, 1, (1,)).item()
  g2 += torch.normal(0.0, 1, (1,)).item()
  eta_t = eta * lr()
  return (x1 - eta_t * g1, x2 - eta_t * g2, 0, 0)

def constant_lr():
  return 1

eta = 0.1
lr = constant_lr # Constant learning rate
d2l.show_trace_2d(f, d2l.train_2d(sgd, steps=50, f_grad=f_grad))

epoch 50, x1: 0.014749, x2: 0.009829

poYBAGR9OS-ARqizAAD4tiLcbHE821.svg

def f(x1, x2): # Objective function
  return x1 ** 2 + 2 * x2 ** 2

def f_grad(x1, x2): # Gradient of the objective function
  return 2 * x1, 4 * x2

def sgd(x1, x2, s1, s2, f_grad):
  g1, g2 = f_grad(x1, x2)
  # Simulate noisy gradient
  g1 += np.random.normal(0.0, 1, (1,))
  g2 += np.random.normal(0.0, 1, (1,))
  eta_t = eta * lr()
  return (x1 - eta_t * g1, x2 - eta_t * g2, 0, 0)

def constant_lr():
  return 1

eta = 0.1
lr = constant_lr # Constant learning rate
d2l.show_trace_2d(f, d2l.train_2d(sgd, steps=50, f_grad=f_grad))

epoch 50, x1: -0.472513, x2: 0.110780

poYBAGR9OTKAJ2iNAAD6IEabta0377.svg

def f(x1, x2): # Objective function
  return x1 ** 2 + 2 * x2 ** 2

def f_grad(x1, x2): # Gradient of the objective function
  return 2 * x1, 4 * x2

def sgd(x1, x2, s1, s2, f_grad):
  g1, g2 = f_grad(x1, x2)
  # Simulate noisy gradient
  g1 += tf.random.normal([1], 0.0, 1)
  g2 += tf.random.normal([1], 0.0, 1)
  eta_t = eta * lr()
  return (x1 - eta_t * g1, x2 - eta_t * g2, 0, 0)

def constant_lr():
  return 1

eta = 0.1
lr = constant_lr # Constant learning rate
d2l.show_trace_2d(f, d2l.train_2d(sgd, steps=50, f_grad=f_grad))

epoch 50, x1: -0.103750, x2: 0.054715

pYYBAGR9OTSAEpZDAAD439nztSw294.svg

正如我们所见,随机梯度下降中变量的轨迹比我们在12.3 节中观察到的梯度下降中的轨迹噪声大得多。这是由于梯度的随机性。也就是说,即使我们到达最小值附近,我们仍然受到瞬时梯度注入的不确定性的影响η∇fi(x). 即使在 50 步之后,质量仍然不是很好。更糟糕的是,它不会在额外的步骤后得到改善(我们鼓励您尝试更多的步骤来确认这一点)。这给我们留下了唯一的选择:改变学习率η. 但是,如果我们选择的太小,我们最初不会取得任何有意义的进展。另一方面,如果我们选择太大,我们将得不到好的解决方案,如上所示。解决这些相互冲突的目标的唯一方法是随着优化的进行动态降低学习率。

lr这也是在step函数中加入学习率函数的原因sgd。在上面的例子中,学习率调度的任何功能都处于休眠状态,因为我们将相关lr 函数设置为常量。

12.4.2。动态学习率

更换η具有随时间变化的学习率 η(t)增加了控制优化算法收敛的复杂性。特别是,我们需要弄清楚多快 η应该腐烂。如果太快,我们将过早地停止优化。如果我们减少它太慢,我们会在优化​​上浪费太多时间。以下是一些用于调整的基本策略η随着时间的推移(我们稍后会讨论更高级的策略):

(12.4.5)η(t)=ηiifti≤t≤ti+1piecewise constantη(t)=η0⋅e−λtexponential decayη(t)=η0⋅(βt+1)−αpolynomial decay

在第一个分段常数场景中,我们降低学习率,例如,每当优化进展停滞时。这是训练深度网络的常用策略。或者,我们可以通过指数衰减更积极地减少它。不幸的是,这通常会导致在算法收敛之前过早停止。一个流行的选择是多项式衰减α=0.5. 在凸优化的情况下,有许多证据表明该比率表现良好。

让我们看看指数衰减在实践中是什么样子的。

def exponential_lr():
  # Global variable that is defined outside this function and updated inside
  global t
  t += 1
  return math.exp(-0.1 * t)

t = 1
lr = exponential_lr
d2l.show_trace_2d(f, d2l.train_2d(sgd, steps=1000, f_grad=f_grad))

epoch 1000, x1: -0.878960, x2: -0.023958

poYBAGR9OTqAIf3XAAxoo82lIjs506.svg

def exponential_lr():
  # Global variable that is defined outside this function and updated inside
  global t
  t += 1
  return math.exp(-0.1 * t)

t = 1
lr = exponential_lr
d2l.show_trace_2d(f, d2l.train_2d(sgd, steps=1000, f_grad=f_grad))

epoch 1000, x1: -0.820458, x2: 0.004701

pYYBAGR9OT-AYoJPAAx4USqd3aA901.svg

def exponential_lr():
  # Global variable that is defined outside this function and updated inside
  global t
  t += 1
  return math.exp(-0.1 * t)

t = 1
lr = exponential_lr
d2l.show_trace_2d(f, d2l.train_2d(sgd, steps=1000, f_grad=f_grad))

epoch 1000, x1: -0.798681, x2: -0.067649

poYBAGR9OUSAeAziAAxuZ3FWmec041.svg

正如预期的那样,参数的方差显着减少。然而,这是以无法收敛到最优解为代价的x=(0,0). 即使在 1000 次迭代之后,我们仍然离最佳解决方案很远。实际上,该算法根本无法收敛。另一方面,如果我们使用多项式衰减,其中学习率随步数的平方根反比衰减,则收敛仅在 50 步后变得更好。

def polynomial_lr():
  # Global variable that is defined outside this function and updated inside
  global t
  t += 1
  return (1 + 0.1 * t) ** (-0.5)

t = 1
lr = polynomial_lr
d2l.show_trace_2d(f, d2l.train_2d(sgd, steps=50, f_grad=f_grad))

epoch 50, x1: -0.060831, x2: 0.028779

pYYBAGR9OUeAdhPHAAD4_NKbjIo763.svg

def polynomial_lr():
  # Global variable that is defined outside this function and updated inside
  global t
  t += 1
  return (1 + 0.1 * t) ** (-0.5)

t = 1
lr = polynomial_lr
d2l.show_trace_2d(f, d2l.train_2d(sgd, steps=50, f_grad=f_grad))

epoch 50, x1: 0.025029, x2: 0.115820

poYBAGR9OUmAARl4AAD6bsEooro573.svg

def polynomial_lr():
  # Global variable that is defined outside this function and updated inside
  global t
  t += 1
  return (1 + 0.1 * t) ** (-0.5)

t = 1
lr = polynomial_lr
d2l.show_trace_2d(f, d2l.train_2d(sgd, steps=50, f_grad=f_grad))

epoch 50, x1: 0.280001, x2: -0.037688

pYYBAGR9OUyAY7wFAAD5ZKNBFa8832.svg

关于如何设置学习率,还有更多选择。例如,我们可以从一个小的速率开始,然后迅速上升,然后再次下降,尽管速度会更慢。我们甚至可以在更小和更大的学习率之间交替。存在多种此类时间表。现在让我们关注可以进行综合理论分析的学习率计划,即凸设置中的学习率。对于一般的非凸问题,很难获得有意义的收敛保证,因为通常最小化非线性非凸问题是 NP 难题。有关调查,请参见 Tibshirani 2015 的优秀讲义 。

12.4.3。凸目标的收敛性分析

以下针对凸目标函数的随机梯度下降的收敛分析是可选的,主要用于传达有关问题的更多直觉。我们将自己限制在最简单的证明之一(Nesterov 和 Vial,2000)。存在显着更高级的证明技术,例如,每当目标函数表现得特别好时。

假设目标函数 f(ξ,x)是凸的x 对全部ξ. 更具体地说,我们考虑随机梯度下降更新:

(12.4.6)xt+1=xt−ηt∂xf(ξt,x),

在哪里f(ξt,x)是关于训练样例的目标函数ξt 在步骤中从一些分布中提取t和x是模型参数。表示为

(12.4.7)R(x)=Eξ[f(ξ,x)]

预期的风险和R∗它的最低限度 x. 最后让x∗是最小化器(我们假设它存在于x被定义为)。在这种情况下,我们可以跟踪当前参数之间的距离xt在时间t和风险最小化 x∗看看它是否随着时间的推移而改善:

(12.4.8)‖xt+1−x∗‖2=‖xt−ηt∂xf(ξt,x)−x∗‖2=‖xt−x∗‖2+ηt2‖∂xf(ξt,x)‖2−2ηt〈xt−x∗,∂xf(ξt,x)〉.

我们假设ℓ2随机梯度范数 ∂xf(ξt,x)受一些常数的限制L, 因此我们有

(12.4.9)ηt2‖∂xf(ξt,x)‖2≤ηt2L2.

我们最感兴趣的是两者之间的距离 xt和x∗预期的变化。事实上,对于任何特定的步骤序列,距离很可能会增加,具体取决于哪个ξt我们遇到。因此我们需要绑定点积。因为对于任何凸函数f它认为 f(y)≥f(x)+〈f′(x),y−x〉 对全部x和y, 根据凸性我们有

(12.4.10)f(ξt,x∗)≥f(ξt,xt)+〈x∗−xt,∂xf(ξt,xt)〉.

将不等式(12.4.9)和 (12.4.10)代入(12.4.8)我们得到了时间参数之间距离的界限t+1如下:

(12.4.11)‖xt−x∗‖2−‖xt+1−x∗‖2≥2ηt(f(ξt,xt)−f(ξt,x∗))−ηt2L2.

这意味着只要当前损失与最优损失之间的差异大于ηtL2/2. 由于这种差异必然会收敛到零,因此学习率ηt也需要消失。

接下来我们对(12.4.11)进行期望。这产生

(12.4.12)E[‖xt−x∗‖2]−E[‖xt+1−x∗‖2]≥2ηt[E[R(xt)]−R∗]−ηt2L2.

最后一步涉及对不等式求和 t∈{1,…,T}. 由于总和望远镜并且通过删除较低的项我们获得

(12.4.13)‖x1−x∗‖2≥2(∑t=1Tηt)[E[R(xt)]−R∗]−L2∑t=1Tηt2.

请注意,我们利用了x1是给定的,因此可以放弃期望。最后定义

(12.4.14)x¯=def∑t=1Tηtxt∑t=1Tηt.

自从

(12.4.15)E(∑t=1TηtR(xt)∑t=1Tηt)=∑t=1TηtE[R(xt)]∑t=1Tηt=E[R(xt)],

由 Jensen 不等式(设置i=t, αi=ηt/∑t=1Tηt在 (12.2.3) ) 和凸性R它遵循E[R(xt)]≥E[R(x¯)], 因此

(12.4.16)∑t=1TηtE[R(xt)]≥∑t=1TηtE[R(x¯)].

将其代入不等式(12.4.13)得到边界

(12.4.17)[E[x¯]]−R∗≤r2+L2∑t=1Tηt22∑t=1Tηt,

在哪里 r2=def‖x1−x∗‖2 是参数的初始选择与最终结果之间距离的界限。简而言之,收敛速度取决于随机梯度的范数如何有界(L) 以及初始参数值离最优性有多远 (r). 请注意,边界是根据x¯而不是 xT. 这是因为x¯是优化路径的平滑版本。每当r,L, 和 T已知我们可以选择学习率 η=r/(LT). 这产生作为上限 rL/T. 也就是说,我们收敛于 rate O(1/T)到最优解。

12.4.4。随机梯度和有限样本

到目前为止,在谈到随机梯度下降时,我们玩得有点快和松了。我们假设我们绘制实例 xi,通常带有标签yi从一些分布 p(x,y)并且我们使用它以某种方式更新模型参数。特别地,对于有限的样本量,我们简单地认为离散分布 p(x,y)=1n∑i=1nδxi(x)δyi(y) 对于某些功能δxi和δyi允许我们对其执行随机梯度下降。

然而,这并不是我们所做的。在当前部分的玩具示例中,我们只是将噪声添加到其他非随机梯度中,即,我们假装有对(xi,yi). 事实证明,这是有道理的(详细讨论见习题)。更麻烦的是,在之前的所有讨论中,我们显然都没有这样做。相反,我们只对所有实例进行一次迭代。要了解为什么这样做更可取,请考虑相反的情况,即我们正在抽样n从带有替换的离散分布观察 。选择元素的概率i随机是1/n. 因此至少选择一次是

(12.4.18)P(choosei)=1−P(omiti)=1−(1−1/n)n≈1−e−1≈0.63.

类似的推理表明,恰好一次选择某个样本(即训练示例)的概率由下式给出

(12.4.19)(n1)1n(1−1n)n−1=nn−1(1−1n)n≈e−1≈0.37.

相对于无放回抽样,放回抽样会导致方差增加和数据效率降低。因此,在实践中我们执行后者(这是贯穿本书的默认选择)。最后请注意,重复通过训练数据集以不同的随机顺序遍历它。

12.4.5。概括

对于凸问题,我们可以证明,对于广泛选择的学习率,随机梯度下降将收敛到最优解。

对于深度学习,通常情况并非如此。然而,对凸问题的分析让我们对如何接近优化有了有用的认识,即逐步降低学习率,尽管不是太快。

学习率太小或太大时都会出现问题。在实践中,通常需要经过多次实验才能找到合适的学习率。

当训练数据集中有更多示例时,梯度下降的每次迭代计算成本更高,因此在这些情况下首选随机梯度下降。

随机梯度下降的最优性保证在非凸情况下通常不可用,因为需要检查的局部最小值的数量很可能是指数级的。

12.4.6。练习

试验随机梯度下降的不同学习率计划和不同的迭代次数。特别是,绘制与最佳解决方案的距离 (0,0)作为迭代次数的函数。

证明对于函数f(x1,x2)=x12+2x22 向梯度添加正常噪声相当于最小化损失函数 f(x,w)=(x1−w1)2+2(x2−w2)2 在哪里x从正态分布中提取。

当您从中采样时比较随机梯度下降的收敛性{(x1,y1),…,(xn,yn)}有更换和当您在没有更换的情况下取样时。

如果某个梯度(或者与其相关的某个坐标)始终大于所有其他梯度,您将如何更改随机梯度下降求解器?

假使,假设f(x)=x2(1+sin⁡x). 有多少局部最小值f有?你能改变吗f以这样一种方式来最小化它需要评估所有局部最小值?

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 随机梯度下降

    关注

    0

    文章

    4

    浏览量

    969
  • pytorch
    +关注

    关注

    2

    文章

    808

    浏览量

    13219
收藏 人收藏

    评论

    相关推荐

    如何更新权重实现梯度下降

    实现梯度下降
    发表于 07-15 10:09

    随机梯度估值在盲均衡算法中的影响

    该文引人随机梯度估值,在梯度向量中加入噪声成分,结合梯度估值引起的权偏差相关系数,分析其对盲均衡算法的影响.理论研究和仿真结果表明,随机
    发表于 03-07 14:41 20次下载
    <b class='flag-5'>随机</b><b class='flag-5'>梯度</b>估值在盲均衡算法中的影响

    随机并行梯度下降图像匹配方法性能研究及优化_李松洋

    随机并行梯度下降图像匹配方法性能研究及优化_李松洋
    发表于 03-14 08:00 0次下载

    机器学习:随机梯度下降和批量梯度下降算法介绍

    随机梯度下降(Stochastic gradient descent) 批量梯度下降(Batch gradient descent)
    发表于 11-28 04:00 8896次阅读
    机器学习:<b class='flag-5'>随机</b><b class='flag-5'>梯度</b><b class='flag-5'>下降</b>和批量<b class='flag-5'>梯度</b><b class='flag-5'>下降</b>算法介绍

    一文看懂常用的梯度下降算法

    编辑:祝鑫泉 一 概述 梯度下降算法( Gradient Descent Optimization )是神经网络模型训练最常用的优化算法。对于深度学习模型,基本都是采用梯度下降算法来进
    发表于 12-04 18:17 1801次阅读

    梯度下降算法及其变种:批量梯度下降,小批量梯度下降随机梯度下降

    现在我们来讨论梯度下降算法的三个变种,它们之间的主要区别在于每个学习步骤中计算梯度时使用的数据量,是对每个参数更新(学习步骤)时的梯度准确性与时间复杂度的折衷考虑。
    的头像 发表于 05-03 15:55 2.1w次阅读

    基于PyTorch的深度学习入门教程之PyTorch的自动梯度计算

    本文参考PyTorch官网的教程,分为五个基本模块来介绍PyTorch。为了避免文章过长,这五个模块分别在五篇博文中介绍。 Part1:PyTorch简单知识 Part2:PyTorch
    的头像 发表于 02-16 15:26 2028次阅读

    基于PyTorch的深度学习入门教程之PyTorch重点综合实践

    实例。该网络有一个隐含层,使用梯度下降来训练,目标是最小化网络输出和真实输出之间的欧氏距离。 目录 Tensors(张量) Warm-up:numpy PyTorch:Tensors Autograd
    的头像 发表于 02-15 10:01 1786次阅读

    基于分布式编码的同步随机梯度下降算法

    基于数据并行化的异步随机梯度下降(ASGD)算法由于需要在分布式计算节点之间频繁交换梯度数据,从而影响算法执行效率。提出基于分布式编码的同步随机
    发表于 04-27 13:56 2次下载
    基于分布式编码的同步<b class='flag-5'>随机</b><b class='flag-5'>梯度</b><b class='flag-5'>下降</b>算法

    梯度下降法在机器学习中的应用

    梯度下降法沿着梯度的反方向进行搜索,利用了函数的一阶导数信息。
    的头像 发表于 05-18 09:20 1381次阅读
    <b class='flag-5'>梯度</b><b class='flag-5'>下降</b>法在机器学习中的应用

    PyTorch教程12.4随机梯度下降

    电子发烧友网站提供《PyTorch教程12.4随机梯度下降.pdf》资料免费下载
    发表于 06-05 14:58 0次下载
    <b class='flag-5'>PyTorch</b>教程<b class='flag-5'>12.4</b>之<b class='flag-5'>随机</b><b class='flag-5'>梯度</b><b class='flag-5'>下降</b>

    PyTorch教程12.5之小批量随机梯度下降

    电子发烧友网站提供《PyTorch教程12.5之小批量随机梯度下降.pdf》资料免费下载
    发表于 06-05 15:00 0次下载
    <b class='flag-5'>PyTorch</b>教程12.5之小批量<b class='flag-5'>随机</b><b class='flag-5'>梯度</b><b class='flag-5'>下降</b>

    PyTorch教程19.3之异步随机搜索

    电子发烧友网站提供《PyTorch教程19.3之异步随机搜索.pdf》资料免费下载
    发表于 06-05 10:43 0次下载
    <b class='flag-5'>PyTorch</b>教程19.3之异步<b class='flag-5'>随机</b>搜索

    PyTorch教程22.6之随机变量

    电子发烧友网站提供《PyTorch教程22.6之随机变量.pdf》资料免费下载
    发表于 06-06 09:24 0次下载
    <b class='flag-5'>PyTorch</b>教程22.6之<b class='flag-5'>随机</b>变量

    PyTorch教程-12.5。小批量随机梯度下降

    12.4 节一次处理一个训练示例以取得进展。它们中的任何一个都有其自身的缺点。当数据非常相似时,梯度下降并不是特别有效。随机梯度
    的头像 发表于 06-05 15:44 763次阅读
    <b class='flag-5'>PyTorch</b>教程-12.5。小批量<b class='flag-5'>随机</b><b class='flag-5'>梯度</b><b class='flag-5'>下降</b>