Loading [MathJax]/extensions/TeX/AMSmath.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >梯度下降及其优化

梯度下降及其优化

作者头像
狼啸风云
修改于 2022-09-04 13:35:27
修改于 2022-09-04 13:35:27
1.7K0
举报

目录

一、梯度与方向导数

二、梯度下降

三、Jacobian和Hessian函数

四、随机梯度下降


一、梯度与方向导数

偏导数刻画了函数沿坐标轴方向的变化率,但有些时候还不能满足实际需求。为了研究函数沿着任意方向的变化率,就需要用到方向导数。

设函数 在点 的某一个邻域 内有定义。自点 引射线 ,设 轴正向到射线 的转角为 ,并设 上的另一点,且 。这里规定,逆时针方向旋转生成的角是正角 ,顺时针方向生成的角为负角 。此时,再考虑函数的增量 两点间的距离 的比值。当点沿着射线 逐渐趋近于 时,如果这个比的极限存在,则称该极限为函数 在点 沿着方向 的方向导数,记作

从定义可知,当函数 在点 的偏导数 存在时,函数 在点 沿着 轴正向 轴正向 的方向导数存在其值依次为 ,函数 沿着 轴负向 轴负方向 的方向导数也存在其值一次为 、。

如果函数 在点 处可微,那么函数在该点沿任意一个方向 的方向导数都存在,且有

其中, 轴到方向 的转角。

与方向导数有关的一个重要概念是梯度。对于二元函数而言,设函数 在平面区域 内具有一阶连续偏导数,则对于没一点 ,都可以给出一个向量 这个向量称为函数 在点 的梯度,记作 ,或符号 ,即 需要说明的是, 是一个偏微分算子,它又称为哈密尔顿算子(Hamilton)算子,它定义为:

或写成

求一个函数 的梯度,就可以看成是将哈密尔顿算子与函数 做乘法,即 。可见对一个函数求梯度,其实是从一个标量得到一个矢量的过程。

如果设 是与方向 同方向的单位向量,则由方向单数的计算公式可知

这里 表示向量 的夹角。由此可见,方向导数就是梯度在 上的投影,当方向 与梯度方向一致时,有 从而方向导数有最大值。所以,沿着梯度方向的方向导数达到最大值,也就是说梯度方向是函数 在这点增长最快的方向。从梯度的定义中可知,梯度的模为

总而言之,函数在某点的梯度是这样一个向量,它的方向与方向导数取得最大值的方向一致,而它的模为方向导数的最大值。

二、梯度下降

大多数深度学习算法都涉及某种形式的优化。优化指的是改变x以最小化或最大化某个函数f(x)的任务。通常以最小化f(x)指代大多数优化稳如。最大化可以经由最小化 来实现。

我们把要最小化或最大化的函数称为目标函数(object function)或准则(criterion)。当我们对其进行最小化是时,也把它称为代价函数(cost function)、损失函数(loss function)。

假设有一个函数 ,其中 都是实数。这个函数的导数(derivation)记为 。导数 代表 在点 出的斜率。换句话说,它表明如何缩放输入的小变化才能在输出获得相应的变化:

因此导数对于最小化一个函数很有用,因为它告诉我们如何更改 来略微地改善 。例如,我们知道对于足够小的 来说, 是比 小的。因此我们可以将往梯度的方向移动一小步来减少 。这种技术称为梯度下降(gradient descent)。

小于0时,导数无法提供往哪个方向移动的信息。f'(x)=0的点称为临界点(critical point)或驻点(stationary point)。一个局部极小点(local minimum)意味着这个点的f(x)小于所有邻近点,因此不可能通过移动无穷小的步长来减小f(x)。一个局部极大值点(local maximum)意味着这个点的f(x)大于所有邻近点,因此不可能通过移动无穷小的步长来增大f(x)。有些临界点既不是最小点也不是最大点,这些点称为鞍点(saddle point)

使f(x)取得绝对的最小值(相对所有其他值)的点是全局最小点(global minimum)。函数可能只有一个全局最小点或存在多个全局最小点,还可能存在不是全局最优的局部极小值点。在深度学习的背景下,我们要优化的函数可能包含许多不是最优的局部极小点,或者还有很多处于非常平摊的区域内的鞍点。尤其当输入时多维的时候,所有这些都将使优化变得困难。因此,我们通常寻找使f非常小的点,但这在任何形式意义下并不一定最小。

