基于Pytorch的不同优化算法(Adagrad、RMSProp、AdaDelta、Adam四种)在 MNIST 数据集上的性能比较与可视化

本文主要介绍了Adagrad、RMSProp、AdaDelta、Adam四种经典的深度学习的优化算法。在基于 PyTorch 的 MNIST数字图像数据集分类模型训练与评估的简单练习-CSDN博客一文中展示了深度学习的简单框架,在其基础上通过修改优化器便能得到不同优化方法的结果。下面将只展示修改的优化器部分。

一、Adagrad方法


该方法通过初始化一个变量s为0,然后每次将该参数的梯度平方求和累加到这个变量s上,然后更新参数设置学习率为

\frac{\eta}{\sqrt{s+\epsilon}}

此处的\epsilon是为了防止s为零时,导致学习率为无穷大而设置的一个很小的正数,通常设置为10^{-10}。该方法核心是在梯度一直特别大时,学习率就会特别小,从而防止震荡。当梯度一直特别小时,学习率就会变大,从而快速更新参数。

但是该方法存在一些问题,比如,s是损失值平方的累加,会越来越大,导致后期学习率会很小,导致还没收敛,学习率就特别低,使得进程十分缓慢。

优化器设置如下:

optimizer = torch.optim.Adagrad(net.parameters(), lr=0.01)

 如果我们想自己实现优化函数,代码如下所示:

def sgd_adagrad(parameters, sqrs, learn_rate):
    eps = 1e-10
    for param, sqr in zip(parameters, sqrs):
        sqr[:] = sqr + param.grad.data ** 2
        change = learn_rate / torch.sqrt(sqr + eps) * param.grad.data
        param.data = param.data - change

 其中sqrs需要初始化为与参数大小相同的张量。

二、RMSProp方法


该方法仍然使用到了损失值平方累加,但在处理上与Adagrad方法不同。 该方法在损失值平方累加上还添加了一个指数加权移动平均来计算s,如下所示:

s_i=\alpha s_{i-1}+(1-\alpha) g^2

其中\alpha就是添加的权重,而g是当前参数的梯度值。最终学习率就与上面的Adagrad方法一样了。

 \frac{\eta}{\sqrt{s+\epsilon}}

拥有\alpha这个参数后,在每次更新参数时,对于梯度较大的方向,其学习率会相对较小,从而避免了学习过程中的大幅震荡;对于梯度较小的方向,学习率相对较大,能够更快地收敛到最优值。同时这个系数也使得到了训练后期s不会打太,使得其依然能找到比较优秀的结果。

优化器设置如下:

optimizer = torch.optim.RMSprop(net.parameters(), 0.001, 0.9)

若自己实现优化器,代码如下:

def rmsprop(parameters, sqrs, lr, alpha):
    eps = 1e-10
    for param, sqr in zip(parameters, sqrs):
        sqr[:] = alpha * sqr + (1 - alpha) * param.grad.data ** 2
        div = lr / torch.sqrt(sqr + eps) * param.grad.data
        param.data = param.data - div

 其中sqrs需要初始化为与参数大小相同的张量,alpha通常设置为0.9。

三、AdaDelta方法


该方法算是Adagrad方法的延伸,与RMSProp方法一样,都是为了解决在Adagrad方法中学习率不断减小的问题。

该方法同RMSProp一样,先使用移动平均来计算

 s_i=\alpha s_{i-1}+(1-\alpha) g^2

此处的\alphag同RMSProp方法的一样,分别是移动平均系数与当前参数梯度。然后计算参数更新的变化量,如下:

g'=\frac{\sqrt{\Delta\theta+\epsilon}}{\sqrt{s+\epsilon}}g

\Delta\theta初始值设置为0的张量,更新\Delta\theta与上述更新s的方式相同。

\Delta\theta=\alpha\Delta\theta+(1-\alpha)g'^2

