Firefly开源社区

神经网络优化算法

117

积分

1

威望

0

贡献

技术小白

积分
117
发表于 2018-12-10 17:03:10     
什么是优化算法?
  在模型训练时候,你会发现模型内部有些参数,是用来计算测试集中目标值Y的真实值和预测值的偏差程度的,基于这些参数,就形成了损失函数loss(x)。所以现在大部分的机器学习算法的本质都是建立优化模型,通过最优化方法对目标函数(或损失函数)进行优化,可以得到一个更好更小的损失函数值,从而训练出最好的模型。在pytorch中比较常用的优化器有sgd、momentum、adagrad、RMSProp、Adam等等。
  
Stochastic Gradient Descent (SGD):
  普通的训练方法, 需要重复不断的把整套数据放入神经网络NN中训练, 这样消耗的计算资源会很大。SGD是最基础的优化方法,当我们使用SGD会把数据拆分后再分批不断放入 NN 中计算。 每次使用批数据, 虽然不能反映整体数据的情况, 不过却很大程度上加速了 NN 的训练过程,而且也不会丢失太多准确率。一般情况下,在训练数据太多时,整个数据集更新不会在时间上不显示出来,所以可以利用SGD方法减少机器的压力,并且可以更快训练出数据模型。

  weight = weight - learning_rate * gradient

# SGD 就是随机梯度下降opt_SGD    = torch.optim.SGD(net_SGD.parameters(), lr=LR)

优点:
训练速度快,避免了批量梯度更新过程中的计算冗余问题,
对于很大的数据集,也能够以较快的速度收敛。


缺点
由于是抽取,因此不可避免的,得到的梯度肯定有误差.因此学习速率需要逐渐减小,
否则模型无法收敛
因为误差,所以每一次迭代的梯度受抽样的影响比较大,
不能很好的反映真实梯度。并且SGD有较高的方差,其波动较大。




Momentum :
  SGD方法的一个缺点是,其更新方向完全依赖于当前的batch,因而其更新十分不稳定。当我们使用SGD训练参数时,有时候会下降的非常慢,并且可能会陷入到局部最小值中。momentum的引入就是为了解决了SGD存在的不足,特别是对于高曲率、小但一致的梯度。动量的主要思想是积累了之前梯度指数级衰减的移动平均(前面的指数加权平均)即更新的时候在一定程度上保留之前更新的方向,同时利用当前batch的梯度微调最终的更新方向。这样一来,可以在一定程度上增加稳定性。

# Momentum update
v = momentum * v - learning_rate * dx  # integrate velocity
W += v  # integrate position

# momentum 动量加速,在SGD函数里指定momentum的值即可opt_Momentum  = torch.optim.SGD(net_Momentum.parameters(),
                     lr=LR, momentum=0.8)


adagrad:

      这种方法是在学习率上面动手脚, 使得每一个参数更新都会有自己与众不同的学习率。它的主要功能是:它对不同的参数调整学习率,具体而言,对低频出现的参数进行大的更新,对高频出现的参数进行小的更新。因此,他很适合于处理稀疏数据。



v +=  dx^2  # integrate velocity
W += - learning_rate * dx/√v # integrate position
# lr 默认: 1e-2,lr_decay 默认: 0,weight_decay 默认: 0
opt_Momentum  = torch.optim.adagrad(net_Adagrad.parameters(),
                     lr=LR, lr_decay=0, weight_decay=0)


优点:能够实现学习率的自动更改。如果这次梯度大,那么学习速率衰减的就快一些;如果这次梯度小,那么学习速率衰减的就慢一些。


缺点:
其学习率是单调递减的,训练后期学习率非常小
其需要手工设置一个全局的初始学习率
更新时,左右两边的单位不同一



RMSProp:

在实际使用过程中,RMSprop已被证明是一种有效且实用的深度神经网络优化算法。目前它是深度学习人员经常采用的优化算法之一。RMSProp通过引入一个衰减系数,让学习率每回合都衰减一定比例,类似于Momentum中的做法。



v =  alpha * v + (1-alpha) * dx^2  # integrate velocity
W += - learning_rate * dx/√v
# integrate position



RMSprop 也将学习率除以了一个指数衰减的衰减均值。Hinton 建议设定 为 0.9,相对而言,0.001 是一个较好的默认值。

# RMSprop 指定参数alpha
opt_RMSprop     =  torch.optim.RMSprop(net_RMSprop.parameters(),                                             lr=LR, alpha=0.9)



特点:
其实RMSprop依然依赖于全局学习率
RMSprop算是Adagrad的一种发展,和Adadelta的变体,效果趋于二者之间
适合处理非平稳目标- 对于RNN效果很好。



Adam:

       Adam是另外一种给每个参数计算不同更新速率的方法,其本质上是带有动量项的RMSprop,它利用梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率。Adam的优点主要在于经过偏置校正后,每一次迭代学习率都有个确定范围,使得参数比较平稳。它和上述的adadelta和RMSprop一样,都存储了以前的偏导平方衰减平均值,此外,它还存储以前的偏导衰减平均值。



m = b1 * m + (1-b1) * dx

v = b2 * v + (1-b2) * dx^2

w += -learning_rate * m/√v

建议 b1取0.9, b2取0.999 ,



# Adam 参数betas=(0.9, 0.999)
opt_Adam    =  torch.optim.Adam(net_Adam.parameters(), lr=LR,                                             betas=(0.9, 0.999))

特点:
    结合了Adagrad善于处理稀疏梯度和RMSprop善于处理非平稳目标的优点
    对内存需求较小
    为不同的参数计算不同的自适应学习率
    也适用于大多非凸优化- 适用于大数据集和高维空间

  经过偏置校正后,每一次迭代学习率都有个确定范围,使得参数比较平稳。



三、如何选择
在构建神经网络模型时,选择出最佳的优化器,以便快速收敛并正确学习,同时调整内部参数,最大程度地最小化损失函数。SGD 是最普通的优化器, 也可以说没有加速效果, 而 Momentum 是 SGD 的改良版, 它加入了动量原则。后面的RMSprop又是Momentum的升级版. 而 Adam又是 RMSprop 的升级版。



1、对于稀疏数据,SGD和Momentum项等方法可能效果不好。因此对于稀疏数据           集,应该使用某种自适应学习率的方法,且另一好处为不需要人为调整学习率,使       用默认参数就可能获得最优值。
2、SGD通常训练时间更长,但是在好的初始化和学习率调度方案的情况下,结果更可  靠。

3、Adam在实际应用中效果良好,超过了其他的自适应技术。

4、如果想使训练深层网络模型快速收敛或所构建的神经网络较为复杂,则应该使用        Adam或其他自适应学习速率的方法,因为这些方法的实际效果更优。



参考链接:


python torch.optim.SGD

深度学习各种优化函数详解

pytorch中使用torch.optim优化神经网络以及优化器的选择

深度学习中优化方法
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

友情链接 : 爱板网 电子发烧友论坛 云汉电子社区 粤ICP备14022046号-2
快速回复 返回顶部 返回列表