zl程序教程

您现在的位置是:首页 >  .Net

当前栏目

机器学习——批量梯度下降法、随机梯度下降法、小批量梯度下降法

2023-02-18 16:33:48 时间

1 批量梯度下降

  在经典的随机梯度下降算法(批量梯度下降)中,迭代下降公式是

    $x_{t+1}=x_{t}-\alpha \nabla f\left(x_{t}\right)$

  以一元线性回归的目标函数为例

    $\sum \limits _{i=1}^{n}\left(a x_{i}+b-y_{i}\right)^{2}$

  其梯度表达为

    $\left(\frac{\partial g}{\partial a}, \frac{\partial g}{\partial b}\right)=\left(2 \sum \limits_{i=1}^{n} x_{i}\left(a x_{i}+b-y_{i}\right), 2 \sum \limits_{i=1}^{n}\left(a x_{i}+b-y_{i}\right)\right)$

  可以看到,这里的梯度计算,使用了所有的样本数据。倘若数据集有 1000 组数据,那就需要计算 1000 次才可以得到梯度,倘若数据集有一亿组数据,就需要计算一亿次,其时间复杂度是 $O(n)$ 。当样本数据较多时,对于模型的求解,学习一次的过程是很浪费时间的。 


  举例:使用只含有一个特征线性回归来展开。
  线性回归的假设函数为:

    $h_{\theta} (x^{(i)})=\theta_1 x^{(i)}+\theta_0$

  其中 $i=1,2,...,n$,其中 $n$ 表示样本数。
  对应的目标函数(代价函数)即为:

    $J(\theta_0, \theta_1) = \frac{1}{2n} \sum_ \limits {i=1}^{n}(h_{\theta}(x^{(i)}) - y^{(i)})^2$

  批量梯度下降法是指在每一次迭代时使用所有样本来进行梯度的更新

  步骤如下:
  (1)对目标函数求偏导

    $\frac{\Delta J(\theta_0,\theta_1)}{\Delta \theta_j} = \frac{1}{n} \sum_ \limits {i=1}^{n} (h_{\theta}(x^{(i)})-y^{(i)})x_j^{(i)}$

  其中 $i=1,2,...,n$,$n$ 表示样本数,$j = 0,1$ 表示特征数,这里使用了偏置项 $x_0^{(i)} = 1$
  (2)每次迭代对参数进行更新:

    $\theta_j := \theta_j - \alpha \frac{1}{n} \sum_ \limits {i=1}^{n} (h_{\theta}(x^{(i)})-y^{(i)})x_j^{(i)}$

  注意:这里更新时存在一个求和函数,即为对所有样本进行计算处理,可与下文SGD法进行比较。
  优点:
  (1)一次迭代是对所有样本进行计算,此时利用矩阵进行操作,实现了并行。
  (2)由全数据集确定的方向能够更好地代表样本总体,从而更准确地朝向极值所在的方向。当目标函数为凸函数时,BGD一定能够得到全局最优。
  缺点:
  (1)当样本数目 $n$ 很大时,每迭代一步都需要对所有样本计算,训练过程会很慢。
  从迭代的次数上来看,BGD迭代的次数相对较少。