我么经常使用最小化具有多维输入的函数: 。为了使“最小化”的概念有意义,输出必须是一维的(标量)。

针对具有多维输入的函数,我们需要用到偏导数(partial derivation)的概念。偏导数 衡量点处只有 增加时如何变化。梯度(gradient)是相对一个向量求导的导数:f的梯度是包含所有偏导数的向量,记为 。梯度的第个元素时关于 的导数。在多维情况下,临界点是梯度中所有元素都为零的点。

(单位向量)方向的方向导数(directional derivation)是函数方向的斜率。换句话说,方向导数是函数 关于 的导数(在 时取得)。使用链式法则,我们可以看到当 时,

为了最小化,我们希望找到使下降最快的方向。计算方向导数: 其中与梯度的夹角。将 代入,并忽略与u无关的项,就能简化得到 。这在u与梯度方向相反时取得最小值。换句话说,梯度向量指向上坡,负梯度方向指向下坡。我们在负梯度方向上移动可以减少f。这被称为最速梯度下降法(method of steepest descent)或梯度下降(gradient descent)。

最速下降建议新的点为 其中 为学习率(learning rate),是一个确定步长大小的正标量。可以通过集中不同的方式选择 。普遍的方式是选择一个小常数。有时我们通过计算,选择使用方向导数消失的步长。还有一种方法是根据几个 计算 ,并选择其中能产生最小目标函数值的 。这种策略称为在线搜索。

最速梯度下降在梯度的每一个元素为零时收敛(或在实践中,很接近零时)。在某些情况下,我么也许能够避免运行该迭代算法,并通过解方程 直接跳到临界点。

虽然最速梯度下降限制在连续空间中的优化问题,但不断向更好的情况移动一小步(即邻近最佳的小移动)的一般概念可以推广到离散空间。递增带有离散参数的目标函数称为爬山(hill climbing)算法。

三、Jacobian和Hessian函数

有时我们需要计算输入和输出都为向量的函数的所有偏导数。包含所有这样的偏导数的矩阵被称为Jacobian矩阵。具体来说,如果,我们有一个函数fJacobian矩阵JRn×m 定义为Ji,j=f(x)ixj

有时也会导数的导数感兴趣,即二阶导数(second derivative)。例如,有一个函数f:RmRf的一阶导数(关于xj)关于xi 的导数记为2fxixj 。在一维情况下,可以将 。二阶导数告诉我们,一阶导数将如何随着输入的变化而变化。它表示只基于梯度信息下降步骤是否会产生我们预期的那样大的改善,因此它是重要的。我们可以认为,二阶导数是对曲率的衡量。假设我们有一个二次函数(虽然很多实践中的函数都可以认为,二阶导数至少在局部可以很好地用二次近似),如果这样的函数具有零二阶导数,那就没有曲率,也就是一条完全平坦的线,仅用梯度就可以预测它的值。我么使用沿负梯度方向大小为 的下降步,当该梯度是1时,代价函数将下降 。如果二阶导数是负的,函数曲线向下凹陷(向上凸出),因此代价函数将下降的比 多。如果二阶导数是正的,函数曲线是向上凹陷(向下凸出),因此代价函数将下降得比 少。

当我们的函数具有多维输入时,二阶导数也有很多。我们可以将这些导数合并成一个矩阵,称为Hessian矩阵。Hessian矩阵H(f)x定义为:

Hessian矩阵等价于梯度的Jacobian矩阵。

微分算子在任何二阶偏导数连续的点处可交换,也就是它们的顺序可以互换:

这意味着 ,因此Hessian矩阵在这些点上是对称的。在深度学习背景下,我们遇到的大多数函数的Hessian矩阵几乎处处都是对称的。因为Hessian矩阵是实对称的,我们可以将其分解成一组是特征值和一组特征向量的正交基。在特定方向d上的二阶导数可以写成 。当d时H的一个特征向量时,这个方向的二阶导数就是对应的特征值。对于其他方向d,方向的二阶导数是所有特征值的加权平均,权重在0到1之间,且与d夹角越小的特征向量的权重越大。最大特征值确定最大二阶导数,最小特征值确定最小二阶导数。

