精华内容
下载资源
问答
  • 鸢尾花(adam同时结合SGDM一阶动量和RMSPro二阶动量) # 利用鸢尾花数据集,实现前向传播、反向传播,可视化loss曲线 # adam同时结合SGDM一阶动量和RMSPro二阶动量 import tensorflow as tf from sklearn import ...

    鸢尾花(adam同时结合SGDM一阶动量和RMSPro二阶动量)

    # 利用鸢尾花数据集,实现前向传播、反向传播,可视化loss曲线
    # adam同时结合SGDM一阶动量和RMSPro二阶动量
    
    import tensorflow as tf
    from sklearn import datasets
    from matplotlib import pyplot as plt
    import numpy as np
    import time  ##1##
    
    # 导入数据,分别为输入特征和标签
    x_data = datasets.load_iris().data
    y_data = datasets.load_iris().target
    
    # 随机打乱数据(因为原始数据是顺序的,顺序不打乱会影响准确率)
    # seed: 随机数种子,是一个整数,当设置之后,每次生成的随机数都一样
    np.random.seed(116)  # 使用相同的seed,保证输入特征和标签一一对应
    np.random.shuffle(x_data)
    np.random.seed(116)
    np.random.shuffle(y_data)
    tf.random.set_seed(116)
    
    # 将打乱后的数据集分割为训练集和测试集,训练集为前120行,测试集为后30行
    x_train = x_data[:-30]
    y_train = y_data[:-30]
    x_test = x_data[-30:]
    y_test = y_data[-30:]
    
    # 转换x的数据类型,否则后面矩阵相乘时会因数据类型不一致报错
    x_train = tf.cast(x_train, tf.float32)
    x_test = tf.cast(x_test, tf.float32)
    
    # from_tensor_slices函数使输入特征和标签值一一对应。(把数据集分批次,每个批次batch组数据)
    train_db = tf.data.Dataset.from_tensor_slices((x_train, y_train)).batch(32)
    test_db = tf.data.Dataset.from_tensor_slices((x_test, y_test)).batch(32)
    
    # 生成神经网络的参数,4个输入特征故,输入层为4个输入节点;因为3分类,故输出层为3个神经元
    # 用tf.Variable()标记参数可训练
    # 使用seed使每次生成的随机数相同
    w1 = tf.Variable(tf.random.truncated_normal([4, 3], stddev=0.1, seed=1))
    b1 = tf.Variable(tf.random.truncated_normal([3], stddev=0.1, seed=1))
    
    lr = 0.1  # 学习率为0.1
    train_loss_results = []  # 将每轮的loss记录在此列表中,为后续画loss曲线提供数据
    test_acc = []  # 将每轮的acc记录在此列表中,为后续画acc曲线提供数据
    epoch = 500  # 循环500轮
    loss_all = 0  # 每轮分4个step,loss_all记录四个step生成的4个loss的和
    
    ##########################################################################
    m_w, m_b = 0, 0
    v_w, v_b = 0, 0
    beta1, beta2 = 0.9, 0.999
    delta_w, delta_b = 0, 0
    global_step = 0
    ##########################################################################
    
    # 训练部分
    now_time = time.time()  ##2##
    for epoch in range(epoch):  # 数据集级别的循环,每个epoch循环一次数据集
        for step, (x_train, y_train) in enumerate(train_db):  # batch级别的循环 ,每个step循环一个batch
     ##########################################################################
            global_step += 1
     ##########################################################################
            with tf.GradientTape() as tape:  # with结构记录梯度信息
                y = tf.matmul(x_train, w1) + b1  # 神经网络乘加运算
                y = tf.nn.softmax(y)  # 使输出y符合概率分布(此操作后与独热码同量级,可相减求loss)
                y_ = tf.one_hot(y_train, depth=3)  # 将标签值转换为独热码格式,方便计算loss和accuracy
                loss = tf.reduce_mean(tf.square(y_ - y))  # 采用均方误差损失函数mse = mean(sum(y-out)^2)
                loss_all += loss.numpy()  # 将每个step计算出的loss累加,为后续求loss平均值提供数据,这样计算的loss更准确
            # 计算loss对各个参数的梯度
            grads = tape.gradient(loss, [w1, b1])
    
    ##########################################################################
     # adam
            m_w = beta1 * m_w + (1 - beta1) * grads[0]
            m_b = beta1 * m_b + (1 - beta1) * grads[1]
            v_w = beta2 * v_w + (1 - beta2) * tf.square(grads[0])
            v_b = beta2 * v_b + (1 - beta2) * tf.square(grads[1])
    
            m_w_correction = m_w / (1 - tf.pow(beta1, int(global_step)))
            m_b_correction = m_b / (1 - tf.pow(beta1, int(global_step)))
            v_w_correction = v_w / (1 - tf.pow(beta2, int(global_step)))
            v_b_correction = v_b / (1 - tf.pow(beta2, int(global_step)))
    
            w1.assign_sub(lr * m_w_correction / tf.sqrt(v_w_correction))
            b1.assign_sub(lr * m_b_correction / tf.sqrt(v_b_correction))
    ##########################################################################
    
        # 每个epoch,打印loss信息
        print("Epoch {}, loss: {}".format(epoch, loss_all / 4))
        train_loss_results.append(loss_all / 4)  # 将4个step的loss求平均记录在此变量中
        loss_all = 0  # loss_all归零,为记录下一个epoch的loss做准备
    
        # 测试部分
        # total_correct为预测对的样本个数, total_number为测试的总样本数,将这两个变量都初始化为0
        total_correct, total_number = 0, 0
        for x_test, y_test in test_db:
            # 使用更新后的参数进行预测
            y = tf.matmul(x_test, w1) + b1
            y = tf.nn.softmax(y)
            pred = tf.argmax(y, axis=1)  # 返回y中最大值的索引,即预测的分类
            # 将pred转换为y_test的数据类型
            pred = tf.cast(pred, dtype=y_test.dtype)
            # 若分类正确,则correct=1,否则为0,将bool型的结果转换为int型
            correct = tf.cast(tf.equal(pred, y_test), dtype=tf.int32)
            # 将每个batch的correct数加起来
            correct = tf.reduce_sum(correct)
            # 将所有batch中的correct数加起来
            total_correct += int(correct)
            # total_number为测试的总样本数,也就是x_test的行数,shape[0]返回变量的行数
            total_number += x_test.shape[0]
        # 总的准确率等于total_correct/total_number
        acc = total_correct / total_number
        test_acc.append(acc)
        print("Test_acc:", acc)
        print("--------------------------")
    total_time = time.time() - now_time  ##3##
    print("total_time", total_time)  ##4##
    
    # 绘制 loss 曲线
    plt.title('Loss Function Curve')  # 图片标题
    plt.xlabel('Epoch')  # x轴变量名称
    plt.ylabel('Loss')  # y轴变量名称
    plt.plot(train_loss_results, label="$Loss$")  # 逐点画出trian_loss_results值并连线,连线图标是Loss
    plt.legend()  # 画出曲线图标
    plt.show()  # 画出图像
    
    # 绘制 Accuracy 曲线
    plt.title('Acc Curve')  # 图片标题
    plt.xlabel('Epoch')  # x轴变量名称
    plt.ylabel('Acc')  # y轴变量名称
    plt.plot(test_acc, label="$Accuracy$")  # 逐点画出test_acc值并连线,连线图标是Accuracy
    plt.legend()
    plt.show()
    
    
    
    
    展开全文
  • 这个项目是为了演示使用一个叫做 Momenergy(一阶动量和二阶能量之间的分数矩)的新概念来实时识别物体。 为简单起见,输入文件采用位图格式。 根据动量生成函数理论,任何分数阶矩都包含无限阶矩的线性组合,相当于...
  • 深度学习优化学习方法总结 (一阶为主...常用的优化算法:梯度下降法,牛顿法,拟牛顿法,共轭梯度法 (二阶为主)https://blog.csdn.net/sunflower_sara/article/details/81215135 一阶方法: 随机梯度下降(St...

    深度学习优化学习方法总结 (一阶为主)https://blog.csdn.net/sunflower_sara/article/details/81321886

    常用的优化算法:梯度下降法,牛顿法,拟牛顿法,共轭梯度法 (二阶为主) https://blog.csdn.net/sunflower_sara/article/details/81215135

     

    一阶方法:

    随机梯度下降(Stochastic Gradient Descent,SGD)

    动量(SGD with Momentum,SGDM)

    牛顿动量法(Nesterov Acceleration Gradient,NAG)

    AdaGrad(自适应梯度)

    RMSProp(均方差传播)

    Adam

    Nadam

     

    二阶方法:

    牛顿法

    拟牛顿法

    共轭梯度法 CG

    BFGS

    L-BFGS

    展开全文
  •  Adam 融合一阶动量和二阶动量。 因为当和一开始被初始化为 0 时,最初的几步通常会偏向0,表示参数更新太慢。 他们使用偏差纠正系数,来修正一阶矩和二阶矩的偏差: 8. Nadam Nesterov + Adam = Nadam 公式还没...

    1. SGD

    现在的SGD一般都指小批量梯度下降,即每一次迭代计算mini-batch的梯度,然后对参数进行更新。

                   g_{t}= \triangledown _{\theta_{t-1}}J(\theta_{t-1})

                  \triangle \theta _t = -\eta \ast g_t

                  \theta _t = \theta _{t-1}+\triangle \theta _t

    其中\theta _t是模型参数,J(\theta _{t-1})是模型目标函数,g_t是目标函数的梯度,\eta是学习率。

    难点(缺点):

              (1)学习率的选择。过低收敛缓慢,过高无法收敛。

              (2)“之字形”的出现,即在陡谷(一种在一个方向的弯曲程度远大于其他方向的表面弯曲情况)处震荡。如下图所示

    2. 动量法(Momentum)

                   m_t=\mu \ast m_{t-1}-\eta g_t

                   \theta _t = \theta _{t-1}+m _t

    其中m_t是一阶动量,\mu是动量因子。

    优点:改善“之字形”震荡,动量项在梯度指向方向相同的方向逐渐增大,对梯度指向改变的方向逐渐减小(不断中和),一定程度可以靠惯性冲出局部低点。

    3. Nesterov

    我们使用\mu \ast m_{t-1}来移动\theta,通过计算\theta_{t-1}+\mu \ast m_{t-1},我们能够得到一个下次参数位置的近似值——也就是能告诉我们参数大致会变为多少。那么,通过基于未来参数的近似值(站的更远看看)而非当前的参数值计算相得应罚函数J(\theta_{t-1}+\mu \ast m_{t-1})并求偏导数,我们能让优化器高效地「前进」并收敛:

                   m_t=\mu \ast m_{t-1}-\eta \triangledown J(\theta _{t-1}+\mu \ast m_{t-1})

                   \theta _t = \theta _{t-1}+m_t

    4. Adagrad

    解决学习率的选择问题,对学习率进行自适应约束。

                   n_t = n_{t-1}+g_t^2

                  \triangle \theta _t = -\frac{\eta }{ \sqrt{n_t+\varepsilon }}\ast g_t

                  \theta _t = \theta _{t-1}+\triangle \theta _t

    其中\varepsilon是个很小的数,为了确保分母不为0,n_t是梯度平方的累积,为二阶动量。

    优点:不需要手工调节学习率,在稀疏数据场景下效果较好,对于经常更新的参数,我们已经积累了大量关于它的知识,不希望被单个样本影响太大,希望学习速率慢一些;对于偶尔更新的参数,我们了解的信息太少,希望能从每个偶然出现的样本身上多学一些,即学习速率大一些。

    缺点:随着时间的增长,n_t单调增长,\triangle \theta _t单调减少,有可能过早的变为0,训练过早的结束。而且依然依赖与人工设定的学习率。

    5. RMSprop

    由于AdaGrad单调递减的学习率变化过于激进,RMSprop只关注过去一段时间的梯度平均值,离的时间越远越不重要。

                   n_t = \beta_2 n_{t-1}+(1-\beta_2 )g_t^2

                  \triangle \theta _t = -\frac{\eta }{ \sqrt{n_t+\varepsilon }}\ast g_t

                  \theta _t = \theta _{t-1}+\triangle \theta _t

    6. Adadelta

    RMSprop依然需要自己设定全局学习率,因此Adadelta在RMSprop的基础上,用参数更新的平方来替代全局学习率的位置,这样就可以省略全局学习率了。

                   n_t = \beta_2 n_{t-1}+(1-\beta_2 )g_t^2

                   V_t = \gamma V_{t-1}+(1-\gamma )\triangle\theta _t^2

                  \triangle \theta _t = -\frac{ \sqrt{V_t+\varepsilon}}{ \sqrt{n_t+\varepsilon }}\ast g_t

                  \theta _t = \theta _{t-1}+\triangle \theta _t

    7. Adam

    融合一阶动量和二阶动量。

                   m_t=\beta_1 m_{t-1}+(1-\beta_1) g_t

                   n_t = \beta_2 n_{t-1}+(1-\beta_2 )g_t^2

    因为当m_tn_t一开始被初始化为 0 时,最初的几步通常会偏向0,表示参数更新太慢。

    他们使用偏差纠正系数,来修正一阶矩和二阶矩的偏差:

                   \hat{m_t}=\frac{m_t}{1-\beta_1^t}

                   \hat{n_t}=\frac{n_t}{1-\beta_2^t}

                  \triangle \theta _t = -\eta \ast \frac{\hat{m_t} }{ \sqrt{\hat{n_t}+\varepsilon }}

                  \theta _t = \theta _{t-1}+\triangle \theta _t

    8. Nadam

    Nesterov + Adam = Nadam

    公式还没完全理解先不放了。

    不知道算是原创还是转载,放上几篇参考网址吧:

                  https://zhuanlan.zhihu.com/p/22252270

                  https://www.cnblogs.com/shixiangwan/p/7532858.html

                  https://zhuanlan.zhihu.com/p/32230623

    展开全文
  • 虽然局部最小值鞍点可以阻止我们的训练,但是病态曲率可以使训练减慢到机器学习从业者可能认为搜索已经收敛到次优极小值的程度。让我们深入了解病理曲率是什么。 病态曲率 考虑以下损失轮廓。  ...

    另在一篇文章中,我们介绍了随机梯度下降的细节以及如何解决陷入局部最小值或鞍点等问题。在这篇文章中,我们看看另一个困扰神经网络训练的问题,即病态曲率

    虽然局部最小值和鞍点可以阻止我们的训练,但是病态曲率可以使训练减慢到机器学习从业者可能认为搜索已经收敛到次优极小值的程度。让我们深入了解病理曲率是什么。

    病态曲率

    考虑以下损失轮廓。

    ççæ²ç

                                                                               病态曲率

    你看,我们在进入以蓝色标记的山沟状区域之前随机开始。颜色实际上表示损失函数在特定点处的值有多大,红色表示最大值,蓝色表示最小值。我们想要达到最小值点,为此但需要我们穿过山沟。这个区域就是所谓的病态曲率。理解要为什么它被称为病态,让我们深入研究。下图是病态曲率放大后的图像,看起来像..

    patho2-1

     

    要理解这里发生的事情并不是很难。梯度下降沿着山沟的山脊反弹,向极小的方向移动较慢。这是因为脊的表面在W1方向上弯曲得更陡峭。

    如下图,考虑在脊的表面上的一个点梯度。该点的梯度可以分解为两个分量,一个沿着方向w1,另一个沿着w2。梯度在w1方向上的分量要大得多,因此梯度的方向更靠近w1,而不是朝向w2(最小值位于其上)。

    patho3

     

    通常情况下,我们使用低学习率来应对这样的反复振荡,但在病态曲率区域使用低学习率,可能要花很多时间才能达到最小值处。事实上,有论文报告,防止反复振荡的足够小的学习率,也许会导致从业者相信损失完全没有改善,干脆放弃训练。

    大概,我们需要找到一种方法,首先缓慢地进入病态曲率的平坦底部,然后加速往最小值方向移动。二阶导数可以帮助我们来到来到赖这一点一一。

    牛顿法

    下降梯度的英文一阶优化方法。它只考虑损失函数的一阶导数而不是较高的导数。这基本上意味着它没有关于损失函数曲率的线索它可以判断损失是否在下降和速度有多快,但无法区分曲线是平面,向上弯曲还是向下弯曲。

    第ä¸ä¸ªè®¢å

    上图三条曲线,红点处的梯度都是一样的,但曲率大不一样。解决方案?考虑二阶导数,或者说梯度改变得有多快。

    使用二阶导数解决这一问题的一个非常流行的技术是牛顿法(Newton's Method)。为了避免偏离本文的主题,我不会过多探究牛顿法的数学。相反,我将尝试构建牛顿法的直觉。

    牛顿法可以提供向梯度方向移动的理想步幅。由于我们现在具备了损失曲面的曲率信息,步幅可以据此确定,避免越过病态曲率的底部。

    牛顿法通过计算海森矩阵做到这一点.Hessian矩阵是损失函数在所有权重组合上的二阶导数的矩阵。

    ç²éº»å¸

    黑森州提供了损失曲面每一点上的曲率估计。正曲率意味着随着我们的移动,损失曲面变得不那么陡峭了。负曲率则意味着,损失曲面变得越来越陡峭了。

    å±å¹æªå¾ -  2018年到6月1日 - å¨ - 25å¹'ææ27æ¥ï¼PM

    注意,如果这一步的计算结果是负的,那就意味着我们可以切换回原本的算法。这对应于下面梯度变得越来越陡峭的情形。

    é¡å³ç

    然而,如果梯度变得越来越平坦,那么我们也许正向病态曲率的底部移动。这时牛顿算法提供了一个修正过的学习步幅,和曲率成反比。换句话说,如果损失曲面变得不那么陡峭,学习步幅就下降。 

    为何我们不常使用牛顿法?

    你已经看到公式中的海森矩阵了.Hessian矩阵需要我们计算损失函数在所有权重组合上的梯度。也就是说,需要做的计算的数量级是神经网络所有权重数量的平方。

    现代神经网络架构的参数量可能是数亿,计算数亿的平方的梯度在算力上不可行。

    虽然高阶优化方法在算力上不太可行,但二阶优化关于纳入梯度自身如何改变的想法是可以借鉴的虽然我们无法准确计算这一信息,但我们可以基于之前梯度的信息使用启发式算法引导优化过程。(这个大家可以看看神经网络与机器学习这本书,那里有详细的讲解,当然需要你拥有很好的数学基础和理解能力

    随机梯度下降( Stochastic Gradient Descent,SGD

    SGD的学习原理很简单就是选择一条数据,就训练一条数据,然后修改权值算法过程如下:

    随机梯度下降法:

    给定数据集X = \ left \ {x ^ 1,x ^ 2,...,x ^ n \ right \},数据集标记为:Y = \ left \ {y ^ 1,y ^ 2,...,y ^ n \ right \},学习器为F(X;  W)的,学习率\α

              对于迭代足够多次

                      {

                                 1.随机选择数据:\ left \ {x ^ j,y ^ j \ right \}

                                 2.计算损失梯度:\ bigtriangledown w = \ frac {\ partial L(y ^ j,f(x ^ j;  w))} {\ partial w}

                                 3.修改权值: w_i = w_ {i(old)}  -  \ alpha \ bigtriangledown w

                       }

    SGD算法在训练过程中很有可能选择被标记错误的标记数据,或者与正常数据差异很大的数据进行训练,那么使用此数据求得梯度就会有很大的偏差,因此SGD在训练过程中会出现很强的随机现象。如何解决呢?

    可以多选择几个数据在一起求梯度和,然求均值,这样做的好处是即使有某条数据存在严重缺陷,也会因为多条数据的中和而降低其错误程度。在上述的的算法中,率学习\α通常的英文固定的值,但是在实际中,我们通常希望学习率随着训练次数增加而减小,减小的原因上面也说了减少振荡,这里先给出一种调节学习率的公式:

                                                  \ alpha _i =(1- \ frac {i} {k})\ alpha _0 + \ frac {i} {k} b

    上面是线性学习率调整规则,通常ķ的取值和训练次数有关,如果训练次数为上百次,则ķ要大于100,而b的值可以粗略的设置为百分之一的初始学习率,学习率初始值一般作为超参数进行设置,一般采取尝试策略。

    学习率最小批量梯度下降算法

    初始化:

    给定数据集X = \ left \ {x ^ 1,x ^ 2,...,x ^ n \ right \},数据集标记为:Y = \ left \ {y ^ 1,y ^ 2,...,y ^ n \ right \},随机采样m条数据,训练周期k,学习率衰减最低值b,学习器为F(X;  W)的,初始学习率\ alpha_0

    训练:

    对于      我是一个人 

            {

                 1.随机采样几条数据:\ left \ {(x ^ 1,y ^ 1),...,(x ^ m,y ^ m)\ right \}

                 2.计算采样数据平均损失梯度:\ bigtriangledown w = \ frac {1} {m} \ sum_ {j = 1} ^ {m} \ frac {\ partial L(y ^ j,f(x ^ j;  w))} {\ partial w}

                 3.计算衰减学习率: \ alpha _i =(1- \ frac {i} {k})\ alpha _0 + \ frac {i} {k} b

                 4.修改权值:w_i = w_ {i(old)}  -  \ alpha_i \ bigtriangledown w_i

            }

    效果如下图

    批量数据集集

    动量学习法

    和SGD一起使用的非常流行的技术称为Momentum。动量也不仅使用当前步骤的梯度来指导搜索,而是累积过去步骤的梯度以确定要去的方向。那么什么是动量学习法呢?

    物理学中,动量的英文与物体的质量、速度相关的物理量。一般而言,一个物体的动量指的的是这个物体在它运动方向上保持运动的趋势。动量是矢量这里我们可以把梯度理解成力,力是有大小和方向的,而且力可以改变速度的大小和方向,并且速度可以累积。这里把权值理解成速度,当力(梯度)改变时就会有一段逐渐加速或逐渐减速的过程,我们通过引入动量就可以加速我们的学习过程,可以在鞍点处继续前行,也可以逃离一些较小的局部最优区域下面类比物理学定义这里的动量

           物理学中,用变量v表示速度,表明参数在参数空间移动的方向即速率,而代价函数的负梯度表示参数在参数空间移动的力,根据牛顿定律,动量等于质量乘以速度,而在动量学习算法中,我们假设质量的单位为1,因此速度v就可以直接当做动量了,我们同时引入超参数\公测,其取值在【0,1】范围之间,用于调节先前梯度(力)的衰减效果,其更新方式为:

                                                v = \ beta v- \ alpha \ bigtriangledown w                                                    (1)

                                                 w = w + v

    根据上面的随机梯度下降算法给出动量随机梯度下降算法;

    初始化:

    给定数据集X = \ left \ {x ^ 1,x ^ 2,...,x ^ n \ right \},数据集标记为:Y = \ left \ {y ^ 1,y ^ 2,...,y ^ n \ right \},,初始速度v,随机采样m条数据,训练周期k,学习率衰减最低值b,学习器为F(X;  W)的,初始学习率\ alpha_0,初始动量参数为\公测

    训练:

              对于  我是一个人

                  {

                            1.随机采样米条数据:\ left \ {(x ^ 1,y ^ 1),...,(x ^ m,y ^ m)\ right \}

                             2.计算采样数据平均损失梯度:\ bigtriangledown w = \ frac {1} {m} \ sum_ {j = 1} ^ {m} \ frac {\ partial L(y ^ j,f(x ^ j;  w))} {\ partial w}

                             3.更新速度:v = \ beta v- \ alpha \ bigtriangledown w

                             4.更新参数:w = w + v

                  }

     在随机梯度的学习算法中,每一步的步幅都是固定的,而在动量学习算法中,每一步走多远不仅依赖于本次的梯度的大小还取决于过去的速度。速度v是累积各轮训练参的梯度,其中\公测越大,依赖以前的梯度越大。假如每轮训练的梯度方向都是相同的,和小球从斜坡滚落,由于但衰减因子的\公测存在,小球并不会一直加速,而是达到最大速度后开始匀速行驶,这里假设每轮获得的梯度都是相同的,那么速度最大值为(按照(1)计算可得):

                                                                   v_ {max} = \ frac {\ alpha \ left \ |  \ bigtriangledown w \ right \ |} {1- \ beta}

    从上式可以看到当\公测= 0.9时,最大速度相当于梯度下降的10倍(带进上式去算可得),通常\公测可取0.5,0.9,0.99,情况一般\公测的调整没有\α调整的那么重要适当。取值即可。

    图形如下:

    好到这里大家懂了动量的学习机理,我们继续看看那篇博文:

    梯度下降的方程式修改如下。

    AE

    上面的第一个等式就是动量,动量等式由两部分组成,第一项是上一次迭代的动量,乘以“动量系数”。

    momentum2-1

     如果我们将v的初始值设置为0并选择我们的系数为0.9,则后续更新方程式将如下所示。

    update_eq-1

    我们看到,后续的更新保留了之前的梯度,但最近的梯度权重更高。

    下面我们来看看动量法如何帮助我们缓解病态曲率的问题。下图中,梯度大多数发生更新在ž字形方向上,我们将每次更新分解为W1和W2方向上的两个分量。如果我们分别累加这些梯度的两个分量,那么W1方向上的分量将互相抵消,而W2方向上的分量得到了加强。 

    moment_compo

    也就是说,基于动量法的更新,积累了W2方向上的分量,清空了W1方向上的分量,从而帮助我们更快地通往最小值。从这个意义上说,动量法也有助于抑制振荡。

    动量法同时提供了加速度,从而加快收敛。但你可能想要搭配模拟退火,以免跳过最小值。当我们使用动量优化算法的时候,可以解决小批量SGD优化算法更新幅度摆动大的问题,同时可以使得网络的收敛速度更快。

    在实践中,动量系数一般初始化为0.5,并在多个时期后逐渐退火至0.9。

    AdaGrad(自适应梯度算法)

    前面的随机梯度和动量随机梯度算法都是使用全局的学习率,所有的参数都是统一步伐的进行更新的,上面的例子中我们是在二维权值的情况,如果扩展到高维,大家可想而知,我么你的优化环境将很复杂,比如你走在崎岖额深山老林林,到处都是坑坑洼洼,如果只是走一步看一步(梯度下降),或者快速奔跑向前(动量学习),那我们可能会摔的头破血流,怎么办呢如果可以针对每个参数设置学习率可能会更好,让他根据情况进行调整,这里就先引出自适应梯度下降?

    AdaGrad其实很简单,就是将每一维各自的历史梯度的平方叠加起来,然后更新的时候除以该历史梯度值即可。如针对第我个参数,算法如下。

    定义首先一个量\ THETA用于累加梯度的平方,如下:

                                                       \ theta _i = \ theta _i +(\ bigtriangledown w_i)^ 2

    平方的原因是去除梯度符号的干扰,防止抵消,更新时:

                                                      w_i = w_i  -  \ frac {\ alpha} {\ sqrt {\ theta _i} + \ delta} \ bigtriangledown w_i

            其中\三角洲= 10 ^ -7,防止数值溢出。

    从上式可以看出,AdaGrad使的参数在累积的梯度较小时(\ theta <1)就会放大学习率,使网络训练更加快速。在梯度的累积量较大时(\ theta> 1)就会缩小学习率,延缓网络的训练,简单的来说,网络刚开始时学习率很大,当走完一段距离后小心翼翼,这正是我们需要的。但是这里存在一个致命的问题就是AdaGrad容易受到过去梯度的影响,陷入“过去“无法自拔,因为梯度很容易就会累积到一个很大的值,此时学习率就会被降低的很厉害,因此AdaGrad很容易过分的降低学习率率使其提前停止,怎么解决这个问题呢?RMSProp算法可以很好的解决该问题。

    RMSProp(均方根支柱)

    同样,RMSProp可以自动调整学习率。还有,RMSProp为每个参数选定不同的学习率。

    虽然AdaGrad在理论上有些较好的性质,但是在实践中表现的并不是很好,其根本原因就是随着训练周期的增长,学习率降低的很快。而RMSProp算法就在AdaGrad基础上引入了衰减因子,如下式,RMSProp在梯度累积的时候,会对“过去”与“现在”做一个平衡,通过超参数进行调节衰减量,常用的取值为0.9或者0.5(这一做法和SGD有异曲同工之处)

                                                              \ theta _i = \ beta \ cdot \ theta _i +(1+ \ beta)(\ bigtriangledown w_i)^ 2

    参数更新阶段,和AdaGrad相同,学习率除以历史梯度总和即可。

                                                               w_i = w_i  -  \ frac {\ alpha} {\ sqrt {\ theta _i} + \ delta} \ bigtriangledown w_i

    实践中,RMSProp更新方式对深度学习网络十分有效,是深度学习的最有效的更新方式之一。

    图形如下:

    下面接着那篇博客看,(这里还是通过动量过来的,原理是一样的,因为都是梯度的累加。这里大家不用迷惑,当你知道本质的东西以后,就知道通过表面看本质的的意义了)

    momprop2-2

    在第一个等式中,类似之前的动量法,我们计算了梯度平方的指数平均。由于我们为每个参数单独计算,这里的梯度GT表示正更新的参数上的梯度投影

    第二个等式根据指数平均决定步幅大小。我们选定一个初始学习率η,接着除以平均数。在我们上面举的例子中,W1的梯度指数平均比W2大得多,所以W1的学习步幅比W2小得多。这就帮助我们避免了脊间振荡,更快地向最小值移动。

    第三个等式不过是权重更新步骤。

    上面的等式中,超参数ρ一般定为0.9,但你可能需要加以调整。等式2中的ε是为了确保除数不为零,一般定为1E-10。

    注意RMSProp隐式地应用了模拟退火。在向最小值移动的过程中,RMSProp会自动降低学习步幅,以免跳过最小值。

    Adam自适应动量优化

    到目前为止,我们已经看到RMSProp和动量采用对比方法。虽然动量加速了我们对最小值方向的搜索,但RMSProp阻碍了我们在振荡方向上的搜索.Adam通过名字我们就可以看出他是基于动量和RMSProp的微调版本,该方法是目前深度学习中最流行的优化方法,在默认情况尽量使用亚当作为参数的更新方式

    首先计算当前最小批量数据梯度G

                                                          g = \ frac {1} {m} \ sum_ {j = 1} ^ {m} \ frac {\ partial L(y ^ j,f(x ^ j;  w))} {\ partial w}

    和动量学习法一样,计算衰减梯度五:

                                                          v = \ beta _1 \ cdot v +(1- \ beta _1)g

    和RMSProp算法类似,计算衰减学习率R:

                                                         r = \ beta _2 \ cdot r +(1- \ beta _2)g ^ 2

    最后更新参数:

                                                         w = w- \ frac {\ alpha} {\ sqrt {r} + \ delta} v

    上面就是RMSProp和动量的有机集合,使他们的优点集于一身,是不是很漂亮,但还是有一个问题就是开始时梯度会很小,R和v经常会接近0,因此我们需要初始给他一个?合适的值,这个值怎么给才合适呢先看下面的公式:

                                                   v_b = \ frac {v} {1- \ beta _1 ^ t},r_b = \ frac {r} {1- \ beta _2 ^ t}

    其中吨表示训练次数,刚开始动很大,随着训练次数吨的增加VB逐渐趋向于V,R类似下面给出总体的算法结构。

    初始化:

     给定数据集X = \ left \ {x ^ 1,x ^ 2,...,x ^ n \ right \},数据集标记为:Y = \ left \ {y ^ 1,y ^ 2,...,y ^ n \ right \},初始速度v,随机采样m条数据,训练周期k,学习器为F(X;  W)的,初始学习率\α,初始动量参数为\ beta_1,学习衰减参数\ beta_2\ delta = 10 ^ { -  7}

    训练:

            用于   t <k

                  {

                           1.随机采样米条数据:\ left \ {(x ^ 1,y ^ 1),...,(x ^ m,y ^ m)\ right \}

                           2.计算当前采样数据的梯度:g = \ frac {1} {m} \ sum_ {j = 1} ^ {m} \ frac {\ partial L(y ^ j,f(x ^ j;  w))} {\ partial w}

                           3.更新当前速度:v = \ beta _1 \ cdot v +(1- \ beta _1)g

                           4.更新当前学习率:r = \ beta _2 \ cdot r +(1- \ beta _2)g ^ 2

                           5.更新训练次数: T = t + 1的

                                                  v_b = \ frac {v} {1- \ beta _1 ^ t},r_b = \ frac {r} {1- \ beta _2 ^ t}

                           6.更新参数:w = w- \ frac {\ alpha} {\ sqrt {rb} + \ delta} vb

                   }         

     好,我们继续看看那篇博客:

    äºå½

    这里,我们计算了梯度的指数平均和梯度平方的指数平均(等式1和等式2)。为了得出学习步幅,等式3在学习率上乘以梯度的平均(类似动量),除以梯度平方平均的均方根(类似RMSProp)。等式4是权重更新步骤。

    超参数β1一般取0.9,β2一般取0.99.ε一般定为1E-10。

    结语

    本文介绍了三种应对病态曲率同时加速训练过程的梯度下降方法。

    在这三种方法之中,也许动量法用得更普遍,尽管从论文上看Adam更吸引人。经验表明这三种算法都能收敛到给定损失曲面的不同的最优局部极小值。然而,动量法看起来要比Adam更容易找到比较平坦的最小值,而自适应方法(自动调整学习率)倾向于迅速地收敛于较尖的最小值。比较平坦的最小值概括性更好。

    AA

     尽管这些方法有助于我们训练深度网络难以控制的损失平面,随着网络日益变深,它们开始变得不够用了。除了选择更好的优化方法,有相当多的研究试图寻找能够生成更平滑的损失曲面的架构。批量归一化(Batch Normalization)和残差连接(Residual Connections)正是这方面的两个例子。我们会在后续的文章中详细介绍它们。但这篇文章就到此为止了。欢迎在评论中提问。

    进一步阅读

    1. 关于指数加权平均值的视频
    2. 对于数学倾向,对动量的精彩解释
    3. 更多关于病理曲率和二阶优化
    4. 关于牛顿方法和一般优化

    原博客地址:https://blog.paperspace.com/intro-to-optimization-momentum-rmsprop-adam/(需要翻墙)

    这里需要说明的是,本人在那篇博客的基础上增添了SGD,动量,AdaGrad,RMSProp,亚当的算法推倒说明以及算法伪代码的实现,因此转载请注明出处,谢谢。本节到此结束,下一篇继续讲解梯度消失和激活函数的优化问题。

    展开全文
  • 目录 梯度下降 训练目标分析 GD与ODE 随机梯度下降 ...从一阶二阶 GD+Momentum 如何加速? Nesterov动量 Kramers方程 思考回顾   在本文中,我们来关心优化算法 SGD(stochastic gradient ...
  • 简单来说就是每个点的值都是前几个点当前点的加权平均。公式如下: beta的值越大,数据越平稳。但是beta的值过大会使数据有一种“滞后”的感觉,如图中的绿线。1.1 理解为什么叫“指数”加权平均呢?因为根据公式...
  • 深度学习中优化算法小结

    千次阅读 2018-08-15 16:08:40
    SGDM在SGD基础上增加了一阶动量来抑制震荡现象,AdaGrad和RMSProp在SGD基础上增加了二阶动量实现各个参数学习率的自适应调整。将一阶动量和二阶动量都用起来就是Adam了。 m t = β 1 ⋅ m t − 1 + ( 1 − β 1 ) ⋅...
  • 动量( Momentum )方法 为了解决随机梯度下降法山谷震荡鞍点停滞的问题,我们做一个简单的思维实验。想象一下纸团在山谷鞍点处的运动轨迹,在山谷中纸团受重力作用沿山道滚下,两边是不规则的山壁,纸团不可...
  •  5.2 Adam Adam = Adaptive + Momentum,顾名思义Adam集成了SGD的一阶动量和RMSProp的二阶动量。 SGD可以使用类似于物理中的动量来累积梯度,RMSProp可以使得收敛速度更快同时使得波动的幅度更小。Adam把它们的...
  • 计算t时刻一阶动量mt和二阶动量Vt     3.计算时刻下降梯度: ~     4.计算t+1时刻参数: 一阶动量:与梯度相关的函数 二阶动量:与梯度平方相关的函数 ~ 优化器演化流程:      SGD -> SGDM -> NAG -&...
  • 机器学习 之 优化器

    2019-04-23 19:12:00
    梯度下降优化法经历了 SGD→...一阶动量来给梯度下降法加入惯性(即,越陡的坡可以允许跑得更快些) 二阶动量引入之后,才真正意味着“自适应学习率”优化算法时代的到来 首先定义:  待优化参数:w 目标函数...
  • 机器学习优化器总结

    2019-06-27 10:12:00
    其中,mtvt分别为一阶动量和二阶动量项。β1,β2为动力值大小通常分别取0.90.999;m^t,v^t分别为各自的修正值。Wt表示t时刻即第t迭代模型的参数,gt=ΔJ(Wt)表示t次迭代代价函数关于W的梯度大小;ϵ是一个取值...
  • 其中动量系数一般取(0,1),直观上理解就是要是当前梯度方向与前一步的梯度方向一样,那么就增加这一步的权值更新,要是不一样就减少更新。
  • t 时刻 一阶动量 和 二阶动量 3、计算 t 时刻下降梯度: 4、计算 t+1 时刻参数: 一阶动量:与梯度相关的函数 二阶动量:与梯度平方相关的函数 不同的优化器实质上只是定义了不同的一阶动量和二阶动量公式。...
  • 因此,可以对一阶和二阶动量做偏置校正 (bias correction)。可以看到,迭代到后期 t 比较大,那么 a^t,b^t几乎为 0,就不会对 v p 有任何影响了。   5、每种优化方法,我都在MNIST数据集上自己实现了...
  • 深度学习: 鞍点

    千次阅读 2018-04-03 12:56:10
    Introduction 关于 鞍点 的定义: [1]: 鞍点附近的某些点比鞍点有... 鞍点处的一阶导为0,二阶导换正负号。 多变量函数: 鞍点处在某些方向往上曲,在其他方向往下曲。 Note: 在高维空间中,局...
  • 一文看懂各种神经网络优化算法:从梯度下降到Adam方法 编译自 Medium在调整模型更新权重偏差参数的方式时,你是否考虑过哪种优化算法能使模型产生更好且更快的效果?应该用梯度下降,随机梯度下降,还是Adam方法?...
  • 作者发现一阶动量和二阶动量在初始训练时很小,接近为0,因为β值很大,所以重新计算一个偏差来校正: m t ^ = m t 1 − β 1 t \hat{m_t}=\frac{m_t}{1-β_1^t} mt​^​=1−β1t​mt​​ v t ^ = v t 1 − β 2 t \...
  • Adam 最后但并非最不重要的是,Adam (Adaptive Moment Estimation)同时兼顾了动量和 RMSProp 的优点。Adam在实践中效果很好,因此在最近几年,它是深度学习问题的常用选择。 让我们来看看它是如何工作的: sum_of_...
  • 【Interview】Optimization

    2019-11-07 21:55:40
    SGD-M 和 RMSprop 的结合,把一阶动量和二阶动量都用起来(Adaptive + SGD-M) ,一阶二阶动量用指数移动平均计算,并做偏置校正 SGD-M 和 RMSprop 对二阶动量使用指数移动平均类似,Adam 中对一阶...
  • 为了充分利用大型强子对撞机数据的潜力,我们计算了包含在内的pTW光谱的二阶[next-to-next-lead-order(NNLO)] QCD校正以及W的光谱比率 -/ W +Z / W。 我们发现,将NNLO QCD校正内容包括在内,可以极大地改善...
  • SGD的一阶动量: 加上AdaDelta的二阶动量: 优化算法里最常见的两个超参数,都在这里了,前者控制一阶动量,后者控制二阶动量。 Nadam 最后是Nadam。我们说Adam是集大成者,但它居然遗漏了Nesterov,这还能忍?必须...
  • 把一阶动量和二阶动量都用起来,就是Adam了——Adaptive + Momentum。 SGD的一阶动量: 加上AdaDelta的二阶动量: 优化算法里最常见的两个超参数 就都在这里了,前者控制一阶动量,后者控制二阶动量。 Nadam ...
  • 动量是物理学中的概念,一般指物体在它运动方向上保持运动的趋势,是该物体质量速度的乘积。 在深度学习中,动量法是用之前积累动量来代替真正的梯度,这样,每个参数实际更新差值取决于最近一段时间内梯度的加权...
  • 最近在看Google的Deep Learning一书,看到优化方法那一部分,正巧之前用tensorflow也是对那些优化方法一知半解的,所以看完后就整理了下放上来,主要是一阶的梯度法,包括SGD, Momentum, Nesterov Momentum, AdaGrad...
  • 二阶优化算法Natural Gradient Descent,是从分布空间推导最速梯度下降方向的方法,牛顿方法有非常紧密的联系。Fisher Information Matrix往往可以用来代替牛顿法的Hessian矩阵计算。下面详细道来。
  • 在每个epoch : 1 计算目标函数关于当前参数的梯度: 2 根据历史梯度计算一阶动量和二阶动量: 3 计算当前时刻的下降梯度: 4 根据下降梯度进行更新: 掌握了这个框架,你可以轻轻松松设计自己的优化算法。...
  • 来源:Paperspace编译:weakish来源:论智编者按:DRDO研究人员Ayoosh Kathuria深入浅出地介绍了牛顿法、动量法、RMSProp、Adam优化算法。本系列的上...
  • 在每个epoch : 1 计算目标函数关于当前参数的梯度: 2 根据历史梯度计算一阶动量和二阶动量: 3 计算当前时刻的下降梯度: 4 根据下降梯度进行更新: 掌握了这个框架,你可以轻轻松松设计自己的优化算法。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,449
精华内容 579
关键字:

一阶动量和二阶动量