行业资讯
Adam优化器在更新模型参数时,使用的训练样本范围是什么?

BGD(批量梯度下降法)、SGD(随机梯度下降法)、MBGD(小批量梯度下降法)等等,目前有相当多的资料,解释的非常清晰。主要区别是,更新模型权重时损失函数值的由来:分别是整体训练样本随机单个训练样本小批训练样本

可是针对Adam类的优化方法,通常只解释其中“惯性量的变化算法”以及“学习率的变化算法”等等。

我的疑惑点是:使用Adam类的优化方法时,损失函数值是如何得到的?是整体训练样本、随机单个训练样本、小批量训练样本,还是其他的不同方法?

谢邀,

Adam对大小批量都适用,不过大家通常用的都是小批量的样本。

SGD是MBGD在批量数等于1的特例,通常提起时,和MBGD意义混用。SGD之后的优化器,大多旨在解决SGD受小批量样本带来的随机噪声影响,这些噪声会让下降方向疯狂摆动而难以收敛。同时,一些优化器也在解决梯度下降方向受损失函数空间形态影响而很难靠近最优点的问题。(想象一下,用等势面类比,一边长,一边窄的地形会让总的下降方向偏向长的地形方向,而不是直接往最低点方向)

如果是整体数据集进行训练,不会有前一个噪声问题。那么Adam只对后一个问题有意义。

另外,“惯性量”momentum有一个好处是,在接近“山谷”的时候“速度”会降下来,因而不会冲过头了。

卸腰。建议寻找一下Adam/AdamW的原始论文,其中伪代码能给出你想要的答案。

对于你列举的这几种模式,其实Adam都支持。可以简单的把Adam看做是momentum和SGD的结合,利用偏导矩阵的一阶矩和二阶矩估计来加速收敛(修改导数与学习率),而对具体传入的目标函数模式没有严格要求。更一般的描述方式是:只要能将各维度偏导描述成偏导矩阵及其线性组合形式,就可以利用Adam优化器求解。

adam也是sgd的变种,在momentum的基础上增加了adaptive的机制,在系数update稀疏的时候比较有用。可以用在sgd和momentum上的batch size理论上都可以用在adam上,最小为1,最大为整个数据集,一般都是mini batch。计算loss和你选用的优化器没有关系,优化器是优化loss的。同一个loss,你可以选用sgd也可以用adam

不过由于adam和momentum都需要计算目前各个方向导数的1st或者2nd momentum的moving average,一般建议batch size不要选太小,否则震荡会很大

adam一般在训练前期loss下降会比较快,后期往往不如sgd,很多人建议逐步降低adam里的两个beta最后把adam变为sgd

首先诸多优化器例如SGD、SGD+Momentum、AdaGrad、RMSProp、Adam等等的原理都是梯度下降,只是随着解决问题的复杂性,优化器不断改进。至于训练样本的size选择,跟优化器是两个概念,所有优化器对大小批量都是支持的,但目前比较普遍的做法都采用了小批量样本。

既然提到优化器,我们就总结一下优化器的发展过程。

首先最先提出的是SGD(随机梯度下降),也是最简单直观的方法。虽然严格意义上是训练批量样本为1,但实际说起SGD时,其实代指小批量样本梯度下降。小批量样本训练带来了一个好处就是单次梯度更新时间变短,但是也有一个弊端,一方面随机性梯度相对于全局梯度抖动明显,另一方面如果梯度在不同方向上的敏感程度不同,也会出现zigzag现象,导致全局收敛缓慢。SGD的另一弊病在于特征维度变高时,容易陷入局部最优和在鞍点附近下降缓慢,因此,需要提出一种解决这些弊端的优化器。

SGD+Momentum优化器的提出缓解了上述SGD的两大弊端。在梯度下降过程中,给梯度加上了一个动量,使其可以越过局部最优和鞍点继续下降。并且在加入动量后,在一定程度上克服了噪音问题,缓解了zigzag现象。代码如下:

dx=computer_gradient(x)
v=mu*v - learning_rate*dx
x +=v

之后也出现了Nesterov Momentum的加入动量的梯度下降方式。

AdaGrad通过除以先前累加的梯度更好的解决了zigzag现象。代码如下:

dx=compute_gradient(x)
grad_squared +=dx*dx
x -=learning_rate * dx / (np.sqrt(grad_squared) + 1e-7)

通过除以原来累加的梯度,更新幅度大的梯度除以更大值,反之更新幅度较小的梯度除以更小值,这样,zigzag现象将减小,但是随着训练次数的增加,grad_squared不断增加,会导致梯度下降缓慢。后来的RMSProp跟AdaGrad相似。代码如下:

dx=compute_gradient(x)
grad_squared +=decay_rate * grad_squared + (1—decay_rate)*dx*dx
x -=learning_rate * dx / (np.sqrt(grad_squared) + 1e-7)

Adam则像结合了动量和RMSProp的优化器,话不多说,代码如下:

dx=compute_gradiend(x)
first_moment=beta1 * first_moment + (1-beta1) * dx
second_moment=beta2 *second_moment +(1-beta2) * dx *dx
x -=learning_rate*first_moment / (np.sqrt(second_moment) + 1e-7)

其中first_moment是加入动量的过程,而second_moment则是用来算累加的梯度。由于在第一步通常将second_moment设为0,这会导致第一步更新过大,因此需要加入偏置项。所以完整的Adam代码如下:

dx=compute_gradiend(x)
first_moment=beta1 * first_moment + (1-beta1) * dx
second_moment=beta2 *second_moment +(1-beta2) * dx *dx
first_unbias=first_moment/(1-beta1**step)
second_unbias=second_moment/(1-beta2**step)
x -=learning_rate*first_moment / (np.sqrt(second_moment) + 1e-7)

参考内容

cs231n课程

平台注册入口