我们可以通过(方向)二阶导数预期一个梯度下降步骤能表现得多好。我们在当前点 处做函数的近似二阶泰勒级数:

其中是梯度, 点的。如果我们使用学习率 ,那么新的点 将会是 。代入上述的近似,可得

其中有3项:函数的原始值,函数斜率导致的预期改善和函数曲率导致的校正。当最后一项太大时,梯度下降实际上是可能向上移动的。当 为正时,通过计算可得,使近似泰勒级数下降最多的最优步长为:

最坏的情况下,最大特征值 对应的特征向量对齐,则最优步长是 。当我们要最小化的函数能用二次函数很好地近似的情况下,Hessian的特征值决定了学习率的量级。

二阶导数还可以用于确定一个临界点是都是局部极大点、局部极小点或鞍点。回想一下,在临界点处 。而 意味着f'(x)会随着我们移向右边而增加,移向左边而减小,也就是 对足够小的 成立。换句话说,当我们移向右边,斜率开始指向右边的上坡;当我们移向左边,斜率开始指向左边的上坡。因此我们得出结论,当 时,是一个局部极小值点。同理,当 时,是一个局部极大点。这就是所谓的二阶导数测试。不幸的是,当 时,测试是不确定的。在这种情况下,x可以是一个鞍点或平坦区域的一部分。

在多维情况下,我们需要检测函数的所有二阶导数。利用Hessian的特征分解,我们可以将二阶导数测试扩展到多维情况。在临界点处( ),我们通过检测Hessian的特征值来判断该临界点是一个局部极大值点、局部极小值点还是鞍点。当Hessian是正定的(所有特征值都是正的),则该临界点是局部极小点。因为方向二阶导数在任意方向都是正的,参考单变量的二阶导数测试就能得出此结论。同样的,当Hessian时负定的(所有特征值都是负的),这个点就是局部极大点。在多维情况下,实际上我么可以找到确定该点是否为鞍点的积极迹象(某些情况下)。如果Hessian的特征值中至少有一个是正的且至少一个是负的,那么x是f某个截面的局部极大点,却是另一个截面的局部极小点。最后,多维二阶导数测试可能像单变量版本那样是不确定的。当所有非零特征值是同号的且至少有一个特征值是0时,这个函数就是不确定的。这是因为单变量的二阶导数测试在零特征值对应的横截面上是不确定的。

多维情况下,单个点处每个方向上的二阶导数是不同的。Hessian的条件数衡量这些二阶导数的变化范围。当Hessian的条件数很差时,梯度下降法也会表现得很差,这是因为一个方向上的导数增加得很快,而在另一个方向上的增加得很慢。梯度下降不知道导数的这种变化,所以它不知道应该优化探索导数长期为负的方向。病态条件也导致很难选择适合的步长。步长必须足够小,以免冲过最小而向具有较强正曲率的方向上升。这通常意味着步长太小,以至于在其他较小曲率的方向上进展不明显。

