热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Mxnet(25):优化算法

对于深度学习问题,通常是先定义损失函数,获得损失之后在通过优化函数尽量减小损失,大多数的优化算法都是涉及最小化。要最大化也很简单只需要在目

对于深度学习问题,通常是先定义损失函数,获得损失之后在通过优化函数尽量减小损失,大多数的优化算法都是涉及最小化。要最大化也很简单只需要在目标上取反即可。

1 优化和估算

优化和深度学习本质上目标是不同的。优化的目的是最小化损失,而深度学习是根据提供的数据找到最佳模型。训练误差和泛化误差通常是不同的:优化算法的目标是损失函数,因此其优化的目的是减少训练误差。而深度学习的目的是减少泛化误差。为了实现后者除了优化函数还需要注意过拟合问题。

from d2l import mxnet as d2l
from mxnet import np, npx
import plotly.express as px
import plotly.graph_objs as go
import pandas as pd
npx.set_np()

这里定义两个函数, 期望函数fff 以及经验函数ggg。这里 ggg 不如 fff平滑因为我们只有有限的数据。

def f(x):return x*np.cos(np.pi*x)def g(x):return f(x) + 0.2 * np.cos(5*np.pi*x)

训练误差的最小值和预测误差的最小值不在一个同一个位置。

x = np.arange(0.5, 1.5, 0.01)
df = pd.DataFrame([f(x).tolist(), g(x).tolist()], index=['expected', 'empirical'], columns=x.tolist()).Tdef annotations_set():return dict(xref="x",yref="y",showarrow=True,arrowhead=2,arrowwidth=1.5,arrowcolor="#636363",bordercolor="#c7c7c7",borderwidth=2,bgcolor="#ff7f0e"
)fig = px.line(df, width=600, height=380, labels={'index':'x', 'value': 'rish'})
fig.add_annotation(x=1.1, y=-1.05, text="expected risk", ax=10, ay=-80)
fig.add_annotation( x=1, y=-1.2, text="empirical risk", ax=-90, ay=-20)
fig.update_annotations(annotations_set())
fig.show()

在这里插入图片描述

2 深度学习中的优化挑战

这里主要研究优化算法,因此关注点是对目标函数优化的性能而不是神经网络的泛化误差。大多数的目标函数很复杂,没有解析解。

优化有许多挑战点:

  • 局部最小
  • 鞍点
  • 梯度消失

2.1 局部最小值

对于目标函数 f(x)f(x)f(x),如果 f(x)f(x)f(x)xxx 的值小于在它附近的点的 f(x)f(x)f(x)值,那么 f(x)f(x)f(x) 为局部最小值。如果 f(x)f(x)f(x)xxx的值是在整个定义域中最小的值,它为 f(x)f(x)f(x) 的全局最小值。

用下面的函数距离,理解全局最小值和局部最小值:

f(x)=x⋅cos(πx)for −1.0≤x≤2.0f(x) = x \cdot \text{cos}(\pi x) \text{ for } -1.0 \leq x \leq 2.0 f(x)=xcos(πx) for 1.0x2.0

使用代码演示

x = np.arange(-1.0, 2.0, 0.01)
fig = px.line(pd.DataFrame([f(x).tolist()], index=['f(x)'], columns=x.tolist()).T , width=600, height=380, labels = {'index': 'x', 'value': 'f(x)'})
fig.add_annotation(x=1.1, y=-0.95, text="global minimum", ax=10, ay=-80)
fig.add_annotation( x=-0.3, y=-0.25, text="local minimum", ax=10, ay=40)
fig.update_annotations(annotations_set())
fig.show()

在这里插入图片描述

深度学习模型的目标函数通常具有许多个局部最小值。当优化的数值接近局部最优的时候,梯度变为0,表示最终迭代获取的数值就是局部最优解,而不是全局最优。随机梯度下降就是为了解决这个问题, 迷你批上的自然变化能够使参数偏离局部最小值。

2.2 鞍点

除了局部最小值外,鞍点是梯度消失的另一个原因。鞍点会使函数梯度消失,但是既不是全局的不是局部的。举个例子函数f(x)=x3f(x) = x^3f(x)=x3. 其一阶和二阶导数在0处为0。0处既不是局部最优也不是全局最优,但是优化还是会停止。

在这里插入图片描述

高维度的数据中鞍点更加隐藏。例如 f(x,y)=x2−y2f(x, y) = x^2 - y^2f(x,y)=x2y2。它在 (0,0)(0, 0)(0,0) 有一个鞍点。对于xxx来说它是最大的yyy值,它看起来像一个马鞍,所以称为鞍点。

