⚡机器学习⚡中的优化器(Optimizers)方法

Posted 府学路18号车神

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了⚡机器学习⚡中的优化器(Optimizers)方法相关的知识,希望对你有一定的参考价值。

⚡终于!!!
⚡终于又有时间学习Deep Learning了⚡!
30ML计划,一起加油!!!
https://blog.csdn.net/weixin_44333889/category_11271153.html《专栏》

在训练NN的时候,有哪些Optimizers可以优化更快的找到global Minima?

下面我们来看下有哪些方法可以优化求解。

Background

在训练神经网路的时候,最开始我们是用的Gradient Descent(梯度下降法,GD)来求解,但是会出现很多问题,面临大量的数据的时候,GD会出现local Minima,而且求解速度会下降。

关于GD+Momentum,可以看这个介绍简单易懂。

整个技术的发展路线如下:

  • SGD 【Cauchy,1847】
  • SGD with momentum 【Rumelhart,et al.,Nature’1986】

上面两个是远古时期的优化求解方法,其实放到现在来看,依旧还是很有效果。

如下面这些就是SGDM训练出来的,

目前比较常用的是下面三个Optimizers:

  • Adagrad 【Duchi,et al. JMLR’11 2011】
  • RMSProp 【Hinton,et al. Lecture slides, 2013】
  • Adam 【kingma,et al. ICLR’15 2014】

借用一下李老师(台大,李宏毅)的PPT。

SGD,stochastic gradient descent。也就是最普通的方法,如下图所示

SGD就像图中的更新方式一样,随机找到一个起始点,对其求梯度,然后在其梯度的反方向按照 η \\eta η步长进行更新,找到下一个点,然后在不断的重复操作,直到找到Minima。

关于SGDM的更新方式如下图。可以看出,更新方式在SGD的基础上,增加了Momentum,而这个Momentum则是在一次梯度下降后,按照其算的梯度方向的反方向(图中 g 1 g^1 g1)和上一个更新方向的延长(图中 m 1 m^1 m1)的合成方向(图中 m 2 m^2 m2)的方向进行更新操作的。不断的进行更新,直到找到最优的解则停止。

Adagrad

Adagrad(自适应梯度算法)。其基本思想是,对每个参数theta自适应的调节它的学习率,自适应的方法就是对每个参数乘以不同的系数,并且这个系数是通过之前累积的梯度大小的平方和决定的,也就是说,对于之前更新很多的,相对就可以慢一点,而对那些没怎么更新过的,就可以给一个大一些的学习率。

Adagrad算法:


  • 参数设置: ϵ \\epsilon ϵ 为全局学习率;初始参数 θ \\theta θ;较小的常数(超参数,自己设定) δ \\delta δ,为了数值稳定大约设置为 1 0 − 7 10^{-7} 107
  • 初始化梯度累积变量 r = 0 r=0 r=0

接下来是循环迭代更新

while 没有达到停止准则 do

  • 从训练集中采包含 m m m个样本 { x ( 1 ) , . . . , x ( m ) } \\{x^{(1)},...,x^{(m)}\\} {x(1),...,x(m)}的小批量,对应目标为 y ( i ) y^{(i)} y(i)
  • 计算梯度: g ← 1 m ▽ θ Σ i L ( x ( 1 ) ; θ , y ( i ) ) g \\leftarrow \\frac{1}{m} \\bigtriangledown _\\theta\\Sigma_i L(x^{(1)};\\theta,y^{(i)}) gm1θΣiL(x(1);θ,y(i))
  • 累积平方梯度: r ← r + g ⊙ g r\\leftarrow r+g \\odot g rr+gg
  • 计算更新: △ θ ← − ϵ δ + r ⊙ g \\bigtriangleup \\theta\\leftarrow - \\frac{\\epsilon}{\\delta+\\sqrt{r}}\\odot g θδ+r ϵg(逐步元素地应用除和求平方根)
  • 应用更新: θ ← θ + △ θ \\theta\\leftarrow \\theta+\\bigtriangleup \\theta θθ+θ