可以使用Hessian矩阵的信息来指导搜索,以解决这个问题。其中最简单的方法是牛顿法(Newton's method)。牛顿法基于一个二阶泰勒展开来近似 附近的

接着通过计算,可以得到这个函数的临界点:

如果是一个正定二次函数,牛顿法只要应用一次就能直接跳到函数的最小点。如果f不是一个真正二次但能在局部近似为正定二次,牛顿法则需多次迭代。迭代地更新近似函数和跳到近似函数的最小点可以比梯度下降更快地到达临界点。这在接近局部极小值点时是一个特别有用的性质,但是在鞍点附近是有害的。仅使用梯度信息的优化算法称为一阶优化算法,如梯度下降。使用Hessian矩阵的优化算法称为二阶最优化算法。

四、随机梯度下降

梯度下降沿着整个数据集的梯度方向下降,这可以使用随机梯度下降很大程度地加速。

随机梯度下降(SGD)及其变种很可能是一般机器学习中应用最多的优化算法,特别是在深度学习中。按照数据分布生成抽取m个小批量(独立同分布的)样本,通过计算它们的梯度均值,我们可以得到梯度的无偏估计,下面是梯度随机梯度下降的伪代码:

Require: 学习率 Require: 初始化参数 while 停止准则为满足 do 从训练集中采包含m个样本 的小批量,其中 对应的目标函数为 计算梯度估计:

应用更新:

end while

SGD算法中一个关键参数是学习率。之前,我们介绍的SGD使用固定的学习率。在实践中,有必要随着时间的推移逐渐降低学习率,因此我们将第k步迭代的学习率记作

这是因为SGD中梯度估计引入了噪声源(m个训练样本的随机采样)并不会在极小点处消失。相比之下,当我们使用批量梯度下降达到极小点时,整个代价函数的真实梯度会变得很小,之后为0,因为批量梯度下降可以使用固定的学习率。保证SGD收敛的一个充分条件是 实践中,一般会线性衰减学习率直到第 次迭代:

其中 。在 不迭代之后,一般使 保持常数。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019年07月18日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
有意思的数据可视化案例:R语言ggplot2画山脊图展示NBA球员出手距离的分布
主要内容是探索了NBA 14/15赛季常规赛MVP排行榜前四名 库里 哈登 詹姆斯 威少的投篮数据。今天重复第一个内容:用R语言的ggplot2画山脊图展示以上四人的投篮出手距离的分布。
用户7010445
2021/02/05
8850
R语言ggplot2堆积柱形图添加误差线的简单小例子
最近有人在公众号后台留言问到这个问题,今天的推文介绍一下ggplot2做堆积柱形图并添加误差线的办法 完整代码 ''' 堆积柱形图添加误差线 ''' getwd() library(ggplot2) library(dplyr) library(see) df<-read.csv("penguins.csv") head(df) df %>% na.omit() %>% group_by(species,sex) %>% summarise(mean_value=mean(bill_le
用户7010445
2021/08/31
4.1K0
R语言ggplot2堆积柱形图添加误差线的简单小例子
R语言ggplot2画分组堆积柱形图展示密码子偏向性的RSCU值
之前录制视频介绍过如何绘制堆积柱形图展示密码子偏向性的内容,但是之前的内容只能画一组堆积柱形图,如果你有好几个物种想要画到一起,可能比较麻烦,我记录一些我自己的画图代码
用户7010445
2021/07/12
3.1K0
R语言ggplot2画分组堆积柱形图展示密码子偏向性的RSCU值
R语言ggplot2分组箱线图添加误差线的简单小例子
这样多了一个垂直线,不好看,我们把误差线的图层放到最下层,就是把代码写到boxplot的前面,然后加一些基本的美化
用户7010445
2021/10/13
5.5K0
跟着PNAS学数据分析:泛基因组(pan-genome)分析核心基因组可变基因组大小
https://github.com/AnimalGenomicsETH/bovine-graphs/tree/main
用户7010445
2023/12/19
4.6K3
跟着PNAS学数据分析:泛基因组(pan-genome)分析核心基因组可变基因组大小
全网最全的R语言基础图形合集
直方图是一种对数据分布情况进行可视化的图形,它是二维统计图表,对应两个坐标分别是统计样本以及该样本对应的某个属性如频率等度量。
生信学习者
2024/06/12
1220
全网最全的R语言基础图形合集
跟着BMC genomics学作图:R语言ggplot2+ggtree进化树拼接三角热图
这里新学到的一个知识点是拼图的时候可以使用plot_spacer()函数占据一个空白位置
用户7010445
2021/10/25
1.9K0
R语言ggplot2画热图添加分组信息的颜色条
之前有人在公众号留言问文章开头这幅图如何实现,下面的B图是折线图加柱形图,相对比较容易实现,上面的A图稍微有点复杂,我想到的办法是拼图,图A可以看成三个热图,然后加一个堆积柱形图,最后将四个图组合到一起。那就按照这个思路试一下看能不能实现。 最初的想法是左侧的颜色条用堆积柱形图来实现,又看了一遍Y叔公众号关于aplot这个包的推文,发现他是用geom_tile()函数实现的,仔细想想还是geom_tile()函数实现起来比较方便。 首先解决昨天的遗留问题:ggplot2画图添加文字内容的时候如何添加下划线
用户7010445
2021/01/06
5.4K0
跟着Nature Genetics学画图:R语言ggbio包画基因结构图
(示例数据和代码可以在今天推文次条的广告文案留言处获得下载链接,哈哈哈哈 想到了一个提高广告阅读量的好办法 哈哈哈 )
用户7010445
2021/07/12
3.5K2
跟着Nature Genetics学画图:R语言ggbio包画基因结构图
ggplot2分组条形图饼图箱线图
写在最后:有时间我们会努力更新的。大家互动交流可以前去论坛,地址在下面,复制去浏览器即可访问,弥补下公众号没有留言功能的缺憾。
生信喵实验柴
2022/10/25
8940
ggplot2分组条形图饼图箱线图
跟着Nature microbiology学画图~ggplot2散点图添加分组边界
添加分组边界主要参考了文章 https://chrischizinski.github.io/rstats/vegan-ggplot2/
用户7010445
2021/01/06
1.3K0
跟着Nature microbiology学画图~ggplot2散点图添加分组边界
R语言ggplot2给PCA散点图结果上添加水平和垂直误差线
公众号后台有读者留言问这个图的实现办法,这个图相比于普通的PCA散点图是多了一个垂直和水平的误差线,这个如何实现之前还没有尝试过,所以查了查资料,找到了一个参考链接
用户7010445
2021/11/08
1.1K0
看篮球学R语言:卢卡东契奇到底有多棒?
https://www.kaggle.com/xvivancos/how-good-is-luka-doncic
用户7010445
2020/08/28
6420
看篮球学R语言:卢卡东契奇到底有多棒?
跟着Science学画图:R语言ggplot2实现图中嵌图
部分数据代码是公开的 下载链接https://zenodo.org/record/4781590#.YSB40Hzivic
用户7010445
2021/10/13
1.4K0
R语言ggplot2做箱线图的时候如何添加表示平均值的线
箱线图展示的就是分位数,中间的线表示的是中位数,也就是50%分位数,如果非要在箱线图上画上表示平均值的线段也是可以实现的,今天介绍一下实现代码
用户7010445
2021/10/13
6.8K0
跟着Science Advances学画图:R语言ggplot2画图如何让坐标轴以科学计数法显示
今天的推文是昨天推文的延续 跟着Science Advances学画图:R语言ggplot2画柱形图如何让屁股朝右。在昨天的推文中模仿了论文 Landscapes of bacterial and metabolic signatures and their interaction in major depressive disorders中的 figure2B image.png image.png 但是有一个细节没有能够实现,就是让坐标轴以上图样子的科学计数法显示,昨天的推文发出后有读者留言了对应的
用户7010445
2021/03/26
2.9K0
跟着Science Advances学画图:R语言ggplot2画图如何让坐标轴以科学计数法显示
跟着Nature microbiology学画图~箱线图放到频率分布直方图的右上角
频率分布直方图之前的推文有过详细的介绍,点击下方蓝字直达,这里的代码就不再过多介绍
用户7010445
2021/01/06
8000
R语言ggplot2画小提琴图展示库里哈登詹姆斯微少爷命中率
本篇推文的主要内容来自于 https://nycdatascience.com/blog/student-works/nba-shot-log/,主要内容是探索14-15赛季NBA篮球运动员 库里、哈
用户7010445
2021/02/05
3260
ggplot2散点图直方图条形图
熟悉ggplot2绘图,有一本书,可以介绍大家使用,《R数据可视化手册》第二版
生信喵实验柴
2022/10/25
6050
ggplot2散点图直方图条形图
跟着Nature Genetics 学画图:R语言ggplot2一次性画好多个饼状图
最基本的想法就是单独画好多个饼状图,然后通过拼图实现,但是因为之前重复地图的时候新遇到了一个包是 scattermore可以直接指定输入数据,然后一次性将所有饼状图画好,这样就省去了拼图的步骤
用户7010445
2021/05/07
2.6K0
推荐阅读
相关推荐
有意思的数据可视化案例:R语言ggplot2画山脊图展示NBA球员出手距离的分布
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档