深度学习中的优化算法

文章目录

  • 前言
  • 一、优化和深度学习
    • 1.1 优化的目标
    • 1.2 深度学习中的优化挑战
      • 1.2.1 局部最小值
      • 1.2.2 鞍点
      • 1.2.3 梯度消失
  • 二、梯度下降
    • 2.1 一维梯度下降
      • 2.1.1 学习率
    • 2.2 多元梯度下降
    • 2.3 自适应方法
      • 2.3.1 牛顿法
      • 2.3.2 其他自适应方法
  • 三、随机梯度下降
    • 3.1 随机梯度更新
    • 3.2 动态学习率
  • 四、小批量随机梯度下降
  • 五、动量法
  • 六、AdaGrad--自适应学习率
  • 七、Adam
  • 总结
  • 附录--参考资料


前言

本章我们主要讲解一下深度学习中的一些优化算法。

一、优化和深度学习

1.1 优化的目标

优化和深度学习的目标是根本不同的。前者主要关注的是最小化目标,后者则关注在给定有限数据量的情况下寻找合适的模型。

例如,训练误差和泛化误差通常不同:由于优化算法的目标函数通常是基于训练数据集的损失函数,因此优化的目标是减少训练误差。但是,深度学习(或更广义地说,统计推断)的目标是减少泛化误差。为了实现后者,除了使用优化算法来减少训练误差之外,我们还需要注意过拟合。

1.2 深度学习中的优化挑战

1.2.1 局部最小值

随着目标函数中的参数不断的迭代,目标函数的值可能陷入一个矩阵最小值,导致找不到目标函数的全局最小值。
在这里插入图片描述

在这种情况下,小批量上梯度的自然变化能够将参数从局部极小值中跳出。

1.2.2 鞍点

除了局部最小值之外,鞍点是梯度消失的另一个原因。鞍点(saddle point)是指函数的所有梯度都消失但既不是全局最小值也不是局部最小值的任何位置。

在二维情况下:
在这里插入图片描述

在三维情况下:
在这里插入图片描述
可以看到中间那个点是x方向的最小值,是y方向的最大值。

对于多维函数来说,判断一个该点是否是局部最小值、局部最大值还是鞍点。通常是通过海森矩阵的正定性来进行判断的。

一个多元函数的二阶泰勒展开式为:
f ( x ) = f ( a ) + ∑ i = 1 n f x i ( a ) ( x i − a i ) + 1 2 ∑ i = 1 n ∑ j = 1 n ( x i − a i ) ( x j − a j ) f x i x j ( a ) ] f(\mathbf{x}) = f(\mathbf{a}) + \sum_{i=1}^{n} f_{x_i}(\mathbf{a})(x_i - a_i) + \frac{1}{2} \sum_{i=1}^{n} \sum_{j=1}^{n} (x_i - a_i)(x_j - a_j) f_{x_i x_j}(\mathbf{a}) ] f(x)=f(a)+i=1nfxi(a)(xiai)+21i=1nj=1n(xiai)(xjaj)fxixj(a)]

改写成矩阵形式:
f ( x ) = f ( a ) + ( x − a ) T ▽ f ( a ) + 1 2 ( x − a ) T H ( x − a ) f(\mathbf{x}) = f(\mathbf{a}) + (\mathbf{x} - \mathbf{a})^T \bigtriangledown f(\mathbf{a}) + \frac{1}{2} (\mathbf{x} - \mathbf{a})^T \mathbf{H} (\mathbf{x} - \mathbf{a}) f(x)=f(a)+(xa)Tf(a)+21(xa)TH(xa)
其中H被称为海森矩阵。由于需要判断的点肯定是每个分量上的导数为0,所以上式可改写为:
f ( x ) = f ( a ) + 1 2 ( x − a ) T H ( x − a ) f(\mathbf{x}) = f(\mathbf{a}) + \frac{1}{2} (\mathbf{x} - \mathbf{a})^T \mathbf{H} (\mathbf{x} - \mathbf{a}) f(x)=f(a)+21(xa)TH(xa)
所以H的正定性决定了该点是什么样的点:

  • 当函数在零梯度位置处的Hessian矩阵的特征值全部为正值时,我们有该函数的局部最小值;

  • 当函数在零梯度位置处的Hessian矩阵的特征值全部为负值时,我们有该函数的局部最大值;

  • 当函数在零梯度位置处的Hessian矩阵的特征值为负值和正值时,我们有该函数的一个鞍点。

