1.梯度的概念
梯度是一个矢量,表示某一函数在该点处的方向导数沿着该方向取得最大值,即函数在该点处沿着该方向变化最快。html
在微积分里面,对多元函数的参数求∂偏导数,把求得的各个参数的偏导数以向量的形式写出来,就是梯度。好比函数f(x,y), 分别对x,y求偏导数,求得的梯度向量就是(∂f/∂x, ∂f/∂y)T,简称grad f(x,y)或者▽f(x,y)。git
问 1)梯度的公式是什么?github
(要记得是极限的形式)
问 2)曲线有斜率吗?
没有,曲线上的点的切线才有斜率。曲线有梯度。算法
2.梯度降低的概念
问:为何 反方向更新?
参数的更新公式为网络
当梯度(导数)为负数的时候(降低),θ增长,即往曲线的下方移动
当梯度为正,θ减少后并以新的θ为基点从新求导,一直迭代机器学习
在不断迭代的过程当中,梯度值会不断变小,因此θ的变化速度也会愈来愈慢,因此在这里其实并不须要使学习率的值随着时间愈来愈小函数
值得注意的是步长的大小,过小,则会迭代不少次才找到最优解,若太大,可能跳过最优,从而找不到最优解。这个时候,学习率衰减就起到相当重要的做用了性能
Python 示例: @ Standford CS231n [Optimization Note](http://cs231n.github.io/optimization-1/) /** * 如下代码以基础梯度公式为例 */ def eval_numerical_gradient(f, x): """ 一个f在x处的数值梯度法的简单实现 - f是只有一个参数的函数 - x是计算梯度的点 """ fx = f(x) # 在原点计算函数值 grad = np.zeros(x.shape) h = 0.00001 # 对x中全部的索引进行迭代 it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite']) while not it.finished: # 计算x+h处的函数值 ix = it.multi_index old_value = x[ix] x[ix] = old_value + h # 增长h fxh = f(x) # 计算f(x + h) x[ix] = old_value # 存到前一个值中 (很是重要) # 计算偏导数 grad[ix] = (fxh - fx) / h # 坡度 it.iternext() # 到下个维度 return grad
该代码中h根据微分原理取值应该越小越好,建议值为1e−5左右。并且中心差值梯度效果也确定比基础梯度效果好,可是相应的计算量也会增大。学习
3.梯度降低的数学描述优化
参考:
http://www.cnblogs.com/pinard/p/5970503.html
4.随机梯度降低
假如咱们要优化一个函数 f(x),即找到它的最小值,经常使用的方法叫作 Gradient Descent (GD)。提及来很简单, 就是每次沿着当前位置的导数方向走一小步
GD 算法至少有两个明显的缺陷。
首先,在使用的时候, GD须要计算f(x)的精确导数,每每意味着咱们要花几个小时把整个数据集都扫描一遍,而后还只能走一小步,通常 GD 要很长时间才能收敛。
其次,若是咱们不当心陷入了鞍点,或者比较差的局部最优势,GD 算法就跑不出来了,由于这些点的导数是 0。什么是鞍点:鞍点是函数上的导数为零但不是轴上局部极值的点
因而Stochastic Gradient Descent (SGD) 算法被提出,解决GD的缺陷。
虽然SGD的降低方向包含必定的随机性,可是从期望上来看,它是等于正确的导数的。
因为它对导数的要求很是低,能够包含大量的噪声,只要指望正确就行,因此导数算起来很是快
除了算得快,SGD 有很是多的优良性质。它可以自动逃离鞍点,自动逃离比较差的局部最优势,并且,最后找到的答案还具备很强的通常性(generalization),即可以在本身以前没有见过可是服从一样分布的数据集上表现很是好
问:什么是鞍点?
首先,咱们考虑的状况是导数为0的点。这些点被称为 Stationary points,即稳定点。稳定点的话,能够是(局部)最小值,(局部)最大值,也能够是鞍点。如何判断呢?咱们能够计算它的 Hessian 矩阵 H。
- 若是 H 是负定的,说明全部的特征值都是负的。这时,不管往什么方向走,导数都会变负,也就是说函数值会降低。因此,这是(局部)最大值。
- 若是 H 是正定的,说明全部的特征值都是正的。这时,你不管往什么方向走,导数都会变正,也就是说函数值会上升。因此,这是(局部)最小值。
- 若是H既包含正的特征值,又包含负的特征值,那么这个稳定点就是一个鞍点。具体参照以前的图片。也就是说有些方向函数值会上升,有些方向函数值会降低。
- 虽然看起来上面已经包含了全部的状况,可是其实不是的!还有一个很是重要的状况就是 H 可能包含特征值为0的状况。这种状况下面,咱们没法判断稳定点到底属于哪一类,每每须要参照更高维的导数才行。想一想看,若是特征值是0,就说明有些方向一马平川无边无际,函数值一直不变,那咱们固然不知道是怎么回事了:)
上面第四种,是被称为退化了的状况,这里只关注前几种非退化状况。
在这种非退化的状况下面,咱们考虑一个重要的类别,即 strict saddle 函数。这种函数有这样的特色:对于每一个点 x
- 要么 x 的导数比较大
- 要么 x 的 Hessian 矩阵包含一个负的特征值
- 要么 x 已经离某一个(局部)最小值很近了
为何咱们要 x 知足这三个状况的至少一个呢?由于
- 若是 x 的导数大,那么沿着这个导数必定能够大大下降函数值(咱们对函数有光滑性假设)
- 若是 x 的 Hessian 矩阵有一个负的特征值,那么咱们经过加噪声随机扰动,跑跑就可以跑到这个方向上,沿着这个方向就可以像滑滑梯同样一路滑下去,大大下降函数值
- 若是 x 已经离某一个(局部)最小值很近了,那么咱们就完成任务了,毕竟这个世界上没有十全十美的事情,离得近和精确跑到这个点也没什么区别。
因此说,若是咱们考虑的函数知足这个 strict saddle 性质,那么 SGD 算法实际上是不会被困在鞍点的.那么 strict saddle 性质是否是一个合理的性质呢?
实际上,有大量的机器学习的问题使用的函数都知足这样的性质。好比 Orthogonal tensor decomposition,dictionary learning, matrix completion 等等。并且,其实并不用担忧最后获得的点只是一个局部最优,而不是全局最优。由于实际上人们发现大量的机器学习问题,几乎全部的局部最优是几乎同样好的,也就是说,只要找到一个局部最优势,其实就已经找到了全局最优,好比 Orthogonal tensor decomposition 就知足这样的性质,还有小马哥 NIPS16 的 best student paper 证实了 matrix completion 也知足这样的性质。我以为神经网络从某些角度来看,也是(几乎)知足的,只是不知道怎么证。
下面讨论一下证实,主要讨论一下第二篇。第一篇论文其实就是用数学的语言在说"在鞍点加扰动,可以顺着负的特征值方向滑下去"。第二篇很是有意思,我以为值得介绍一下想法。
首先,算法上有了一些改动。算法再也不是 SGD,而是跑若干步 GD,而后跑一步 SGD。固然实际上你们是不会这么用的,可是理论分析么,这么考虑没问题。何时跑 SGD 呢?只有当导数比较小,并且已经很长时间没有跑过 SGD 的时候,才会跑一次。也就是说,只有确实陷在鞍点上了,才会随机扰动一下下。
由于鞍点有负的特征值,因此只要扰动以后在这个方向上有那么一点点份量,就可以一马平川地滑下去。除非份量很是很是小的状况下才可能会继续陷在鞍点附近。换句话说,若是加了一个随机扰动,其实大几率状况下是可以逃离鞍点的!
虽然这个想法也很直观,可是要严格地证实很不容易,由于具体函数多是很复杂的,Hessian 矩阵也在不断地变化,因此要说明"扰动以后会陷在鞍点附近的几率是小几率"这件事情并不容易。
做者们采起了一个很巧妙的方法:对于负特征值的那个方向,任何两个点在这两个方向上的投影的距离只要大于 u/2,那么它们中间至少有一个点可以经过多跑几步 GD 逃离鞍点。也就是说,会持续陷在鞍点附近的点所在的区间至多只有 u 那么宽!经过计算宽度,咱们也就能够计算出几率的上届,说明大几率下这个 SGD+GD 算法可以逃离鞍点了。
5.随机梯度降低的数学描述
参考:https://www.cnblogs.com/ooon/p/5485231.html
这里贴上著名的几个动图,以示几种梯度降低法的性能差别。
(搬运自水印)
参考:
https://blog.csdn.net/u010248552/article/details/79764340
https://www.cnblogs.com/ooon/p/4947688.html
https://blog.csdn.net/u013709270/article/details/78667531