文章目录
- 一、SGD,随机梯度下降
- 1.1、算法详解
- 1)MBSGD(Mini-batch Stochastic Gradient Descent)
- 2)动量法:momentum
- 3)NAG(Nesterov accelerated gradient)
- 4)权重衰减项(weight_decay)
- 5)总结
- 1.2、Pytorch实现:torch.optim.SGD
- 1.3、示例
- 二、Adagrad:自适应梯度
- 2.1、算法详解
- 2.2、Pytorch的实现:torch.optim.Adagrad
- 三、RMSprop
- 3.1、算法详解
- 3.2、Pytorch的实现:torch.optim.RMSprop
- 四、Adam
- 4.1、算法详解
- 4.2、Pytorch的实现:torch.optim.Adam
- 这个博客讲的非常清晰:https://blog.csdn.net/xian0710830114/article/details/126551268
一、SGD,随机梯度下降
1.1、算法详解
1)MBSGD(Mini-batch Stochastic Gradient Descent)
- 随机梯度下降其实可以有三种实现方式,最为常用,而且在pytorch中实现的也是小批量随机梯度下降。
- 有以下三种:
1)BGD(批量梯度下降法):每次迭代使用全部训练样本来计算梯度,并根据梯度的平均值来更新模型的参数。尽管 BGD 对参数更新的方向更稳定,但由于计算梯度需要考虑所有样本,因此在大规模数据集上会导致较高的计算开销。
2)SGD(随机梯度下降法):在每次迭代中,随机选择一个样本来计算梯度并更新模型的参数。与 BGD 不同,SGD 每次只使用一个样本,因此计算效率更高。然而,由于单个样本的梯度估计可能存在噪声,SGD 的参数更新方向更加不稳定,收敛速度也相对较慢。
3)MBSGD(小批量随机梯度下降法):MBGD 是 BGD 和 SGD 的折中方法。在每次迭代中,随机选择一个小批量的样本来计算梯度,并根据梯度的平均值来更新模型的参数。这样可以减少计算开销,并且相对于 SGD 而言,参数更新方向更加稳定。
- 对于含有 n个训练样本的数据集,每次参数更新,选择一个大小为 m(m<n) 的mini-batch数据样本计算其梯度,其参数更新公式如下,其中 j 是一个batch的开始:
- 小批量随机梯度下降可以加速收敛,一定程度上有摆脱局部最优的能力(起码比SGD好),但是又可能会存在噪声。
2)动量法:momentum
- 动量(Momentum)是一种优化梯度下降算法的技术,用于加速模型参数的更新,并帮助模型跳出局部最优解。
- 它在训练过程中考虑了之前参数更新的方向和速度。通过将当前梯度与过去梯度加权平均,来获取即将更新的梯度。
- 如图b,可以看出能够加速收敛
- 动量项通常设置为0.9或类似值。
- 参数更新公式如下,其中ρ 是动量衰减率,m是速率(即一阶动量):
3)NAG(Nesterov accelerated gradient)
- 暂时略过,其实它也是加速收敛的方法
4)权重衰减项(weight_decay)
- weight_decay通过对模型的权重进行惩罚来减小权重的大小,用于防止模型过拟合。(简单来说就是控制了模型复杂度,即强制的使权重不会特别大,因为进行了权重衰减,大权重衰减的就多)
- 其实就相当于在梯度后面增加了一个wieght_decay
×
\times
×
θ
t
−
1
\theta_{t-1}
θt−1
g t = g t + λ θ t − 1 g_t = g_t + \lambda\theta_{t-1} gt=gt+λθt−1 - 其实就是在梯度中,增加了权重衰减。weight_decay 用于控制模型权重衰减(weight decay)的程度。
- 较小的 weight_decay 值会使权重衰减的影响较小,而较大的值会使权重衰减的影响更显著。
- 这与岭回归类似,岭回归是在损失函数中增加了L2范数的约束,用于防止过拟合(尤其是当特征数大于样本数时,导致多重非线性)
5)总结
- 优点:收敛速度变快,有一定摆脱局部最优的能力
- 缺点:需要手动调参,例如学习率等
1.2、Pytorch实现:torch.optim.SGD
CLASS torch.optim.SGD(params, lr=<required parameter>, momentum=0, dampening=0, weight_decay=0, nesterov=False, maximize=False)
""
params(iterable)- 参数组,优化器要优化的那部分参数。
lr(float)- 初始学习率,可按需随着训练过程不断调整学习率。
momentum(float)- 动量,通常设置为 0.9,0.8
weight_decay(float)- 权重衰减系数,也就是 L2 正则项的系数
nesterov(bool)- bool 选项,是否使用 NAG(Nesterov accelerated gradient)
maximize(bool)- 最大化还是最小化损失函数,默认是最小化,即False
""
1.3、示例
SGD优化器计算过程(以线性回归为例)
建立模型为:y = w^Tx = w1x1+w2x2+w3x3
初始化:y=1*x1+1*x2+1*x3,三个参数w为[1, 1, 1]
损失函数:
l = (pred-gt)**2 = (w1x1+w2x2+w3x3) ** 2
求导(链式法则,先对pred求导,再对w求导):
l'(w1) = 2(pred-gt)*x1
l'(w2) = 2(pred-gt)*x2
l'(w3) = 2(pred-gt)*x3
输入数据:
x = tensor([ 1.0943, 1.3479, -1.6927])
预测结果:
p = 1*1.0943+1*1.3479+1*-1.6927=0.7495
1)当weight_decay = 0
输出梯度:grad: tensor([[ 2.8188, 3.4719, -4.3600]])
手动计算验证:
l'(w1) = 2*(0.7495- -0.5384)*1.0943=2.81869794
l'(w2) = 2*(0.7495- -0.5384)*1.3479=3.47192082
l'(w3) = 2*(0.7495- -0.5384)*-1.6927=-4.36005666
权重更新:lr = 0.01
w = tensor([[0.9718, 0.9653, 1.0436]], requires_grad=True)
w1 = 1-0.01*2.81869794=0.9718130206
w2 = 1-0.01*3.47192082=0.9652807918
w3 = 1-0.01*-4.36005666=1.0436005666
2)当weight_decay = 0.1,lr = 0.01
输出梯度:grad: tensor([[ 2.8188, 3.4719, -4.3600]])
l'(w1) = l`(w1) + 0.1*1=2.9188
w1:= 1-0.01*2.9188 = 0.9708
参考链接:https://blog.csdn.net/qq_39707285/article/details/124257377
二、Adagrad:自适应梯度
2.1、算法详解
-
Adagrad优化算法可以自适应调整不同参数的学习率大小,用于解决这样一个问题:常见特征(频繁特征)的参数更新较快,而不常见特征(稀疏特征)的更新较慢
-
Adagrad优化算法是引入了二阶动量,即 v t v_t vt,表示之前所有时间步长(iteration/epoch)的历史梯度的平方和。再将学习率变为 η v t + ε \frac{\eta }{\sqrt{v_t+\varepsilon } } vt+εη,那么学习率就可以自适应更新:如果梯度大(更新较快),学习率就会降低;如果梯度小(更新较慢),学习率就会升高。
-
通过这种自适应调整学习率的方式,每个参数都分别拥有自己的学习率。使得对稀疏特征和频繁特征都能得到较好的更新效果。
-
总结:
优点:Adagrad可以自适应调整学习率,使得对稀疏特征和频繁特征都能得到较好的更新效果。
缺点:仍需要手工设置一个全局学习率;在分母中累积平方梯度,因此在训练过程中累积和不断增长。这会导致学习率不断变小并最终变得无限小,使模型不能继续更新。
2.2、Pytorch的实现:torch.optim.Adagrad
CLASS torch.optim.Adagrad(params, lr=0.01, lr_decay=0, weight_decay=0, initial_accumulator_value=0)
''
params (iterable) – 待优化参数的iterable或者是定义了参数组的dict
lr (float, 可选) – 学习率(默认: 1e-2)
lr_decay (float, 可选) – 学习率衰减(默认: 0)
weight_decay (float, 可选) – 权重衰减(L2惩罚)(默认: 0)
initial_accumulator_value - 累加器的起始值,必须为正。
''
三、RMSprop
3.1、算法详解
- RMSprop是对 Adagrad 的一种改进,将AdaGrad的梯度平方和累加 改为 指数加权的移动平均,参数更新公式:
- RMSprop 通过对梯度平方进行移动平均来计算参数的自适应学习率。具体来说,它引入了一个衰减系数(decay rate,即 ρ \rho ρ,一般设为0.99),用于控制历史梯度平方的权重。
- 可以使学习率的调整更加平稳
3.2、Pytorch的实现:torch.optim.RMSprop
CLASS torch.optim.RMSprop(params, lr=0.01, alpha=0.99, eps=1e-08, weight_decay=0, momentum=0, centered=False)
''
params (iterable) – 待优化参数的iterable或者是定义了参数组的dict
lr (float, 可选) – 学习率(默认:1e-2)
momentum (float, 可选) – 动量因子(默认:0)
alpha (float, 可选) – 平滑常数(默认:0.99)
eps (float, 可选) – 为了增加数值计算的稳定性而加到分母里的项(默认:1e-8)
weight_decay (float, 可选) – 权重衰减(L2惩罚)(默认: 0)
centered (bool, 可选) – 如果为True,计算中心化的RMSProp,并且用它的方差预测值对梯度进行归一化
''
四、Adam
4.1、算法详解
- Adam算法结合了Momentum 和 RMSprop,并进行了偏差修正。
- 也可以从数学理论上解释:Adam 利用梯度的一阶矩估计(momentum)结合过去梯度的更新方向以确定当前梯度的方向,以及二阶矩估计(梯度平方的移动平均)动态的调整学习率。
1)梯度一阶矩估计(通常称为动量):它表示先前梯度的指数加权移动平均,类似于动量优化算法中的动量项。它考虑了过去梯度的方向,并在更新时产生相关影响,有助于加速收敛。
2)梯度二阶矩估计(称为自适应学习率):它表示先前梯度的平方的指数加权移动平均。它衡量了过去梯度大小的变化情况,用于自适应地调整学习率,使得在梯度变化较大时减小学习率,在梯度变化较小时增加学习率。
- Adam的优点主要在于经过偏置校正后,每一次迭代学习率都有个确定范围,使得参数比较平稳。
- 总结:
1)自适应学习率:根据梯度的二阶矩估计自动调整学习率大小,在梯度变化较大时减小学习率,在梯度变化较小时增加学习率。这种自适应性使得Adam算法对于不同参数和数据集具有较好的适应性,可以更快地收敛到最优解。
2)动量:利用梯度的一阶矩估计(动量)来考虑过去梯度的方向信息,从而加速模型训练的收敛过程。动量的引入有助于跳出局部最优解。
4.2、Pytorch的实现:torch.optim.Adam
CLASS torch.optim.Adam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0, amsgrad=False)
''
params (iterable) – 待优化参数的iterable或者是定义了参数组的dict
lr (float, 可选) – 学习率(默认:1e-3)
betas (Tuple[float,float], 可选) – 用于计算梯度以及梯度平方的移动平均值的系数(默认:0.9,0.999)
eps (float, 可选) – 为了增加数值计算的稳定性而加到分母里的项(默认:1e-8)
weight_decay (float, 可选) – 权重衰减(L2惩罚)(默认: 0)
''