数学知识点
一、非线性函数
线性函数是一次函数的别称,则非线性函数即函数图像不是一条直线的函数。
非线性函数包括指数函数、幂函数、对数函数、多项式函数等等基本初等函数以及他们组成的复合函数。
二、泰勒展开式
1、泰勒公式:
泰勒公式是将一个在$x=x_0$处具有n阶导数的函数f(x)利用关于$(x-x_0)$的n次多项式来逼近函数的方法。
若函数f(x)在包含$x_0$的某个闭区间[a,b]上具有n阶导数,且在开区间(a,b)上具有(n+1)阶导数,则对闭区间[a,b]上任意一点x,成立下式:
2、泰勒展开式:
实际应用中,泰勒公式需要截断,只取有限项,一个函数的有限项的泰勒级数叫做泰勒展开式。
3、麦克劳林展开:
函数的麦克劳林展开指上面泰勒公式中$x_0$取0的情况,即是泰勒公式的特殊形式,若f(x)在x=0处n阶连续可导,则下式成立:
三、非线性优化
1、简单的线性优化
比如单变量的$y = x^2$直接使用一阶导数为0可以求出解析解。
2、复杂的线性优化
多元变量,偏导数为0求不出解析解。
复杂的非线性优化问题求解思路:
四、雅可比矩阵
又称一阶导数矩阵。
在向量分析中,雅可比矩阵是函数的一阶偏导数以一定方式排列成的矩阵。
一个n元变量组成m个方程组,那么雅克比矩阵的形状是 $m *n $。
五、海森(Hessian)矩阵
又称二阶导数矩阵。
是一个多元函数的二阶偏导数构成的方阵,描述了函数的局部曲率。
黑塞矩阵是由目标函数f在点X处的二阶偏导数组成的nxn阶对称矩阵。
海森矩阵控制了梯度更新步长:
根据泰勒展开式推导得出公式$x_{t+1} = x_{t} -H^{-1}g$, $H^{-1}$等价于一阶优化方法中的步长。
海森矩阵的正定性保证了是梯度下降的方向(特征值为正数):
$H^{-1}g=\sum_{i}^{n}{ \frac{e_{i}^Tg}{\lambda _{i}} e_{i}}$,其中$e_i$是单位特征向量,$\lambda_i$是对应特征值向量的特征值。
六、其它
1、高阶偏导数
高阶偏导数的一个例子:
有多变量函数$z=f(x,y)$,$\frac{\partial^3z}{\partial_y\partial_{x{^2}}}$表示函数z的3阶偏导数,分解步骤为:
1、先求z对y的一阶偏导$\frac{\partial z}{\partial_y}$
2、再求上一步结果$\frac{\partial z}{\partial_y}$对x的二级偏导数$\frac{\partial^2z}{\partial_y\partial_{x}}$
3、最后用上一步结果$\frac{\partial^2z}{\partial_y\partial_{x}}$求对x的三级偏导数$\frac{\partial^3z}{\partial_y\partial_{x{^2}}}$
2、正定矩阵
二阶海塞矩阵非正定时,不能保证产生方向是下降方向。
3、约束非线性优化
优化问题依据被优化函数是否有约束条件分成约束优化问题和非约束优化问题,一般遇到的都是非约束优化,使用时注意区分。
优化方法
原理
使用极限逼近的思想,以某种策略一点点改变自变量方式,逐渐逼近被优化函数的极值。
步骤如下:
假设待优化参数:$w$,目标函数:$f(w)$,初始学习率 $\alpha$。
而后,开始进行迭代优化。在每个epoch $t$:
1、计算目标函数关于当前参数的梯度:$g_t=\nabla f(w_t)$
2、根据历史梯度计算一阶动量和二阶动量:$m_t = \phi(g_1, g_2, \cdots, g_t); V_t = \psi(g_1, g_2, \cdots, g_t)$
3、计算当前时刻的下降梯度:$\eta_t = \alpha \cdot m_t / \sqrt{V_t}$
4、根据下降梯度进行更新:$w_{t+1} = w_t - \eta_t$
步骤3、4对于各个算法都是一致的,主要的差别就体现在1和2上。
第1步中的梯度$g_t$在不同优化方法中的选择是不同的,可以是一阶、二阶或者其它类型的。
第2步中的$m_t$和$V_t$都是关于历史epoch $t$ 每一步迭代对应梯度$g_t$的函数。
优化方法分类
一、按照使用的导数(Gradient)的阶不同来划分
分为一阶优化和二阶优化。
二、按照是否自适应(Adapt)学习率
分为固定学习率和自适应学习率。
三、是否使用动量(Momentum)
分为未使用动量和使用动量。
常见的优化方法
梯度下降法
原理
梯度下降是一种寻找函数极小值的方法,通过不断改变函数自变量的值来寻找函数的极小值。
问题的关键在于自变量如何变化。是变大还是变小,还是依据某个方向变动?
另外还要关注自变量变动的幅度。幅度过大可能一下子跨过某个极小值,幅度过小寻找极小值的效率又太慢。
一、梯度更新公式:
$\theta = \theta - \alpha {\frac {\partial}{\partial_\theta} J(\theta)}$
$J(\theta)$是优化函数,是一个多元方程,例如:$J(\theta) = g( \theta_0x_0+\theta_1x_1+...+\theta_nx_n)$。
$\theta$表示需要求解的参数,是一个向量。在这里要把它看成自变量,因为x代表的样本数据是已知的。
$\alpha$表示优化速率,可以人为设定,也可以算法自适应设置。
${\frac {\partial}{\partial_\theta} J(\theta)}$ 表示分别对$\theta_0...\theta_n$求偏导之后组成的导数向量。
二、公式中负号的由来:
导数代表了函数的变化率,导数为正时随着自变量增大函数增大,导数为负随着自变量增大函数变小。
所以用负号表示自变量$\theta$沿着导数的相反方向函数值是会变小的。
三、优化过程:
刚开始参数$\theta$有一个随机的初始值,设置初始值之后参数是迭代更新的。目标函数在参数$\theta$处的导数${\frac {\partial}{\partial_\theta} J(\theta)}$也会随着参数的更新而更新。
所以参数更新过程是这样的
1、用初始参数代入目标函数
2、对目标函数求导数并更新参数
3、再次求目标函数并重复2步骤
4、直至达到停止条件
每更新一次参数我们可以对比函数值较上一次的变化量,如果值很小很小,说明
我们的函数值已经在极值附近,则可以停止迭代,此时的$\theta$就是我们要求的解。
四、缺点
1、每一步的学习率 $\alpha$ 是固定的。在不同的迭代步骤无法自动选择学习率,比如根据前面累积的梯度的值来自发的控制学习率的变化。
2、每个参数的学习率都是相同的。无法根据特征在样本中出现频率来设置每个参数的学习率,没有做到根据每个参数的特点设置对应的学习率。
几种方法
批量梯度下降
每次迭代遍历全部样本数据集计算。
优点:
目标函数若为凸函数,能够保证收敛到全局最优值;若为非凸函数,能够收敛到局部最优值。
缺点:
由于每轮迭代都需要在整个数据集上计算一次,所以批量梯度下降可能非常慢。
训练数较多时,需要较大内存。
批量梯度下降不允许在线更新模型,例如新增样本实例。
适用场景:
总体数据量不大的情况。
随机梯度下降
在进行参数更新迭代时,每次更新使用的仅仅是一个样本的梯度。
优点:
算法收敛速度快。
可以在线更新。
有几率跳出一个比较差的局部最优而收敛到一个更好的局部最优甚至是全局最优。
缺点:
模型抖动比较大。
容易收敛到局部最优,并且容易被困在鞍点。
适用场景:
大数据量的情况,比如大于100k的数据量,有可能只用其中几万条或者几千条的样本,就已经将theta迭代到最优解了。
最小化每条样本的损失函数,虽然不是每次迭代得到的损失函数都向着全局最优方向, 但是大的整体的方向是向全局最优解的,最终的结果往往是在全局最优解附近。
mini-batch梯度下降
把数据分成若干个批,按批来更新参数,这样一批中的一组数据共同决定了本次梯度的方向,下降起来就不容易跑偏,减少了随机性。批的样本数与整个数据集相比小了很多,计算量也不是很大。是sgd与bgd的折中。
常见问题
一、优化算法,什么时候可以直接求导(极大似然估计)?什么时候必须用梯度下降?
数据量比较小的时候可以直接求导。
不直接求导的原因:
1、大数据量需要把所有数据代入计算,计算量大,对内存要求高。
2、复杂函数无法直接求出解析解。
3、直接求解需要矩阵的逆,但是不是所有矩阵都有逆
梯度下降每步进行更新参数,只需要计算
二、梯度上升法可以求最大值吗?
可以
三、梯度下降的停止条件?
1、大概的迭代步数,可以设置稍微大一点
2、定义两次迭代的损失函数差值,达到差值停止
四、随机梯度下降法随机体现在何处?
找出一批样本数据进行更新参数值。
某个参数值更新: 参数值=参数值-步长*参数值对应的梯度(假设函数对参数求偏导)
体现在每次参数更新(每次迭代过程)求梯度时所使用的样本范围大小(不是全量样本而是一个样本)。
动量梯度下降法(SGD with Momentum)
笔者也称之为惯性梯度下降法,更多的使用历史梯度进行参数的更新,以减少随机梯度下降“路线折来折去”浪费时间的问题。
$m_t = \beta \cdot m_{t-1} + (1-\beta )\cdot g_t$
相比SGD用$m_t$代替了$g_t$,$m_t$称为动量。
其中衰减率$\beta$的经验值一般小于等于0.9,这个量可以决定取最近历史多少次的迭代梯度(离现在越近的迭代梯度影响越大,否则影响越小)。
优化过程:
初始化$m_0$为0,设$\beta=0.9$
epoch 1:
$m_1 = 0.9 \cdot 0 + 0.1\cdot g_1$
$\theta = \theta - \alpha \cdot m_1$
epoch 2:
$m_2 = 0.9 \cdot m_1 + 0.1\cdot g_2$
$\theta = \theta - \alpha \cdot m_2$
epoch 3:
$m_3 = 0.9 \cdot m_2 + 0.1\cdot g_3$
$\theta = \theta - \alpha \cdot m_3$
$m_3$展开:
$m_3 = (0.9 \cdot {(0.9 \cdot {( 0.1\cdot g_1)} + 0.1\cdot g_2)} + 0.1\cdot g_3)$
$m_3 = 0.081 \cdot g_1 + 0.09\cdot g_2 + 0.1\cdot g_3$
可以推广到第$t$次迭代,从 $g_t$ 到$g_1$的系数是一个公比为0.9的且不断减小的等比数列。
优点:
可以不断累积上一次的梯度值。
相较于SGD,动量法可以收敛得更快,并且减少震荡。
NAG,SGD with Nesterov Acceleration
NAG算法相对于Momentum多了一个本次梯度相对上次梯度的变化量,这个变化量本质上是对目标函数二阶导的近似。
由于利用了二阶导的信息,NAG算法才会比Momentum具有更快的收敛速度。
优点:
比Momentum更快。
AdaGrad(Adaptive Gradient)
SGD及其变种以同样的学习率更新每个参数,而AdaGrad方法的学习率是根据每个参数“历史梯度下降量(笔者理解)”来确定的,学习率与参数的“历史梯度下降量”成反比。
通过控制学习率以达到对历史梯度下降少的参数进行大幅更新,并且对历史梯度下降大的参数小幅更新。
随着优化过程的进行,对于已经下降很多的变量,则减缓学习,对于还没怎么下降的变量,则保持一个较大的学习率。
这种算法实现了精细调节每个参数的效果。
$V_{t,i} = \sum\limits_{\tau=1}^{t} g_{\tau,i}^2$
$\theta_{t+1,i} = \theta_{t,i} - \frac{\alpha}{\sqrt{V_{t,i}+\xi}} \cdot g_{t,i}$
学习率$\alpha$相比SGD算法变成了$ \frac{\alpha}{\sqrt{V_{t,i}+\xi}}$
$V_{t,i}$ 表示前 $t$ 次迭代,参数 $i$ 梯度的累加平方和,用来表示历史更新中对该参数的更新的幅度呢。
$g_{t,i}$ 表示第 $t$ 次迭代,参数 $i$ 的梯度值。
$\sqrt{V_{t,i}+\xi}$ 表示第t步以前累加的梯度平方和,$\xi$是为了避免分母为0,在分母上加一个小的平滑项
优点:
1、学习的过程中自动调整学习率。
2、有利于提高稀疏梯度的学习效率。
缺点:
1、学习率单调递减,随着时间增加导致学习率不断变小导致过早收敛
2、模型学习后期由于调整学习率的分母积累的太大,导致学习率很低,提前结束训练。
AdaDelta
adadelta 是 Adagrad 的一种改进算法,解决AdaGrad单调递减的学习率变化过于激进。
不累积全部历史梯度,而是使用梯度平方的衰减平均值。
RMSProp
RMSprop 和 Adadelta 都是为了解决 Adagrad 学习率急剧下降问题的,
跟Adadelta类似。
Adam (Adaptive Momentum)
综合了动量梯度下降法(SGD with Momentum)、NAG (SGD with Nesterov Acceleration)、AdaGrad(Adaptive Gradient)三种方法的优势。
三种优秀的方法进行了组合:动量+模拟二阶+自适应参数学习率。
动量减少模型抖动,模拟二阶用来学习加速,自适应参数学习率提高稀疏梯度的学习效率。
牛顿法
原理:
利用优化函数的二阶导数即Hessian矩阵的逆矩阵替代人工设置的学习率,在梯度下降的时候可以完美的找出下降方向,在每一次迭代中,以牛顿方向为搜索方向进行更新。
$x^{(t+1)}=x^{(t)}-H_t^{-1}g_t$,推导过程详见推导
$x^{(t+1)}$指t+1次自变量值组成的向量。
$H_t^{-1}$表示二阶偏导组成的矩阵。
$g_t$表示梯度向量。
优点:
收敛速度快。
缺点:
要求函数二阶可导。
不适合大数据,求逆矩阵的时间复杂度近似 O(n3),计算代价太高。
保证不了迭代方向是下降方向(要求海塞矩阵正定,这个是个很高的要求)。
阻尼牛顿法
通过增加在得到迭代方向之后继续在该方向进行一维搜索这一步骤,解决了牛顿法迭代方向不一定是下降的问题。
原理参考【最优化】无约束优化方法-阻尼牛顿法
拟牛顿法
解决了牛顿法中的Hession矩阵H在稠密时求逆计算量大,也有可能没有逆(Hesse矩阵非正定)的问题。
相比牛顿法不含二阶导数的矩阵$U_t$替代牛顿法中的$H^{−1}_t$,然后沿搜索方向−Utgt−Utgt做一维搜索。
优化方法对比
优化方法 | 样本范围 | 几阶导数 | 引入动量 | 参数自适应 | |
---|---|---|---|---|---|
BGD | 全部 | 一阶 | 否 | 否 | |
SGD | 单个 | 一阶 | 否 | 否 | |
SGD with Momentum | 小批次 | 一阶 | 是 | 否 | |
SGD with Nesterov Acceleration | 小批次 | 一阶(模拟二阶) | 是 | 否 | |
AdaGrad(Adaptive Gradient) | 小批次 | 一阶 | 否 | 是 | |
AdaDelta/RMSProp | 小批次 | 一阶 | 否 | 是(平缓的) | |
Adam(Adaptive Momentum) | 小批次 | 一阶 | 是 | 是(平缓的) | |
Nadam (Adaptive Momentum with Nesterov) | 小批次 | 一阶(模拟二阶) | 是 | 是(平缓的) |
如何选择
如果数据是稀疏的,就用自适用方法,即 Adagrad, Adadelta, RMSprop, Adam。
RMSprop, Adadelta, Adam 在很多情况下的效果是相似的。
Adam 就是在 RMSprop 的基础上加了 bias-correction 和 momentum,
随着梯度变的稀疏,Adam 比 RMSprop 效果会好。
整体来讲,Adam 是最好的选择。
很多论文里都会用 SGD,没有 momentum 等。SGD 虽然能达到极小值,但是比其它算法用的时间长,而且可能会被困在鞍点。
如果需要更快的收敛,或者是训练更深更复杂的神经网络,需要用一种自适应的算法。
工程实战
在常见工具包中实现的优化算法
tensorflow
spark
sklearn
泰勒展开式思想和理解
到底什么是非线性优化?
高阶偏导数
海塞矩阵的特征值有什么作用,在优化中的推导
一个框架看懂优化算法之异同 SGD/AdaGrad/Adam,优化算法的套路
学习笔记13:随机梯度下降法(Stochastic gradient descent, SGD)
梯度下降(Gradient Descent)小结
动量梯度下降法
比Momentum更快:揭开Nesterov Accelerated Gradient的真面目
AdaGrad优化器-机器之心
梯度下降优化算法概述
深度学习常见的优化方法(Optimizer)总结:Adam,SGD,Momentum,AdaGard等
拟牛顿法(DFP、BFGS、L-BFGS)推导
深度学习优化器对比与实践
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。