end
(结束优化更新)


以上就为Adagrad算法的内容。

Python实现代码:

import numpy as np

class Adagrad:
    def __init__(self, learning_rate=0.01):
        self.learning_rate = learning_rate    # 学习率设置为0.01
        self.fg = None  
        self.delta = 1e-07                   # 设置1e-07微小值避免分母为0
        
    def update(self, params, grads):     # 更新操作
        if self.fg is None:
            self.fg = {}               # 设为空列表
            for key, value in params.items():
                self.fg[key] = np.zeros_like(value)   # 构造一个矩阵

        for key in params.keys():        # 循环迭代
            self.fg[key] += grads[key] * grads[key]     
            params[key] -= self.learning_rate * grads[key] / (np.sqrt(self.fg[key]) + self.delta) 

RMSProp

RMSProp算法实则为对Adagrad的一个改进,也就是把Adagrad对历史梯度加和变成了对历史梯度求均值,再利用这个均值代替Adagrad累加的梯度和对当前梯度进行加权,并用来update更新。

用均值代替求和是为了解决Adagrad的学习率逐渐消失的问题。


(图片源自网络)

有位大佬的解释更加清晰,可跳转此处

def RMSprop(x, y, step=0.01, iter_count=500, batch_size=4, alpha=0.9, beta=0.9):
    length, features = x.shape
    data = np.column_stack((x, np.ones((length, 1))))
    w = np.zeros((features + 1, 1))
    Sdw, v, eta = 0, 0, 10e-7
    start, end = 0, batch_size
    
    # 开始迭代
    for i in range(iter_count):
        # 计算临时更新参数
        w_temp = w - step * v
        
        # 计算梯度
        dw = np.sum((np.dot(data[start:end], w_temp) - y[start:end]) * data[start:end], axis=0).reshape((features + 1, 1)) / length        
        
        # 计算累积梯度平方
        Sdw = beta * Sdw + (1 - beta) * np.dot(dw.T, dw)
        
        # 计算速度更新量、
        v = alpha * v + (1 - alpha) * dw
        
        # 更新参数
        w = w - (step / np.sqrt(eta + Sdw)) * v
        start = (start + batch_size) % length
        if start > length:
            start -= length
        end = (end + batch_size) % length
        if end > length:
            end -= length
    return w

Adam

最后讲讲Adam(自适应矩估计 Adaptive moment estimation),因为目前是比较强的,下面这些都是由Adam训练出来的,

看一下Adam和SGDM的准确率对比(源自论文)

由于Adam的提出的地方有一些突兀,并非在论文或会议,能找到的最原始的出处也只有下面了,看一下他的更新方式吧,相当于一个优化参数的更新模块。

简单翻译一下上面的更新步骤:

首先,参数设置: g t 2 = g t ⊙ g t g_t^2=g_t \\odot g_t gt2=gtgt,默认测试的学习率(LR) α = 0.001 \\alpha=0.001 α=0.001,各种超参数 β 1 = 0.9 、 β 2 = 0.999 、 ϵ = 1 0 − 8 \\beta _1=0.9、\\beta_2=0.999、\\epsilon =10^{-8} β1=0.9β2=0.999ϵ=108

  1. α \\alpha α: 步长(Stepsize)亦或学习率
  2. β 1 , β 2 ∈ [ 0 , 1 ] \\beta _1,\\beta _2\\in[0,1] β1,β2[0,1]:矩估计的指数衰减率
  3. f ( θ ) f(\\theta) f(θ):参数 θ \\theta θ 的随机目标函数值
  4. θ 0 \\theta_0 θ0: 初始参数向量{ m 0 ← 0 m_0 \\leftarrow0 m00:(初始化第一权值向量)、 v 0 ← 0 v_0\\leftarrow0 v00:(初始化第二权值向量)、 t ← 0 t\\leftarrow0 t0:(初始化时变步长)}

下面为约束,当且仅当 θ t \\theta_t θt 不收敛的时候执行以下操作: