当前位置: 首页 > news >正文

优化算法

目录

1  Mini-batch梯度下降

2  理解Mini-batch梯度下降法

3  指数加权平均值

4  了解指数加权平均数

5  指数加权平均数的偏差校正

6  Momentum梯度下降法

7  RMSprop

8  Adam优化算法

09  学习率衰减

10  局部最优化问题


1  Mini-batch梯度下降

        如果对整个训练数据集进行训练,采用梯度下降法的训练速度会很慢。你可以将训练集拆分成很小的训练集,即小批量训练集(Mini-batch)。

        这个算法每次只处理一个小批量样例X^{\begin{Bmatrix} t \end{Bmatrix}},Y^{\begin{Bmatrix} t \end{Bmatrix}}.

        假设我们有500万条训练样本,也就是我们有5000个训练子集,每个子集1000个训练样本,在训练集上运行小批量梯度下降算法时候,每个子集都要运行一遍。

for t=1,2,...,5000:

        前向传播:z^{[1]}=W^{[1]}X^{\begin{Bmatrix} t \end{Bmatrix}}+b^{[1]}

                        A^{[1]}=g^{[1]}(z^{[1]})

                        ............

                        A^{[L]}=g^{[L]}(z^{[L]})

        计算代价函数:J^{\begin{Bmatrix} t \end{Bmatrix}}=\frac{1}{1000}\sum_{j=1}^{1000}L(\hat{y^{(j)},y^{(j)}})+\frac{\lambda }{2000}\sum_{k=1}^{L}||W^{[L]}||^{2}

        反向传播计算J^{\begin{Bmatrix} t \end{Bmatrix}}的梯度,更新权重

        上述的称为训练集的一次遍历,使用批梯度下降法的一次遍历训练集只能让你做一次梯度下降,而使用Mini-batch梯度下降法,一次遍历训练集嫩能够让你做5000次(对于本例)梯度下降。你想要多轮遍历训练集,你可以在上面的for循环外,再增加一个循环,直到最后你能收敛到一个合适的值。

2  理解Mini-batch梯度下降法

        在批量梯度下降算法中,每一次迭代你都要遍历整个训练集,并希望代价函数的值随着迭代次数的增加而不断减少;如果代价函数的值在某次迭代中增加了,则说明出现了错误,也许是学习率太大了。

        使用Mini-batch梯度下降法,如果你做出代价函数在整个过程中的图,你会发现并不是每次迭代都是下降的,特别是在每次迭代过程中,因为你是对不同的训练集进行迭代。

        你需要决定的变量之一是Mini-batch的大小,假设训练集的大小为m。极端情况下,如果Mini-batch的大小等于m,此时就是batch梯度下降法;如果Mini-batch的大小=1,此时就是随机梯度下降法,每个样本都是独立的Mini-batch。        

        batch梯度下降从某一点处开始,相对噪声低一些,幅度也大一些;而在随机梯度下降算法中,每次只对一个样本进行迭代,有时向着全局最小值靠近,有时由于这组数据不好会往错误方向移动,远离最小值,因此随机梯度下降有很多噪声。一般来说,它会沿着正确方向靠近最小值,而且随机梯度下降不会收敛到某个最小值,而是在最小值附近波动。

        如果使用batch梯度下降法,Mini-batch的大小为m,每次迭代需要大量训练样本,该算法的主要弊端是:在训练样本数量巨大的时候,单次迭代耗时太长;如果训练样本不大,batch梯度下降法能很好地运行。如果使用随机梯度下降法,如果你只要处理一个样本,那这个方法很好,通过减小学习率,噪声会被减小,但是随机梯度下降算法的缺点是:失去了使用向量化加速运算的机会。        

        通常,我们选择的Mini-batch大小在1和m之间,让Mini-batch大小既不太大也不太小,这样你的训练才能最快,既可以使用向量的方式运算;也可以不用等待整个训练集都遍历完一遍再运行梯度下降法,虽然并不能保证总是到达最小值,但是相比随机梯度下降,它总是朝着最小值的方向移动,而且不会总在最小值附近摆动。

        训练集小(≤2000),就使用batch梯度下降算法;对于大的训练集,一般选64到512作为Mini-batch的大小。

        确保Mini-batch的训练集是可以放进CPU/GPU内存。

