深度学习优化器

目前常用的优化器

深度学习的优化算法就是为了找到一个全局的最优参数使得loss最小的一种算法,目前一般采用梯度下降法。

梯度下降中有根据整个数据集进行更新的,还有一种是采用部分的数据进行更新。全体数据的更新对于凸函数可以

很好的收敛到全局极小值,对于非凸函数会收敛到局部极小值,而且数据很大的时候梯度更新太慢。而部分的数据进行

训练梯度更新比较快,但是容易受到噪声的影响,准确度就会降低,不是全局最优,但是当训练次数足够多的情况下

会趋向于局部最优。因此目前都是采用部分数据min_batch的模式进行训练。

 

BGD (batch  gradient descent)

                         \theta = \theta - \eta \cdot \bigtriangledown J(\theta )

实例代码

for i in range(nb_epochs):

        grad = cal_gradient(loss_fn, data, param)

        param = param - lr*grad

这种方式需要对整个数据集计算梯度,所以计算比较慢,而且不能加入新的数据进行实时更新模型。

SGD(Stochastic gradient descent)

sgd每次都是对每一个样本进行梯度更新,这样更新速度就比较快。

                         \theta = \theta - \eta \cdot \bigtriangledown J(\theta ; x(i) ; y(i))

for i in range(nb_epochs):

        np.random.shuffle(data)
        for  val in data
            grad = cal_gradient(loss_fn, val, param)

            param = param - lr*grad

考虑到数据分布是有统计意义的,可能部分数据的梯度更新已经很接近总体的分布。但是sgd受到噪声的影响比较大,所以上图中的loss曲线抖动很大。

对比bgd和sgd,bgd可能会陷入局部极小值,而sgd可能到不了局部极小值,也有可能跳到更好的局部极小值。

降低学习率之后两者的收敛性差不多。

MBGD (mini-batch  gradient  descent)

每次采用一小批数据进行更新,这样相对于SGD收敛更稳定,同时相对于bgd而言可以保持比较好的梯度更新效率。

                       \theta = \theta - \eta \cdot \bigtriangledown J(\theta ; x(i:i+n) ; y(i:i+n))

for i in range(nb_epochs):

        np.random.shuffle(data)
        for  val_batch in getbatches(data, 10)
            grad = cal_gradient(loss_fn, val_batch, param)

            param = param - lr*grad

这里的n是一个超参数可以调节。

传统的梯度算法的问题

mbgd不能保证很好的收敛性,学习率太小就容易造成收敛速度慢,太大就会在极小值左右摆动甚至偏离。

以上三种朴素的梯度下降算法在非凸函数的时候容易陷入鞍点处,因为此时的梯度都接近0,容易卡在这里。

同时由于都是采用固定的学习率,这样学习率对于梯度没有自适应,我们一般希望在远离最优解的地方学习率大一点

而在最优解附近学习率小一点。

解决方法

可以从梯度方向学习率来解决,在加快训练的同时,可以使得收敛更稳定。在下面的优化方法中都应用了

指数加权这一方法 https://www.cnblogs.com/guoyaohua/p/8544835.html

Momentum

               v(t) = \gamma v(t-1)+\eta \bigtriangledown J(\theta )

                \theta =\theta - v(t)

利用指数加权引入了动量,这样在梯度方向不变时,速度很快,在梯度方向有所改变的维度上又会有所变慢。

这个方法都是迎着当前的趋势进行更新,不具备一些先验知识。

NAG(Nesterov Accelerated Gradient)

                v(t) = \gamma v(t-1)+\eta \bigtriangledown J(\theta - \gamma v(t-1))

                 \theta =\theta - v(t)

  NAG在跟新会根据未来的梯度进行预期调节。

  所以NGA在RNN上会有比较好的表现。

上面是在总体上进行梯度的调节,如果可以根据不同的参数的重要性进行不同程度的更新。

也就是在不同的参数上学习率有所不同。

Adagrad (Adaptive gradient algorithm)

对于低频的数据有较大的更新,对于高频的数据做较小的更新。

            \theta (t+1, i)=\theta (t, i) - \eta /(\sqrt{G(t,ii)+\varepsilon })\cdot g(t,i)

其中g(t,i)表示t时刻参数\theta(i)的梯度,G(t,ii)是一个对角矩阵,对角上面每一个值表示梯度的平方值的累积和。

Adagrad实现了不同参数学习率的自动调整。但是由于分母是梯度平方和的累积会使得学习率不断减少。

Adadelta

这个算法是adagrad的改进版本,它的梯度函数如下:

              \bigtriangledown \theta(t)=-\frac{\eta }{\sqrt{E[g^{2}]_{t}+\varepsilon }}g_{t}

分母采用了梯度的均方根,就是将之前的梯度的平方求和转换成求平均值,用RMS简写

               \bigtriangledown \theta(t)=-\frac{\eta }{RMS[g]_{t}}\cdot g_{t}

而E的计算又依赖之前的平均值和当前的梯度

              E[g^{2}]_{t}=\gamma E[g^{2}]_{t-1} + (1-\gamma )g^{2}_{t}

RMSprop

RMSprop和Adadelta都是为了解决adagrad学习率急剧下降的方法。

Adam (adaptive moment estimation)

这种方式就是在学习率和梯度两个维度上进行了自适应的方式。相当于RMSprop+Momentum

除了像RMSprop存储了过去梯度平方vt的指数衰减平均值,也需要保存momentum中梯度的指数平均衰减值。

                      m_{t}=\beta _{1}m_{t-1}+(1-\beta_{1} )g_{t}

                      v_{t} = \beta _{2} + (1- \beta _{2})g_{t}^{2}

m(t)和v(t)的初始化都为0, 

                      \widehat{m_{t}} = \frac{(m_{t})}{1-\beta _{1}^{t} }

                       \widehat{v_{t}} = \frac{(v_{t})}{1-\beta _{2}^{t} }

梯度更新规则:

                    \theta _{t+1} = \theta _{t} - \frac{\eta }{\sqrt{\widehat{v}_{t} }+\varepsilon }\widehat{m}_{t}

\beta1=0.9   \beta2=0.999 \varepsilon =10e-8

实践证明Adam效果要好一点。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值