2 随机梯度下降

  为解决批量梯度下降法学习一次浪费时间的问题,因此,可以在所有的样本数据中选择随机的一个实例,用这个实例所包含的数据计算“梯度”。此时的梯度为

    $\left(\frac{\partial g}{\partial a}, \frac{\partial g}{\partial b}\right)=\left(2 x_{i}\left(a x_{i}+b-y_{i}\right), 2\left(a x_{i}+b-y_{i}\right)\right)$

  其中 $\left(x_{i}, y_{i}\right)$ 是一个随机选中的样本。
  到了这里,可能会存在一定的疑问,因为目标函数(代价函数)

    $\sum \limits _{i=1}^{n}\left(a x_{i}+b-y_{i}\right)^{2}$

  其梯度并不是

    $\left(\frac{\partial g}{\partial a}, \frac{\partial g}{\partial b}\right)=\left(2 x_{i}\left(a x_{i}+b-y_{i}\right), 2\left(a x_{i}+b-y_{i}\right)\right)$

  那么这个方向还是不是可以使目标函数值下降的方向?只能说,对于一次迭代而言,不一定,但是站在宏观的角度去考虑,最后还是很有机会收敛到近似最优解的。
  事实上,目标函数可以写成

    $\sum \limits_{i=1}^{n} S(i), \ \  S(i)=\left(a x_{i}+b-y_{i}\right)^{2}$

  所以梯度则是

    $\sum \limits _{i=1}^{n} \nabla S(i)$

  这时,优化目标是所有样本的损失函数之和,所以在梯度下降时,自然而然是朝着使总的偏差缩小的方向去移动的。而对于随机梯度下降,每一步迭代的优化目标函数不是始终不变的,其变化的范围就是

    $S(i), i=1,2,3 \ldots$

  在第 $i$ 步,随机地选中  $S(i)$ 作为优化目标,其梯度便是

    $\left(\frac{\partial g}{\partial a}, \frac{\partial g}{\partial b}\right)=\left(2 x_{i}\left(a x_{i}+b-y_{i}\right), 2\left(a x_{i}+b-y_{i}\right)\right)$

  而在第 $i+1$ 步,我们的优化目标可能就变成了

    $\min S(j)$

  此时,梯度也自然变成了

    $\left(\frac{\partial g}{\partial a}, \frac{\partial g}{\partial b}\right)=\left(2 x_{j}\left(a x_{j}+b-y_{j}\right), 2\left(a x_{j}+b-y_{j}\right)\right)$

  显然,随机梯度下降迭代过程中,考虑的下降方向并不是全局下降方向,而是使得某个随机选中的样本的损失函数下降的方向。在一步迭代中,这种局部样本的下降未必会导致全局损失的下降,但是当迭代次数足够的时候,绝大部分样本都会被考虑到,最终一步一步走向全局最优解。
  所以,随机梯度下降相对于梯度下降而言,其根本区别在于每一步迭代时需要优化的目标函数不同。对于经典的梯度下降,其每一步的目标函数(损失函数)是一样的,即所有样本的(平均)损失函数之和。而对于随机梯度下降而言,其每一步的目标函数是被随机选中的某个样本的损失函数,并不是一直不变的。
  可以通过下面这个视频直观地感受一下随机梯度下降。

  SGD可视化视频

  上面的每个小球,可以将其理解为随机梯度下降过程中由于随机性而带来的迭代情况的分支。正是由于这种随机性的存在,每个球可以较为自由地选择运动方向,有些就停在某个位置,有些则一路向下。当迭代的次数足够多时,总会有某个球的路径十分顺畅,最终到达全局最优解的附近。随机梯度下降相对于经典梯度下降,其逃离局部最优的能力更强。因为一旦到达了某个样本的局部最优,随着目标函数的更换,很可能不再是另一个样本的局部最优,迭代就可以继续进行。
  当然,随机梯度下降的缺点也是存在的,即它很可能无法收敛到全局最优解。什么是全局最优,是 $\sum \limits _{i=1}^{n}\left(a x_{i}+b-y_{i}\right)^{2}$ 达到最小嘛?还是每一个 $S(i)$ 都无法继续下降?一般而言,前者可能更容易衡量一些,我们也更偏向于使用总体的最优作为全局最优,而非每一个样本的最优。而对于随机梯度下降,即使已经达到了总体全局最优,对于某些样本而言,其可能依然可以继续下降,所以一旦选中了这些样本,就要偏离全局最优点。所以随机梯度下降最终的收敛性确实值得考虑。
  但总的来说,随机梯度下降还是很不错的,特别是对于大样本的处理情况,每一次迭代中 O(1) 的计算开销无疑会轻松很多,至于最终的收敛问题,则要根据迭代次数,终止准则等进行一个衡量取舍啦。


  随机梯度下降法不同于批量梯度下降,随机梯度下降是每次迭代使用一个样本来对参数进行更新。使得训练速度加快。

  对于一个样本的目标函数为:

    $J^{(i)}(\theta_0,\theta_1) = \frac{1}{2}(h_{\theta}(x^{(i)})-y^{(i)})^2$

  (1)对目标函数求偏导:

    $\frac{\Delta J^{(i)}(\theta_0,\theta_1)}{\theta_j} = (h_{\theta}(x^{(i)})-y^{(i)})x^{(i)}_j$

  (2)参数更新:

    $\theta_j := \theta_j - \alpha  (h_{\theta}(x^{(i)})-y^{(i)})x^{(i)}_j$

  注意:这里不再有求和符号