3  指数加权平均值

        以伦敦某年的每日气温作为例子,把每日气温的数据画出来,得到下面的图:

        这些数据看起来有噪声,如果你想要计算数据的趋势,你可以这样做:

先令v_{0}=0,之后每一天先用0.9乘以之前的v值再加上0.1乘以当天的气温。v_{1}=0.9v_{0}+0.1\theta _{1},第二天仍然使用加权平均,即v_{2}=0.9v_{1}+0.1\theta _{2}v_{3}=0.9v_{2}+0.1\theta _{3}  。

        如果这样计算,并把结果用红色画出来,你就会得到一个滑动平均的图,称为每日温度的指数加权平均。

        通用公式:v_{t}=\beta v_{t-1}+(1-\beta )\theta _{t},对于这个公式,你可以认为v_{t}近似于\frac{1}{1-\beta }天的温度平均。举例来说,当\beta =0.9时,你可以认为这是前十天的气温平均值。

        当\beta =0.98时,这时计算\frac{1}{1-0.98 }=50,这相当于粗略计算了前50天的气温平均值,如果你把它画出来,就会得到绿色的线。 

        有几点需要注意的是:当\beta值很大时,你得到的曲线就会更平滑,因为你对更多天数的气温做了平均处理,因此曲线波动更小、更加平滑;另一方面,这个曲线会右移,因为你在一个更大的窗口内计算平均气温,这个指数加权平均在温度变化时,适应的更加缓慢,这就造成了一定的延迟,使得之前的值具有更大的权重,而当前值的权重非常小。 

        当\beta =0.5,这就是只对两天进行平均,如果画出来,就会得到黄色的线。由于仅仅平均两天的温度,即只在很小的窗口内计算平均,得到的结果就会有很多噪声,更容易受到异常值的影响,但它可以更快的适应温度的变化。

       使用公式:v_{t}=\beta v_{t-1}+(1-\beta )\theta _{t} 可以实现指数加权平均,在统计学中,它被称为指数加权移动平均。通过调整\beta值,可以得到不同的效果。

4  了解指数加权平均数

        在这里假设\beta =0.9,我们来了解下v_{t}=\beta v_{t-1}+(1-\beta )\theta _{t}是如何计算每日气温的。

        以t减小的的方式写出v值的计算:

       v_{100}=0.1\theta _{100}+0.9v_{99}

        v_{100}=0.1\theta _{100}+0.9(0.1\theta _{99}+0.9v_{98})

        v_{100}=0.1\theta _{100}+0.9(0.1\theta _{99}+0.9(0.1\theta _{98}+0.9v_{97}))

        ............

        以此类推,将这些项全部相乘就可以得到:

v_{100}=0.1\theta _{100}+0.1*0.9\theta _{99}+0.1*(0.9)^{2}\theta _{98}+...+0.1*(0.9)^{99}\theta _{1}

        左图是t从1到100时,所对应的\theta _{t}天的气温,右图是构建的一个指数衰减函数,也就是0.1,0.1*0.9,0.1*(0.9)^{2},计算v_{100}是通过把两个函数对应的元素相乘,然后求和。

        所有的系数相加为1或者逼近1,涉及下面要讲的偏差修正。

        最后你也许会问,到底需要平均多少天的温度。实际上有(1-\epsilon )^{\frac{1}{\epsilon }}=\frac{1}{e},从而0.9^{10}\approx 0.35\approx \frac{1}{e}。这个含义是:10天后,权重下降到当日权重的\frac{1}{e},权重可以忽略不计 。