最终参数更新如下。

\theta=\theta-g'

优化器设置如下:

optimizer = torch.optim.Adadelta(net.parameters(), rho=0.9)

若自己实现优化器,代码如下:

ef adadelta(parameters, sqrs, deltas, alpha):
    eps = 1e-6
    for param, sqr, delta in zip(parameters, sqrs, deltas):
        sqr[:] = alpha * sqr + (1 - alpha) * param.grad.data ** 2
        cur_delta = torch.sqrt(delta + eps) / torch.sqrt(sqr + eps) * param.grad.data
        delta[:] = alpha * delta + (1 - alpha) * cur_delta ** 2
        param.data = param.data - cur_delta

其中sqrs、deltas均为初始为0的张量,alpha是平均移动系数。

四、Adam方法


该方法结合了动量法与RMSProp法,首先他将vs都设置为0的张量,然后通过迭代计算他们的更新值。

v=\beta_{1}v+(1-\beta_{1})g\\s=\beta_{2}s+(1-\beta_{2})g^{2}

 在该方法中为了减少s与v初始化为0张量对加权平均移动的影响,每次都会对vs做以下操作。

\hat{v}=\frac{v}{1-\beta_{1}^{t}}\\\hat{s}=\frac{s}{1-\beta_{2}^{t}}

这里t是训练的次数,当\beta_{1}\beta_{2}位于0到1之间时,当训练的次数足够多时,\beta_1^{t}\beta_2^{t}就越趋近于0,则不会影响vs了。算法作者建议将\beta_1\beta_2分别设置成0.9和0.999。然后将计算的到的\hat{v}\hat{s}用于计算更新参数的变化之。

 g^{\prime}=\frac{\eta\hat{v}}{\sqrt{\hat{s}+\epsilon}}

最后进行参数更新。

\theta_i=\theta_{i-1}-g'

该优化算法结合动量法与RMSProp各自的优点,同时具有较好的参数更新稳定性。

优化器设置如下:

optimizer = torch.optim.Adam(net.parameters(), lr=0.001)

若自己实现优化器,代码如下:

def adam(parameters, vs, sqrs, lr, t, beta1=0.9, beta2=0.999):
    eps = 1e-8
    for param, v, sqr in zip(parameters, vs, sqrs):
        v[:] = beta1 * v + (1 - beta1) * param.grad.data
        sqr[:] = beta2 * sqr + (1 - beta2) * param.grad.data ** 2
        v_hat = v / (1 - beta1 ** t)
        s_hat = sqr / (1 - beta2 ** t)
        param.data = param.data - lr * v_hat / torch.sqrt(s_hat + eps)

其中vs和sqrs为初始化为0的张量,t为训练的次数。

五、对比


使用上述四种方法训练相同的数据,通过matplotlab可视化以及控制台输出得到如下结果。

***********adagrad************
epoch:1,Train Loss:0.41554
epoch:2,Train Loss:0.26491
epoch:3,Train Loss:0.22543
epoch:4,Train Loss:0.20005
epoch:5,Train Loss:0.18108
所用时间为:19.04406
***********RMSProp************
epoch:1,Train Loss:0.37212
epoch:2,Train Loss:0.16852
epoch:3,Train Loss:0.12333
epoch:4,Train Loss:0.10148
epoch:5,Train Loss:0.08937
所用时间为:21.77974s
***********adadelt************
epoch:1,Train Loss:0.36424
epoch:2,Train Loss:0.15955
epoch:3,Train Loss:0.12493
epoch:4,Train Loss:0.10394
epoch:5,Train Loss:0.08919
所用时间为:20.12976
*************Adam*************
epoch:1,Train Loss:0.35856
epoch:2,Train Loss:0.17507
epoch:3,Train Loss:0.12567
epoch:4,Train Loss:0.10140
epoch:5,Train Loss:0.08493
所用时间为:23.16603

  • 17
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值