新闻资讯
Pytorch-优化器optimizer
发布时间:2024-04-15
  |  
阅读量:
字号:
A+ A- A
导数:函数在指定坐标轴上的变化率;
方向导数:指定方向上的变化率;
梯度:一个向量,方向为方向导数,取得最大值的方向;
?
梯度下降法的计算过程就是沿梯度下降的方向求解极小值,也可以沿梯度上升方向求解最大值。?
参考知乎优化器的讲解,图片也是来自这里!
?
梯度下降
图1.梯度下降法

?

二、优化器基本属性

  • defaults:优化器超参数
  • state:参数的缓存,如momentum的缓存
  • params_groups:管理的参数组
  • _step_count:记录更新次数,学习率调整中使用

三、优化器基本方法

  • zero_grad():清空所管理参数的梯度
  • step():执行一步更新操作
  • add_param_group():添加参数组
  • state_dict():获取优化器当前状态信息字典
  • load_state_dict():加载状态信息字典

pytorch特性:张量梯度不自动清零。

四、以SGD优化器为例(随机梯度下降)

import torch.optim as optim

optim.SGD(params, lr=<required parameter>, momentum=0, dampening=0, weight_decay=0, nesterov=False)

 
 

原始的梯度下降法:没有添加momentum的情况下的计算公式:

W_{i+1}=W_{i}-lr*g(W_{i})? ? ? ------------------------------------------------(1)

其中的?lr?表示学习率,g(W_{i})?表示?W_{i}?的梯度,然后依次进行更新参数;

以实际代码来看一下不同的学习对梯度下降的影响!

以简单的二次函数:y = 4*x^{^{2}}? ,对这个函数的x进行求导数:y^{'} = 8*x

 
 
图2.二次函数:y = 4*x^2

?使用梯度下降法,即添加一个学习率的情况:这里我们选择从上图二次函数x = 2的时刻开始进行更新;

学习率具体作用是干嘛的呢?:可以理解为控制更新的步伐;

参考博文:

  1. 知乎:学习率
  2. 学习率的理解及如何调整学习率
 
 
 
 
图3.左图表示Loss的值,右边表表示从2开始的梯度下降

?此时的学习率设置为0.02,虽然可以到达最小值,但是速度还是很慢,需要走很多步;尝试设置大一点学习率,其实就是调参数;

最佳的学习率设置为:0.125,观察一下最终的效果如何,从下图可以看出相比上一个学习率而言,这个只需要两步就可以达到最小值;

图4.学习率设置为0.125

那么我们如何能够最快找到合适的学习率呢?如果我们站在上帝视角绝对可以!!!

下面我们看一下在多个学习率情况下的效果如何:

我们这里设置学习的范围为:[0.01,0.2]? 所有的学习率都设置在这个区间内

 
 

?

图5.多种学习率的情况

?从上图5可以看出,在iteration为0时,学习率为0.136时刻下降的最快!这就是针对二次函数?y = 4*x^{^{2}}?使用梯度下降法最佳的学习率!!!

但是梯度下降法存在两个缺点:

  1. 训练速度慢:每走一步都需要计算调整下一步的方向,下山的速度变慢。对于大数据集而言,每输入一个样本都需要更新一次参数,并且每次迭代都要遍历所有的样本。会使得训练过程相当缓慢,需要花费很长时间才能得到收敛。
  2. 容易陷入局部最优解:由于是在有限视距内寻找下山方向。当陷入平坦的洼地,会误以为到达了山地的最低点,从而不会继续走下去。所谓的局部最优解就是鞍点,梯度为0,使得模型参数不会再继续更新。

于是学者们又提出添加momentum(动量或者冲量):结合当前梯度与上一次更新信息,用于当前更新!

主要分为两个情况:

一、momentum

v_{i} = m*v_{i-1}+g(w_{i})

w_{i+1} = w_{i} - lr*v_{i}

其中 w_{i+1}?表示第i+1次更新的参数,lr表示学习率,v_{i}?表示更新量,m?表示momentum系数,g(w_{i})?表示?w_{i}?的梯度。(一般训练时的动量设置为0.9

下面以100次更新为例:

v_{100} = m*v_{99}+g(w_{100}) \\=g(w_{100})+m*(m*w_{98}+g(w_{99})) \\=g(w_{100})+m*g(w_{99})+m^2*v_{98} \\=g(w_{100})+m*g(w_{99})+m^2*g(w_{98})+m^3*v_{97}

二、Nesterov版本进行了类似的修改。参数和上面的定义是一样的!

v_{i} = m*v_{i-1} + lr*g(w_{i})

w_{i+1} = w_{i} - v_{i}

以上两种情况都是动量优化法,引入物理中的动量思想,加速梯度下降,主要有上面两种方法。由上图梯度下降法,从山顶到山底,没有阻力的情况下,它的动量会越来越大,如果遇到阻力,速度就会变小。动量优化方法就是基于此思想,使得梯度方向在不变的维度上,参数更新变快,梯度有所改变时,更新参数变慢,这样就能加快收敛并且减少动荡。

下面整体再以代码的形式看一下optim.SGD:(以RMB二分类为例)

 
 
 
 
 
 
LR=0.0125,momentum=0.9

测试效果:

 
 

五、其他优化器

1. optim.SGD:随机梯度下降法《On the importance of initialization and momentum in deep learning 》

2. optim.Adagrad:自适应学习率梯度下降法

《Adaptive Subgradient Methods for Online Learning and Stochastic
Optimization》

3. optim.RMSprop: Adagrad的改进http://www.cs.toronto.edu/~tijmen/csc321/slides/lecture_slides_lec6.pdf

4. optim.Adadelta: Adagrad的改进《 AN ADAPTIVE LEARNING RATE METHOD》

5. optim.Adam:RMSprop结合Momentum《Adam: A Method for Stochastic Optimization》

6. optim.Adamax:Adam增加学习率上限《Adam: A Method for Stochastic Optimization》

7. optim.SparseAdam:稀疏版的Adam

8. optim.ASGD:随机平均梯度下降

《Accelerating Stochastic Gradient Descent using Predictive Variance
Reduction》

9. optim.Rprop:弹性反向传播《Martin Riedmiller und Heinrich Braun》

10. optim.LBFGS:BFGS的改进

平台注册入口