5  指数加权平均数的偏差校正

        把\beta =0.98代入v_{t}=\beta v_{t-1}+(1-\beta )\theta _{t},实际得到的是紫色曲线而不是绿色曲线。 你会发现,紫色曲线的起点非常低。 

       当计算移动平均值的时候,初始化v_{0}=0v_{1}=0.98v_{0}+0.02\theta _{1},如果第一天的气温是40华氏度,那么v_{1}=0.8,因此得到的值会小很多,所以第一天的气温预估不准确。

        v_{2}=0.98v_{1}+0.02\theta _{2}=0.98*0.02\theta _{1}+0.02\theta _{2}=0.0196\theta _{1}+0.02\theta _{2},计算后v_{2}的值要远小于\theta _{1}\theta _{2},所以v_{2}不能很好的预估前2天的气温。

        有一种方法能很好的预估:用\frac{V_{t}}{1-\beta ^{t}}代替v_{t}.当t=2时,1-\beta ^{t}=1-(0.98)^{2}=0.0396。因此第二天的气温估计值\frac{V_{2}}{0.0396}=\frac{0.0196\theta _{1}+0.02\theta _{2}}{0.0396}。当t值变大,\beta^{t}的值将趋向于0,即偏差修正值对运算基本没有影响。

6  Momentum梯度下降法

        有一种算法叫做动量(Momentum),或者叫做动量梯度下降法,它总是会比标准的梯度下降法更快。动量梯度下降法的算法思想是:计算梯度的指数加权平均,然后使用这个梯度来更新权重。

        例如:如果你要优化代价函数,函数形状如图,红色点代表最小值的位置,你从某一点开始梯度下降法,你会发现梯度下降法需要计算很多步骤,慢慢摆动到最小值。这种上下波动减慢了梯度下降法的速度,你就无法使用更大的学习率。如果你要用较大的学习率,结果可能会偏离函数的范围。

        另一个看待问题的角度是:在纵轴上,你希望学习的慢一些,因为不想要上下的来回摆动;在横轴上,你希望加快学习,能快速找到最小点。

        使用Momentum梯度下降法你需要做的是:在t次迭代的过程中,你需要计算dw,db,然后计算v_{dw}=\beta v_{dw}+(1-\beta )dw,也就是计算w导数的滑动平均值;v_{dw}=\beta v_{dw}+(1-\beta )dw;然后更新权重w=w-\alpha v_{dw}b=b-\alpha v_{db}  。经过这样的操作,可以让梯度下降的每一步变得平滑。

        举例来说,假设你计算的前几个导数是的,如果平均这些梯度,你会发现纵轴上的平均值趋近于0,所以在纵轴方向上,你希望放慢一点;但是在横轴方向上,所有导数指向横轴方向,因此横轴方向的平均值仍然很大。用算法进行几次迭代后,你会发现Momentum梯度下降法在纵轴方向的摆动变小了,横轴方向运动速度更快(下图红色线)。因次算法走了一条更加直接的路径,在抵达最小值的路径上减少了摆动。

        对动量有种直观的理解:如果你想最小化一个碗状函数 ,你可以把导数项dw和db看成是一个球下坡时的加速度,把动量项看成是球的速度。球在加速度的作用下越滚越快,\beta看成是摩擦力,让球不至于一直无限加速下去。不像梯度下降法,每一步都独立于之前的步骤。