对于高维度问题,至少部分特征值为负的可能性相当高。这使得鞍点比局部最小值更有可能出现。

1.2.3 梯度消失

可能遇到的最隐蔽问题是梯度消失。导致梯度消失的一个经典原因就是激活函数的选择问题。例如tanh激活函数在两端的梯度接近于哦,导致优化将会停滞很长一段时间。
在这里插入图片描述

正如我们所看到的那样,深度学习的优化充满挑战。幸运的是,有一系列强大的算法表现良好,即使对于初学者也很容易使用。此外,没有必要找到最优解。局部最优解或其近似解仍然非常有用。

二、梯度下降

2.1 一维梯度下降

为什么梯度下降算法可以优化目标函数呢?我们可以先从一维梯度下降中观察。
首先一元函数在x点处的泰勒展开式为:
f ( x + ϵ ) = f ( x ) + ϵ f ′ ( x ) + O ( ϵ 2 ) . f(x + \epsilon) = f(x) + \epsilon f'(x) + \mathcal{O}(\epsilon^2). f(x+ϵ)=f(x)+ϵf(x)+O(ϵ2).
假设我们已知往负梯度方向可以减少f的值(这个可以去看梯度的推导),我们选择固定步长 η > 0 \eta > 0 η>0,然后取 ϵ = − η f ′ ( x ) \epsilon = -\eta f'(x) ϵ=ηf(x)。可得泰勒展开式: f ( x − η f ′ ( x ) ) = f ( x ) − η f ′ 2 ( x ) + O ( η 2 f ′ 2 ( x ) ) . f(x - \eta f'(x)) = f(x) - \eta f'^2(x) + \mathcal{O}(\eta^2 f'^2(x)). f(xηf(x))=f(x)ηf′2(x)+O(η2f′2(x)).
我们总可以找到足够小的 η \eta η使得高阶项变得无关,因此 f ( x − η f ′ ( x ) ) ⪅ f ( x ) . f(x - \eta f'(x)) \lessapprox f(x). f(xηf(x))f(x).
这时,我们使用 x ← x − η f ′ ( x ) x \leftarrow x - \eta f'(x) xxηf(x)来进行迭代x就能让f的值越来越小。

在这里插入图片描述

2.1.1 学习率

学习率(learning rate)决定目标函数能否收敛到局部最小值,以及何时收敛到最小值。这个学习率 η \eta η可由我们自己设定。

  • 如果设置过小,将导致x的更新非常慢,需要多次迭代。
    在这里插入图片描述
  • 如果设置的过大,泰勒展开式的高阶项可能会变大,导致函数的结果不来回波动,或者陷入局部最小值。
    在这里插入图片描述
    在这里插入图片描述

2.2 多元梯度下降

对于多元函数来说,它的在 x = [ x 1 , x 2 , … , x d ] ⊤ \mathbf{x} = [x_1, x_2, \ldots, x_d]^\top x=[x1,x2,,xd]的泰勒展开可以写为:
f ( x + ϵ ) = f ( x ) + ϵ ⊤ ∇ f ( x ) + O ( ∥ ϵ ∥ 2 ) . f(\mathbf{x} + \boldsymbol{\epsilon}) = f(\mathbf{x}) + \mathbf{\boldsymbol{\epsilon}}^\top \nabla f(\mathbf{x}) + \mathcal{O}(\|\boldsymbol{\epsilon}\|^2). f(x+ϵ)=f(x)+ϵf(x)+O(ϵ2).
其中梯度为: ∇ f ( x ) = [ ∂ f ( x ) ∂ x 1 , ∂ f ( x ) ∂ x 2 , … , ∂ f ( x ) ∂ x d ] ⊤ . \nabla f(\mathbf{x}) = \bigg[\frac{\partial f(\mathbf{x})}{\partial x_1}, \frac{\partial f(\mathbf{x})}{\partial x_2}, \ldots, \frac{\partial f(\mathbf{x})}{\partial x_d}\bigg]^\top. f(x)=[x1f(x),x2f(x),,xdf(x)].

我们同样可以使用 x ← x − η ∇ f ( x ) . \mathbf{x} \leftarrow \mathbf{x} - \eta \nabla f(\mathbf{x}). xxηf(x).来进行迭代。

等高图观察如下:
在这里插入图片描述

2.3 自适应方法

选择“恰到好处”的学习率 η \eta η是很棘手的。 如果我们把它选得太小,就没有什么进展;如果太大,得到的解就会振荡,甚至可能发散。
因此,我们可以考虑目标函数的值以及梯度和曲率的二阶方法,帮助我们自适应这个学习率。

2.3.1 牛顿法

一个多元函数f在x点 ϵ \epsilon ϵ领域内的泰勒展开:
f ( x + ϵ ) = f ( x ) + ϵ ⊤ ∇ f ( x ) + 1 2 ϵ ⊤ ∇ 2 f ( x ) ϵ + O ( ∥ ϵ ∥ 3 ) . f(\mathbf{x} + \boldsymbol{\epsilon}) = f(\mathbf{x}) + \boldsymbol{\epsilon}^\top \nabla f(\mathbf{x}) + \frac{1}{2} \boldsymbol{\epsilon}^\top \nabla^2 f(\mathbf{x}) \boldsymbol{\epsilon} + \mathcal{O}(\|\boldsymbol{\epsilon}\|^3). f(x+ϵ)=f(x)+ϵf(x)+21ϵ2f(x)ϵ+O(ϵ3).
我们令 H = d e f ∇ 2 f ( x ) \mathbf{H} \stackrel{\mathrm{def}}{=} \nabla^2 f(\mathbf{x}) H=def2f(x),其中 H \mathbf{H} H也被称为海森矩阵或者黑塞矩阵。

为了使得函数在这个领域内最小,我们需要令f的梯度为0,两边对 ϵ \epsilon ϵ求导,并忽略掉高阶项,得:
∇ f ( x ) + H ϵ = 0 and hence  ϵ = − H − 1 ∇ f ( x ) . \nabla f(\mathbf{x}) + \mathbf{H} \boldsymbol{\epsilon} = 0 \text{ and hence } \boldsymbol{\epsilon} = -\mathbf{H}^{-1} \nabla f(\mathbf{x}). f(x)+Hϵ=0 and hence ϵ=H1f(x).

所以我们迭代的时候直接令
x ← x − H − 1 ∇ f ( x ) x \leftarrow x -\mathbf{H}^{-1} \nabla f(\mathbf{x}) xxH1f(x)

但是我们需要注意一下,如果二阶导数为负值,即逼近曲线开头向下,f的值可能会增加。这是这个算法的致命缺陷!

这发生了惊人的错误。我们怎样才能修正它? 一种方法是用取Hessian的绝对值来修正,另一个策略是重新引入学习率。 这似乎违背了初衷,但不完全是——拥有二阶信息可以使我们在曲率较大时保持谨慎,而在目标函数较平坦时则采用较大的学习率

2.3.2 其他自适应方法

比如预处理、线搜索等。

三、随机梯度下降

3.1 随机梯度更新

在深度学习中,目标函数通常是训练数据集中每个样本的损失函数的平均值。给定n个样本的训练数据集,我们假设 f i ( x ) f_i(\mathbf{x}) fi(x)是关于索 i i i
的训练样本的损失函数,其中 x \mathbf{x} x是参数向量。然后我们得到目标函数:
f ( x ) = 1 n ∑ i = 1 n f i ( x ) . f(\mathbf{x}) = \frac{1}{n} \sum_{i = 1}^n f_i(\mathbf{x}). f(x)=n1i=1nfi(x).

可以看出反向传播的计算代价随着n线性增长,因此,当训练数据集较大时,反向传播代价高。

为了解决上述问题,我们提出了随机梯度下降(SGD)(注:我们常常把小批量梯度下降算法也称为SGD)。

随机梯度下降算法,不再计算完所有样本的损失函数再反向传播进行迭代了,而是随机抽取所有样本中的一个样本计算损失并反向传播更新参数

3.2 动态学习率

在随机梯度下降中,对学习率敏感,因此,我们可以采用动态调节学习率的方式改变学习率。以下是根据时间动态调整学习率的策略:
η ( t ) = η i if  t i ≤ t ≤ t i + 1 分段常数 η ( t ) = η 0 ⋅ e − λ t 指数衰减 η ( t ) = η 0 ⋅ ( β t + 1 ) − α 多项式衰减 \begin{split}\begin{aligned} \eta(t) & = \eta_i \text{ if } t_i \leq t \leq t_{i+1} && \text{分段常数} \\ \eta(t) & = \eta_0 \cdot e^{-\lambda t} && \text{指数衰减} \\ \eta(t) & = \eta_0 \cdot (\beta t + 1)^{-\alpha} && \text{多项式衰减} \end{aligned}\end{split} η(t)η(t)η(t)=ηi if titti+1=η0eλt=η0(βt+1)α分段常数指数衰减多项式衰减

四、小批量随机梯度下降

随机梯度下降使用完整数据集来计算梯度并更新参数, 随机梯度下降算法一次处理一个训练样本来取得进展。 二者各有利弊:每当数据非常相似时,梯度下降并不是非常“数据高效”。 而由于CPU和GPU无法充分利用向量化,随机梯度下降并不特别“计算高效”。 这暗示了两者之间可能有折中方案,这便涉及到小批量随机梯度下降(minibatch gradient descent)。

加入损失函数的最终全貌图像如下:
在这里插入图片描述
假设我们当前参数所在位置在红点:
在这里插入图片描述
如果我们考虑了所有样本的损失函数的梯度变化情况,那么它就会找到当前点的最优梯度下降方向,最终情况可能如下:
在这里插入图片描述
每次方向找的是最优的,但是计算损失函数以及计算梯度太慢。

而如果随机找一个样本就更新参数,虽然迭代速度很快,但是过于随机可能需要很多次迭代才能降低。

在这里插入图片描述

而小批量梯度下降算法就是他们的折中,可参考下面代码:

lr = 0.03
num_epochs = 3
net = linreg
loss = squared_lossfor epoch in range(num_epochs):for X, y in data_iter(batch_size, features, labels):l = loss(net(X, w, b), y)  # X和y的小批量损失# 因为l形状是(batch_size,1),而不是一个标量。l中的所有元素被加到一起,# 并以此计算关于[w,b]的梯度l.sum().backward()sgd([w, b], lr, batch_size)  # 使用参数的梯度更新参数with torch.no_grad():train_l = loss(net(features, w, b), labels)print(f'epoch {epoch + 1}, loss {float(train_l.mean()):f}')

其中 l l l是一个向量,每个元素都是小批量中每个样本的损失,在本代码中我们使用了sum累加所有损失并反向传播,那么它会对每个样本的损失函数中的每一个参数求偏导并对应加到一起,当然我们除了使用sum也可以使用平均损失函数,pytorch中的MSELoss用的就是平均损失。在迭代器中,我们还需要去除batch_size对梯度的影响。如:

def sgd(params, lr, batch_size):  #@save"""小批量随机梯度下降"""with torch.no_grad():for param in params:param -= lr * param.grad / batch_sizeparam.grad.zero_()

五、动量法

之前我们都是把所有维度的梯度同时考虑并优化,那么我们能不能在每个维度上分别做不同程度的优化呢?答案是可行的,这就是我们要讲的动量法,考虑一种“惯性”。

我们可以先考虑两个参数的梯度下降优化。

在这里插入图片描述
我们可以看到它一方向的梯度大体是对的,而另一个轴的方向波动很大。
在这里插入图片描述
我们可以用当前点的梯度方向加上上个点的梯度方向,如果当前点的一个梯度分量与上个点的对应梯度分量方向相同,就会促进这个方向的变化,如果相反则会抑制它。

而动量法这是利用了这个特性,只不过动量法是考虑了前面所有的梯度并进行加权求和,而不是仅仅考虑上一个点。
在这里插入图片描述
这里的加权是用了指数加权平均法,这个我们在批量归一化那里也有说过。举个例子:
在这里插入图片描述

六、AdaGrad–自适应学习率

AdaGrad是一种优化算法,用于训练机器学习模型。它是基于梯度下降的一种自适应学习率方法,旨在解决传统梯度下降算法中学习率难以选择的问题。

AdaGrad通过自适应地调整学习率,可以在训练过程中逐渐减小对稀疏特征的学习率,而对频繁出现特征的学习率保持较大。具体而言,它会根据每个参数的历史梯度大小来动态地调整学习率。

公式如下:

$$$$

Adagrad优化算法就是在每次使用一个 batch size 的数据进行参数更新的时候,算法计算所有参数的梯度,那么其想法就是对于每个参数,初始化一个变量 s 为 0,然后每次将该参数的梯度平方求和累加到这个变量 s 上。

Adagrad特别适合稀疏数据,所谓的稀疏数据更多的是指某个特征有或者没有,而稠密数据是指都有这些特征,具体区别是特征数值的大小。

有这样一个规律,随着维度的增加,你遇到稀疏数据的可能性越高。

AdaGrad也有一个缺点,就是它会考虑前面所有的历史梯度,这样的话可能会对当前学习率的调整不够准确。改进的方法就是使用指数加权只考虑最近的一些历史梯度。----------此方法就叫做RMSprop方法

七、Adam

我们可以结合动量法与RMSprop方法,修正动量的同时,自适应学习率。

具体公式如下:
在这里插入图片描述

总结

附录–参考资料

  1. 各种优化算法总结
  2. 可视化软件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/81548.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flutter iOS 集成使用 flutter boost

在 Flutter项目中集成完 flutter boost,并且已经使用了 flutter boost进行了路由管理,这时如果需要和iOS混合开发,这时就要到 原生端进行集成。 注意:之前建的项目必须是 Flutter module项目,并且原生项目和flutter m…

Zebec Protocol 将进军尼泊尔市场,通过 Zebec Card 推动该地区金融平等

流支付正在成为一种全新的支付形态,Zebec Protocol 作为流支付的主要推崇者,正在积极的推动该支付方案向更广泛的应用场景拓展。目前,Zebec Protocol 成功的将流支付应用在薪酬支付领域,并通过收购 WageLink 将其纳入旗下&#xf…

grpcGateway配置

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

基于 CentOS 7 构建 LVS-DR 群集以及配置nginx负载均衡

目录 一、基于 CentOS 7 构建 LVS-DR 群集 1、前期准备 1、关闭防火墙 2、安装ifconfig 3、准备四台虚拟机 2、在DS上 2.1、配置LVS虚拟IP 2.2、手工执行配置添加LVS服务并增加两台RS 2.3、查看配置 3、在RS端(第三台、第四台) 上 3.1、配置W…

校对软件助力司法公正:确保法律文书准确无误

校对软件在司法系统中的应用可以助力司法公正,确保法律文书的准确性和无误性。以下是校对软件如何发挥作用: 1.确保准确性:校对软件可以自动检查法律文书中的语法、拼写和标点等方面的错误。通过及时发现和修正这些错误,可以确保文…

CycleGAN论文解读及代码实现

paper: https://arxiv.org/pdf/1703.10593.pdf github: https://github.com/aitorzip/PyTorch-CycleGAN 1 cycleGAN 小结 网络: 生成器2个:G_A,G_B 判别器两个: D_A,D_B损失函数8个 6个生成器损失函数 2个判别器损失…

玩转graphQL

转载至酒仙桥的玩转graphQL - SecPulse.COM | 安全脉搏 前言 在测试中我发现了很多网站开始使用GraphQL技术,并且在测试中发现了其使用过程中存在的问题,那么,到底GraphQL是什么呢?了解了GraphQL后能帮助我们在渗透测试中发现哪些…

【单片机】51单片机,TLC2543,驱动程序,读取adc

TLC2543 是一款 12 位精密模数转换器 (ADC)。 1~9、11、12——AIN0~AIN10为模拟输入端; 15——CS 为片选端; 17——DIN 为串行数据输入端;(控制字输入端,用于选择转换及输出数据格式) 16——…

Unity进阶--使用PhotonServer实现服务端和客户端通信--PhotonServer(一)

文章目录 Unity进阶--使用PhotonServer实现服务端和客户端通信服务器的安装和配置添加日志客户端的配置客户端和服务器的通信Dlc 出现vscode引用不好使的时候 Unity进阶–使用PhotonServer实现服务端和客户端通信 服务器的安装和配置 Photon的地址:https://www.ph…

第八篇: K8S Prometheus Operator实现Ceph集群企业微信机器人告警

Prometheus Operator实现Ceph集群企业微信告警 实现方案 我们的k8s集群与ceph集群是部署在不同的服务器上,因此实现方案如下: (1) ceph集群开启mgr内置的exporter服务,用于获取ceph集群的metrics (2) k8s集群通过 Service Endponit Ser…

RESTful

RESTful 简介 REST(Representational State Transfer):表现层资源状态转移 ①资源 资源是一种看待服务器的方式,即,将服务器看作是由很多离散的资源组成。每个资源是服务器上可命名的抽象概念。因为资源是一种抽象概念&#xff0…

vue3获得url上的参数值

1、引入 import { useRoute } from vue-router2、获得const route useRoute() console.log(route.query.number)

el-table实现指定列合并

table传入span-method方法可以实现合并行或列,方法的参数是一个对象,里面包含当前行row、当前列column、当前行号rowIndex、当前列号columnIndex四个属性。该函数可以返回一个包含两个元素的数组,第一个元素代表rowspan,第二个元素…

HTML 初

前言 HTML的基本骨架 HTML基本骨架是构建网页的最基本的结果。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0">…

conda install 和pip install有什么区别?

本篇为分享贴&#xff0c;截图部分选自知乎&#xff0c;部分选自csdn&#xff0c;文字内容是结合自己实践进行总结。 环境引用的包在哪&#xff1f; 首先&#xff0c;一条命令&#xff1a; python -m site 这条命令可以定位引用的包在哪里 &#xff0c;当然也可以自己设置默认…

Java课题笔记~ 关于错误与异常

非检查异常(unckecked exception)&#xff1a;Error 和 RuntimeException 以及他们的子类。javac在编译时&#xff0c;不会提示和发现这样的异常&#xff0c;不要求程序员必须处理这些异常。在运行阶段&#xff0c;倘若发生Error则虚拟机几乎崩溃&#xff0c;倘若发生RuntimeEx…

mysql的主从复制和读写分离

目录 一、mysql的主从复制和读写分离的相关知识 1&#xff09;什么是读写分离? 2&#xff09;为什么要读写分离呢? 3&#xff09;什么时候要读写分离? 4&#xff09;主从复制的优点 5&#xff09;主从复制与读写分离 6&#xff09;mysql支持的复制类型 STATEMENT和r…

Maven的安装与配置(包含所有细节)

一、idea版本和maven配对 这里是很多新手都会遇到的大坑&#xff0c;一定要先将自己的idea版本和maven进行版本配配对。 Maven3.6.3版本兼容问题 注意&#xff1a;针对一些老项目 还是尽量采用 3.6.3版本&#xff0c;针对idea各个版本的兼容性就很兼容 IDEA 2022 兼容maven 3.8…

vue中vuex的五个属性和基本用法,另加js-cookie的使用

VueX 是一个专门为 Vue.js 应用设计的状态管理构架&#xff0c;统一管理和维护各个vue组件的可变化状态(你可以理解成 vue 组件里的某些 data )。 Vuex有五个核心概念&#xff1a; state, getters, mutations, actions, modules。 1. state&#xff1a; vuex的基本数据&…

HDFS中snapshot快照机制

HDFS中snapshot快照机制 介绍作用功能实现相关命令和操作相关命令 介绍 snapshot是数据存储的某一时刻的状态记录&#xff0c;备份&#xff08;backup&#xff09;则是数据存储的某一个时刻的副本HDFS snapshot快照是整个文件系统或某个目录在某个时刻的镜像&#xff0c;该镜像…