zoukankan      html  css  js  c++  java
  • 随机梯度下降、mini-batch梯度下降以及batch梯度下降

    训练神经网络的时候,基本就是三个步骤:

    1. 正向计算网络输出;
    2. 计算Loss;
    3. 反向传播,计算Loss的梯度来更新参数(即梯度下降)。

    在小的训练集上联系的时候,通常每次对所有样本计算Loss之后通过梯度下降的方式更新参数(批量梯度下降),但是在大的训练集时,这样每次计算所有样本的Loss再计算一次梯度更新参数的方式效率是很低的。因此就有了随机梯度下降和mini-batch梯度下降的方式。下面来具体讲讲。

    批量梯度下降(Batch Gradient Descent)

    上面说了,批量梯度下降就是每个epoch计算所有样本的Loss,进而计算梯度进行反向传播、参数更新:

    其中,(m) 为训练集样本数,(l) 为损失函数,(epsilon) 表示学习率。批量梯度下降的优缺点如下:

    • 优点
      每个epoch通过所有样本来计算Loss,这样计算出的Loss更能表示当前分类器在于整个训练集的表现,得到的梯度的方向也更能代表全局极小值点的方向。如果损失函数为凸函数,那么这种方式一定可以找到全局最优解。
    • 缺点
      每次都需要用所有样本来计算Loss,在样本数量非常大的时候即使也只能有限的并行计算,并且在每个epoch计算所有样本Loss后只更新一次参数,即只进行一次梯度下降操作,效率非常低。

    随机梯度下降(Stochastic Gradient Descent)

    先贴上随机梯度下降的伪代码

    随机梯度下降每次迭代(iteration)计算单个样本的损失并进行梯度下降更新参数,这样在每轮epoch就能进行 (m) 次参数更新。看优缺点吧:

    • 优点
      参数更新速度大大加快,因为计算完每个样本的Loss都会进行一次参数更新
    • 缺点
      1.计算量大且无法并行。批量梯度下降能够利用矩阵运算和并行计算来计算Loss,但是SGD每遍历到一个样本就进行梯度计算和参数下降,无法进行有效的并行计算。
      2.容易陷入局部最优导致模型准确率下降。因为单个样本的Loss无法代替全局Loss,这样计算出来的梯度方向也会和全局最优的方向存在偏离。但是由于样本数量多,总体的Loss会保持降低,只不过Loss的变化曲线会存在较大的波动。像下图这样:

    小批量梯度下降

    似乎随机梯度下降和批量梯度下降走向了两个计算,那么将这两种方法中和一下呢?这就得到了min-Batch Gradient Descent。

    小批量梯度下降将所有的训练样本划分到 (batches) 个min-batch中,每个mini-batch包含 (batch_size) 个训练样本。每个iteration计算一个mini-batch中的样本的Loss,进而进梯度下降和参数更新,这样兼顾了批量梯度下降的准确度和随机梯度下降的更新效率。
    可以看到,当 (batch\_size=m) 时,小批量梯度下降就变成了批量梯度下降;当 (batch\_size=1) ,就退化为了SGD。一般来说 (batch\_size) 取2的整数次方的值。

    注意,这里有个坑!

    事实上,我们平时用梯度下降的时候说的最多的SGD指的是小批量梯度下降,各种论文里所说的SGD也大都指的mini-batch梯度下降这种方式。tensorflow中也是通过定义batch_size的方式在优化过程中使用小批量梯度下降的方式(当然,也取决于batch_size的设置)。

  • 相关阅读:
    Android 逐帧动画
    MAP getLastKnownLocation()返回null的解决
    大数取余
    (a^b)%c和(a/b)%c
    HDU1046 Gridland
    顺序入栈的出栈方法种数
    HDU1021 Fibonacci Again
    HDU1019 Least Common Multiple
    HDU1018 Big Number
    HDU1013 Digital Roots
  • 原文地址:https://www.cnblogs.com/rezero/p/13281899.html
Copyright © 2011-2022 走看看