7  RMSprop

        RMSprop全称均方根传递(Root Mean Square Prop),它也可以加速梯度下降。

        我们继续以下面为例进行探讨:纵轴代表参数b,横轴代表参数w。

         如果你想减缓纵轴方向,同时加快横轴方向的学习,RMSprop算法可以实现这一点。在第t次迭代中,该算法会照常计算当前Mini-batch的导数dw和db,s_{dw}=\beta s_{dw}+(1-\beta )(dw)^{2},同样的s_{db}=\beta s_{db}+(1-\beta )(db)^{2};接下来更新参数w=w-\frac{dw}{\sqrt{s_{dw}}}b=b-\frac{db}{\sqrt{s_{db}}}

        例子中的(横轴)w方向,我们希望学习速度快;垂直(b)方向,我们希望减缓纵轴上的摆动。对于s_{dw}s_{db}这两项,我们希望s_{dw}相对较小,因此我们除以一个较小的数;而希望s_{db}较大,我们要除以一个较大的数字,这样就可以减缓纵轴上的变化。如果你看一下导数,你会发现垂直方向上的导数要比水平方向上的导数更大。(db)^{2}较大,s_{db}也会较大;相比之下,(dw)^{2}会较小,s_{dw}会小一些,结果就是纵轴上的更新量除以一个较大的数,减弱摆动;水平方向的更新量除以一个较小的数,加快收敛。你可以使用更大的学习率,不用担心在垂直方向上发散。

        直观理解就是:在你要消除摆动的维度中,你会计算得到一个更大的和值,即导数平方的加权平均,所以最后你去掉了那些有摆动的方向。

        为了保证\frac{dw}{\sqrt{s_{dw}}}的分母不会趋于0,确保数值稳定,在实际操练过程中,要在分母加上一个很小的\epsilon值,一般是10^{-8}

        RMSprop和Momentum一样,可以消除梯度下降中的摆动,并允许你使用一个更大的学习率,从而加快你的算法学习速度。

8  Adam优化算法

        Adam优化算法将Momentum和RMSprop结合在一起。

        我们看看如何使用Adam优化算法:

首先初始化v_{dw}=0,s_{dw}=0,v_{db}=0,s_{db}=0

在第t次迭代过程中,你要用当前的Mini-batch计算dw和db;

计算Momentum指数加权平均数:v_{dw}=\beta _{1}v_{dw}+(1-\beta _{1})dwv_{db}=\beta _{1}v_{db}+(1-\beta _{1})db;

更新RMSprop中的参数:s_{dw}=\beta _{2}s_{dw}+(1-\beta _{2})(dw)^{2}s_{db}=\beta _{2}s_{db}+(1-\beta _{2})(db)^{2}

 一般使用Adam算法时候,要计算v的偏差修正,v_{dw}^{corrected}=\frac{v_{dw}}{1-\beta _{1}^{t}}v_{db}^{corrected}=\frac{v_{db}}{1-\beta _{1}^{t}};s也需要计算偏差修正:s_{dw}^{corrected}=\frac{s_{dw}}{1-\beta _{2}^{t}}s_{db}^{corrected}=\frac{s_{db}}{1-\beta _{2}^{t}}

更新权重:w=w-\alpha \frac{v_{dw}^{corrected}}{\sqrt{s_{dw}^{corrected}}+\epsilon }b=b-\alpha \frac{v_{db}^{corrected}}{\sqrt{s_{db}^{corrected}}+\epsilon }

        这个算法中有很多的超参数,学习率\alpha很重要,也需要经常调试。通常我们会将\beta _{1}的默认值设置为0.9;超参数\beta _{2}一般设置为0.99;\epsilon值一般为10^{-8}

09  学习率衰减

        有一种让学习算法运行更快的方法就是慢慢减少学习率,我们称之为学习率衰减。

        当你使用适量的小样本进行Mini-batch梯度下降法时,也许一个批次只有64或128个样本,当你迭代时会有噪声,它会逐步向最小点靠近,但不会完全收敛到最小点,你的算法最后会在最小值点附近浮动,这是因为你的学习率取了固定值,不同的Mini-batch中有噪声。

        如果慢慢减少学习率的话,在训练初期时,学习率\alpha还是比较大,学习速度相对快;但随着\alpha变小,你的步伐也会变慢变小,最后你的曲线会在最小值附近的一小块区域内摆动。

        慢慢减小学习率的本质在于:在学习初期你可以采用大得多的步长,但开始收敛的时候,小一些的学习率让你的步伐小一些。

        怎么实现学习率衰减?1个epoch就是把所有的数据遍历一遍。

        学习率\alpha =\frac{1}{1+decayRate*epoch}\alpha _{0},这里的衰减率dacayRate是另一个超参数,比如:dacayRate=1,\alpha_{0}=0.2

