|
神经网络优化算法
发表于 2018-12-10 17:03:10
浏览:2832
|
回复:0
打印
只看该作者
[复制链接]
楼主
什么是优化算法?
在模型训练时候,你会发现模型内部有些参数,是用来计算测试集中目标值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优化神经网络以及优化器的选择
深度学习中优化方法
|
|