小批量梯度下降

  在了解了经典的梯度下降和随机梯度下降,并且知道其不同之处主要在于迭代过程中目标函数选择的不同。经典梯度下降虽然稳定性比较强,但是大样本情况下迭代速度较慢;随机梯度下降虽然每一步迭代计算较快,但是其稳定性不太好,而且实际使用中,参数的调整往往更加麻烦。
  所以,为了协调稳定性和速度,小批量梯度下降应运而生。小批量梯度下降法和前面两种梯度下降的主要区别就是每一步迭代过程中目标函数的选择不同。小批量梯度下降是从 $n$ 个样本中随机且不重复地选择 $m$ 个进行损失函数的求和
    $\sum \limits _{i=1}^{m}\left(w x_{i}+b-y_{i}\right)^{2}$
  并将其作为每一步迭代过程中的目标函数。此时,迭代公式中的梯度也就变成了
    $\left(\frac{\partial g}{\partial w}, \frac{\partial g}{\partial b}\right)=\left(2 \sum \limits _{i=1}^{m} x_{i}\left(w x_{i}+b-y_{i}\right), 2 \sum \limits _{i=1}^{m}\left(w x_{i}+b-y_{i}\right)\right)$
  显然,$m=1$ 时,小批量梯度下降就是随机梯度下降,$m=n $ 时,小批量梯度下降就是经典梯度下降。同时,我们也把经典的梯度下降方法称之为全批量梯度下降。这里的 $m$ 一般称之为批量尺寸,其值的选择对于收敛的稳定性和速度有着较大的影响,也是一个技术活。
  其他的也没什么好分析的了,基本上和随机梯度下降差不多。


  小批量梯度下降,是对批量梯度下降以及随机梯度下降的一个折中办法。其思想是:每次迭代 使用  batch_size 个样本来对参数进行更新。

  这里我们假设$batch_size = 10$,样本数$m=1000$

   优点:
  (1)通过矩阵运算,每次在一个 batch 上优化神经网络参数并不会比单个数据慢太多。
  (2)每次使用一个 batch 可以大大减小收敛所需要的迭代次数,同时可以使收敛到的结果更加接近梯度下降的效果。(比如上例中的30W,设置 batch_size=100 时,需要迭代 3000 次,远小于 SGD 的 30W 次)
  (3)可实现并行化。
  缺点:
  (1)batch_size的不当选择可能会带来一些问题。
  batcha_size的选择带来的影响:
  (1)在合理地范围内,增大batch_size的好处:
    a. 内存利用率提高了,大矩阵乘法的并行化效率提高。
    b. 跑完一次 epoch(全数据集)所需的迭代次数减少,对于相同数据量的处理速度进一步加快。
    c. 在一定范围内,一般来说 Batch_Size 越大,其确定的下降方向越准,引起训练震荡越小。
  (2)盲目增大batch_size的坏处:
    a. 内存利用率提高了,但是内存容量可能撑不住了。
    b. 跑完一次 epoch(全数据集)所需的迭代次数减少,要想达到相同的精度,其所花费的时间大大增加了,从而对参数的修正也就显得更加缓慢。
    c. Batch_Size 增大到一定程度,其确定的下降方向已经基本不再变化。