Epoch\alpha
10.1
20.067
30.05
40.04
..................

随着epoch增加,学习率会衰减,你可以尝试不同的衰减率dacayRate、\alpha_{0}

        除了这个学习率衰减的公式外,人们还会有用一些其他的方式,例如指数衰减:学习率\alpha =0.95^{epoch}\alpha _{0};又比如:\alpha =\frac{k}{\sqrt{epoch}}\alpha _{0}\alpha =\frac{k}{\sqrt{t}}\alpha _{0}

10  局部最优化问题

        在深度学习的早期时候,人们常常担心优化算法会陷入糟糕的局部最优中,但随着深度学习理论的发展,我们对局部最优的理解也在改变。

        当人们想到局部最优的时候,他们脑海中浮现出来的往往是这样的图,也许你想优化一些参数。在图中似乎各处都分布着局部最优,梯度下降或者某个算法可能困在一个局部最优中,而不会抵达全局最优。

        如果你画的是一张二维的图,确实容易像这样有很多局部最优,而人们的直觉往往被这些低维图像所引导,但是这种直觉上的感受并不准确。如果你是在训练一个神经网络,代价函数中大部分梯度为零的点,实际上并不是局部最优,而是鞍点。

        从经验上说,对于一个高维度空间的函数,如果梯度为0,则在每一个方向上,它可能是凸函数或者是凹函数。如果你在两万维空间中,那么想要得到局部最优,所有的两万个方向都需要是的,这发生的概率很小,也许是2^{-20000},你更有可能遇到有些方向的曲线是,有些方向的曲线是,因此在高维度空间,你更有可能遇到鞍点,而不会遇到局部最优点。

        如果局部最优不是问题,那么问题是什么?真正会降低学习速度的实际上是停滞区,停滞区指的是导数长时间接近于0的一段区域。假设现在在曲面上的一点,那么梯度下降法会沿着这个曲面向下移动,然而因为梯度为零或者接近于零,曲面很平,你会花费很长的时间缓慢地在停滞区找到这个点,然后因为左侧或者右侧的随机扰动,你的算法终于能够离开这个停滞区。

        所以说,实际上不太可能陷入糟糕的局部最优点,只要你训练的是一个较大的神经网络,有很多参数,代价函数J定义在一个相对高维的空间上;其次,停滞区也是一个问题,他会让学习过程变得相当慢。


http://www.mrgr.cn/news/100095.html

相关文章:

  • Java常用API详解
  • RHEL与CentOS:从同源到分流的开源操作系统演进
  • 【Luogu】动态规划四
  • Operating System 实验二 内存管理实验
  • cdh平台管理与运维最佳实践
  • 联合体和枚举类型
  • 游戏引擎学习第244天: 完成异步纹理下载
  • 附赠二张图,阐述我对大模型的生态发展、技术架构认识。
  • PR第二课--混剪
  • 巧记英语四级单词 Unit5-中【晓艳老师版】
  • java配置
  • string的基本使用
  • 【初识Trae】字节跳动推出的下一代AI原生IDE,重新定义智能编程
  • 图像预处理-图像亮度变换
  • 查找函数【C++】
  • 二项式分布html实验
  • Linux学习笔记之环境变量
  • 全栈开发的未来:低代码与AI辅助编程的边界探索
  • Linux网络编程 原始套接字与ARP协议深度解析——从数据包构造到欺骗攻防
  • 【linux】Chrony服务器