x, y = np.meshgrid(np.linspace(-1.0, 1.0, 101), np.linspace(-1.0, 1.0, 101))
z = x**2 - y**2fig = go.Figure(data = go.Surface(z=z.asnumpy(), showscale=False, colorscale='IceFire'))
fig.update_layout(width = 600, height=580)
fig.add_annotation(x=0, y=0.3, text="saddle point", ax=30, ay=-60)
fig.update_annotations(annotations_set())
fig.show()

在这里插入图片描述

假设输入函数的是一个k维向量,输出位标量,因此其Hessian矩阵将具有 kkk 特征值。梯度为0时,函数的解可以为局部最小,局部最大和鞍点三种情况:

  • 当Hessian矩阵的特征值在零梯度位置都为正时,该函数有一个局部最小值
  • 当Hessian矩阵的特征值在零梯度位置都为负时,该函数有一个局部最大值
  • 当Hessian矩阵的特征值在零梯度位置有正有负,该函数有一个鞍点

简而言之,凸函数是那些Hessian特征值从不为负的函数。

2.3 梯度消失

可能遇到的最隐蔽的问题是梯度消失问题。例如,我们要最小化功能 f(x)=tanh⁡(x)f(x) = \tanh(x)f(x)=tanh(x) 并且以 x=4x = 4x=4开始。 持矢fff接近为0。进一步求导f′(x)=1−tanh⁡2(x)f'(x) = 1 - \tanh^2(x)f(x)=1tanh2(x) 其值为 f′(4)=0.0013f'(4) = 0.0013f(4)=0.0013。因此优化起初进展会很慢。这也是在使用 ReLU激活函数之前训练深度学习模型比较棘手的问题。

x = np.arange(-2.0, 5.0, 0.01)
fig = px.line(pd.DataFrame([np.tanh(x).tolist()], index=['f(x)'], columns=x.tolist()).T , width=600, height=380, labels = {'index': 'x', 'value': 'f(x)'})
fig.add_annotation(x=4, y=1, text="vanishing gradient", ax=-10, ay=80)
fig.update_annotations(annotations_set())
fig.show()

在这里插入图片描述

3. 参考

https://d2l.ai/chapter_optimization/optimization-intro.html

4. 代码

github


推荐阅读
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • Highcharts翻译系列之二十:曲线图例子(二)
    Highcharts翻译系列之二十:曲线图例子(二)代码 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了使用Spark实现低配版高斯朴素贝叶斯模型的原因和原理。随着数据量的增大,单机上运行高斯朴素贝叶斯模型会变得很慢,因此考虑使用Spark来加速运行。然而,Spark的MLlib并没有实现高斯朴素贝叶斯模型,因此需要自己动手实现。文章还介绍了朴素贝叶斯的原理和公式,并对具有多个特征和类别的模型进行了讨论。最后,作者总结了实现低配版高斯朴素贝叶斯模型的步骤。 ... [详细]
  • 我用Tkinter制作了一个图形用户界面,有两个主按钮:“开始”和“停止”。请您就如何使用“停止”按钮终止“开始”按钮为以下代码调用的已运行功能提供建议 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • Tkinter Frame容器grid布局并使用Scrollbar滚动原理
    本文介绍了如何使用Tkinter实现Frame容器的grid布局,并通过Scrollbar实现滚动效果。通过将Canvas作为父容器,使用滚动Canvas来滚动Frame,实现了在Frame中添加多个按钮,并通过Scrollbar进行滚动。同时,还介绍了更新Frame大小和绑定滚动按钮的方法,以及配置Scrollbar的相关参数。 ... [详细]
  • 广度优先遍历(BFS)算法的概述、代码实现和应用
    本文介绍了广度优先遍历(BFS)算法的概述、邻接矩阵和邻接表的代码实现,并讨论了BFS在求解最短路径或最短步数问题上的应用。以LeetCode中的934.最短的桥为例,详细阐述了BFS的具体思路和代码实现。最后,推荐了一些相关的BFS算法题目供大家练习。 ... [详细]
  • 使用Flutternewintegration_test进行示例集成测试?回答首先在dev下的p ... [详细]
  • keras归一化激活函数dropout
    激活函数:1.softmax函数在多分类中常用的激活函数,是基于逻辑回归的,常用在输出一层,将输出压缩在0~1之间,且保证所有元素和为1,表示输入值属于每个输出值的概率大小2、Si ... [详细]
author-avatar
苦蔷薇1988
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有