首页 > 代码库 > 梯度优化算法总结(转载)以及solver中相关参数解释
梯度优化算法总结(转载)以及solver中相关参数解释
如果熟悉英文的话,强烈推荐阅读原文,毕竟翻译过程中因为个人理解有限,可能会有谬误,还望读者能不吝指出。另外,由于原文太长,分了两部分翻译,本篇主要是梯度下降优化算法的总结,下篇将会是随机梯度的并行和分布式,以及优化策略的总结。
梯度下降是优化中最流行的算法之一,也是目前用于优化神经网络最常用到的方法。同时,每个优秀的深度学习库都包含了优化梯度下降的多种算法的实现(比如, lasagne 、 caffe 和 keras 的文档)。然而,这些算法一般被封装成优化器,如黑盒一般,因此很难得到它们实际能力和缺点的解释。
本篇博客的目标是为读者提供不同梯度下降优化算法的直观解释,希望读者可以学以致用。我们会先了解下梯度下降的不同变种。然后会对训练过程的问题进行简单总结。接着,我们会介绍最常用的优化算法,展示它们解决这些问题的动机,以及它们对应更新规则变化的原因。我们也就会简单回顾在并行和分布式的情况下,梯度下降优化的算法和架构。最后,我们也会聊聊有助于优化梯度下降的其他策略。
梯度下降是最小化以模型参数 θ∈Rdθ∈Rd 构建的目标函数 J(θ)J(θ) 的一种方法,它通过按目标函数 ?θJ(θ)?θJ(θ) 在参数梯度的相反方向更新参数。学习率 ηη 决定了我们到达(局部)最小所需的步数的大小。换成通俗的话说,我们会沿着目标函数所构建的表面坡度的方向往下走,直到我们到达一个谷底。如果你还不熟悉梯度下降,你可以参考这篇 优化神经网络的入门介绍 。
不同版本的梯度下降
一共有三种不同版本的梯度下降,它们的不同之处字啊与我们计算目标函数梯度时使用数据的多少。根据数据量的大小,我们会在参数更新的准确度和更新花费的时间之间进行权衡。
批量梯度下降
最普通的梯度下降,即批量梯度下降,使用整个训练数据根据参数 θθ 计算目标函数的梯度:
θ=θ?η??θJ(θ)θ=θ?η??θJ(θ)
因为我们需要计算完整个数据集的梯度才能更新,批量梯度下降非常的耗时,而且面对无法完全放入内容的数据集,处理起来也很棘手。批量梯度更新也无法让我们 在线 ,即在运行时加入新的样本进行模型更新。
以代码的形式,批量梯度下降的形式如下:
for i in range(nb_epochs):
params_grad = evaluate_gradient(loss_function, data, params)
params = params - learning_rate * params_grad
对于预先设定好的训练迭代次数,我们首先对于整个数据集根据参数矢量 params
计算损失函数的梯度矢量 weight_grad
。注意最新的深度学习库提供了自动微分的方法,可以根据参数高效计算梯度。如果你自己做梯度的微分,那么最好做一下梯度检查。(从 这篇文章 可以获取一些合理检查梯度的技巧。)
SGD 的代码片段仅仅在训练样本时添加了一个循环,根据每个样本进行梯度估计。注意我们会在每次更新训练时会对训练数据进行随机洗牌处理,这会在后面进行解释:
for i in range(nb_epochs):
np.random.shuffle(data)
for example in data:
params_grad = evaluate_gradient(loss_function, example, params)
params = params - learning_rate * params_grad
挑战
然而, 传统的 mini-batch 梯度下降,并无法保证好的收敛,但却有一些需要强调的挑战:
- 选择一个合适的学习率很困难。学习率太小导致收敛巨慢,而学习率过大又会妨碍收敛,导致损失函数在最小值附件波动,甚至发散出去。
- 学习率的调度 11 尝试使用如模拟退火等方法在训练时可以根据预先定义的调度方式,或者当两次训练中目标的变化在阈值之下时,可以自动的调整学习率。然而,这些调度方式和阈值需要提前定义,因此无法适用于数据集的特征 10 。
- 另外,同一个学习率应用到所有的参数更新。如果我们的数据非常稀疏,特征具有完全不同的频率,我们可能不希望以相同的方式对它们进行更新,更希望对少量出现的特征进行较大的更新。
- 另一个关键的挑战在于最小化神经网络中常见的非凸误差函数时,要避免陷入大量的局部最小值。Dauphin et al.声称实际上难度并非由局部最小值引起,而是由鞍点导致,鞍点就是那些在一个维度是上坡,另一个维度是下坡的点。这些鞍点一般由稳定的相同错误值围绕,这就让 SGD 很难从鞍点逃逸,因为梯度在各个维度都接近于零。
梯度下降优化算法
接下来,我们将会罗列一些深度学习社区广泛用于处理前面提到的挑战的算法。我们将不会讨论那些无法实际处理高维数据集的算法,即二阶方法,如 牛顿法 。
二、关于solver.prototxt中相关参数的解释:
epoch:1个epoch就是将所有的训练图像全部通过网络训练一次
例如:假如有1280000张图片,batchsize=256,则1个epoch需要1280000/256=5000次iteration
它的max-iteration=450000,则共有450000/5000=90个epoch
而lr什么时候衰减与stepsize有关,减少多少与gamma有关,即:若stepsize=500, base_lr=0.01, gamma=0.1,则当迭代到第一个500次时,lr第一次衰减,衰减后的lr=lr*gamma=0.01*0.1=0.001,以后重复该过程,所以
stepsize是lr的衰减步长,gamma是lr的衰减系数。
在训练过程中,每到一定的迭代次数都会测试,迭代次数是由test-interval决定的,如test_interval=1000,则训练集每迭代1000次测试一遍网络,而
test_size, test_iter, 和test图片的数量决定了怎样test, test-size决定了test时每次迭代输入图片的数量,test_iter就是test所有的图片的迭代次数,如:500张test图片,test_iter=100,则test_size=5, 而solver文档里只需要根据test图片总数量来设置test_iter,以及根据需要设置test_interval即可。
momentum:动量(又称动量衰减系数)
weight_decay:正则化惩罚项的系数
梯度优化算法总结(转载)以及solver中相关参数解释