优化器介绍I——BGD/SGD/MBGD

本文最后更新于 2024年7月8日凌晨4点54分

优化器介绍I——BGD/SGD/MBGD

优化器介绍篇章1,这里介绍了三种梯度更新方法:BGD/SGD/MBGD,并实现公式推导。

优化器的作用

优化器的作用是更新模型参数,让损失函数尽可能减小,把参数往正确方向引导,让损失函数不断逼近全局最小值。

这个优化问题就像下山,损失函数是一座山(真实的损失函数是高维,这里理解为三维),我们要找到全局最小值。当前位置是在当前参数下的损失函数值,下山的方向是损失函数梯度的反方向(梯度是函数上升最快的方向),下山的步长是学习率决定的。

常见的优化器有:

  • BGD: Batch gradient descent
  • SGD: Stochastic gradient descent
  • MBGD: Mini-batch gradient descent
  • 使用动量的优化器方法(在优化器篇章2介绍)

首先区分epoch,batch size,iteration这几个概念:
每一个epoch会用到所有训练数据,每一次iteration后更新模型参数,batch size是每次iteration时输入给模型的样本个数。
假设现在训练集有1000个样本,会训练epoch=10次,batch size=50,则每个epoch里iteration的次数是$\frac{1000}{50}=20$,因为每次输入50个样本给模型,要把所有数据训练一次,需要输入20次,故一个epoch会更新20次参数。总共会更新$20 \times 10 = 200$次参数。

梯度更新的公式可以统一这样表示:

其中是在 $ \theta_{t+1}$ 是t+1时刻的参数,$ g_t $ 是t时刻的梯度,lr是学习率。

BGD batch gradient descent

BGD方法会让batch size=总样本数,即每次epoch会一次性把所有数据输入给模型,使用所有样本求loss,然后求这些loss的平均值,再反向传播更新参数。
也就是说,一个epoch里面只有一次iteration,一个epoch只更新一次参数,但会用到所有样本。
优点:能得到全局最优解,很稳定,容易并行实现;
缺点:训练很慢,需要很大的显存,因为batch size太大。

SGD 随机梯度下降

每一次iteration使用一个样本,即batch size=1,每次epoch更新N次参数,其中N是总样本数。每一个样本更新一次参数,迭代方向很不稳定,不容易收敛,但也不容易陷入局部最优。
优点:训练速度快,不容易陷入局部最优;
缺点:准确度低,不是每次迭代都朝着整体最优的方向,迭代方向不稳定,不容易并行实现。

mini-batch gradient descent

简称为mini-batch SGD,会设置合适的batch size=n。假设总样本数=N,每次epoch开始前,使用shuffle打乱样本顺序,然后顺序选择n个样本作为一个batch输入给模型。一个epoch有$\frac{N}{n}$次iteration,即一次epoch更新$\frac{N}{n}$次参数,每个iteration计算n个参数的loss,再计算loss的平均,反向求梯度更新参数。

现在代码中说的SGD一般都是指mini-batch SGD。

公式推导

上面讲的三种方法,BGD使用N个样本点来更新参数,SGD使用1个样本点更新参数,MBGD使用batch size=n个样本点更新参数。这里要思考,使用n个样本点更新参数时,到底是先求这n个loss,求loss的平均值,再计算梯度反向更新;还是先计算每个样本点的loss然后计算梯度,求梯度的平均值来更新参数?

我认为求loss的平均和求梯度的平均是同一个事情,是等价的。下面通过公式来说明:(注意下面的公式中$x^i$表示一个向量,表示$x_j$向量中的第j位,是一个值。)

假设这个模型是线性函数,其中$\theta_j$是第j个待训练参数,一共有n个待训练参数,即参数向量$\theta$的长度为 $n \times 1$:

下面计算一个样本点的损失,损失函数如下,其中x是输入向量,y是真实向量:

则,如果只使用1个输入样本x来更新参数,参数更新公式如下,其中$\alpha$是学习率,$\theta_j$是第j个参数:

下面求损失函数$J_{\theta}$相对于的$\theta_j$这个参数的偏导数,注意一共有n个待训练参数,$x_j$表示向量x的第j个位:

假设batch size=m,先计算m个loss的平均,再计算梯度更新如下(其中$x^i$表示第i个输入向量):

先计算m个样本对应的梯度,再计算梯度平均,再更新参数,如下:

所以先计算loss的平均然后梯度更新,和计算梯度的平均来更新,两个概念是一样的。

手动实现BGD/SGD/MBGD三种梯度更新的代码:
pytorch面试题II:梯度更新的代码实现

参考:

(梯度下降的三种形式BGD/SGD/MBGD)[https://www.cnblogs.com/zongfa/p/9293887.html]


优化器介绍I——BGD/SGD/MBGD
https://kangkang37.github.io/2024/07/05/optimizer/
作者
kangkang
发布于
2024年7月5日
许可协议