优化器总结
机器学习中,有很多优化方法来试图寻找模型的最优解。比如神经网络中可以采取最基本的梯度下降法。
梯度下降法 (Gradient Descent)
梯度下降法是最基本的一类优化器,目前主要分为三种梯度下降法:标准梯度下降法 (GD, Gradient Descent),随机梯度下降法 (SGD, Stochastic Gradient Descent) 及批量梯度下降法 (BGD, Batch Gradient Descent)。
1. 标准梯度下降法 (GD)
-
假设要学习训练的模型参数为
WW
,代价函数为
J(W)J(W)
,则代价函数关于模型参数的偏导数即相关梯度为
ΔJ(W)ΔJ(W)
,学习率为
ηtηt
,则使用梯度下降法更新参数为:
Wt+1=Wt−ηtΔJ(Wt)Wt+1=Wt−ηtΔJ(Wt)
其中,
WtWt
表示
tt
时刻的模型参数。
-
从表达式来看,模型参数的更新调整,与代价函数关于模型参数的梯度有关,即沿着梯度的方向不断减小模型参数,从而最小化代价函数。
-
基本策略可以理解为” 在有限视距内寻找最快路径下山 “,因此每走一步,参考当前位置最陡的方向 (即梯度) 进而迈出下一步。可以形象的表示为:
评价:标准梯度下降法主要有两个缺点:
- 训练速度慢:每走一步都要要计算调整下一步的方向,下山的速度变慢。在应用于大型数据集中,每输入一个样本都要更新一次参数,且每次迭代都要遍历所有的样本。会使得训练过程及其缓慢,需要花费很长时间才能得到收敛解。
- 容易陷入局部最优解:由于是在有限视距内寻找下山的反向。当陷入平坦的洼地,会误以为到达了山地的最低点,从而不会继续往下走。所谓的局部最优解就是鞍点。落入鞍点,梯度为 0,使得模型参数不在继续更新。
2. 批量梯度下降法 (BGD)
-
假设
批量训练样本
总数为
nn
,每次输入和输出的样本分别为
X(i),Y(i)X(i),Y(i)
,模型参数为
WW
,代价函数为
J(W)J(W)
,每输入一个样本
ii
代价函数关于
WW
的梯度为
ΔJi(Wt,X(i),Y(i))ΔJi(Wt,X(i),Y(i))
,学习率为
ηtηt
,则使用批量梯度下降法更新参数表达式为:
Wt+1=Wt−ηt∑i=1nΔJi(Wt,X(i),Y(i))Wt+1=Wt−ηt∑i=1nΔJi(Wt,X(i),Y(i))
其中,
WtWt
表示
tt
时刻的模型参数。
-
从表达式来看,模型参数的调整更新与全部输入样本的代价函数的和(即批量 / 全局误差)有关。即每次权值调整发生在批量样本输入之后,而不是每输入一个样本就更新一次模型参数。这样就会大大加快训练速度。
-
基本策略可以理解为,在下山之前掌握了附近的地势情况,选择总体平均梯度最小的方向下山。
评价:
- 批量梯度下降法比标准梯度下降法训练时间短,且每次下降的方向都很正确。
3. 随机梯度下降法 (SGD)
-
对比批量梯度下降法,假设从一批训练样本
nn
中随机选取一个样本
isis
。模型参数为
WW
,代价函数为
J(W)J(W)
,梯度为
ΔJ(W)ΔJ(W)
,学习率为
ηtηt
,则使用随机梯度下降法更新参数表达式为:
Wt+1=Wt−ηtgtWt+1=Wt−ηtgt
其中,
gt=ΔJis(Wt;X(is);X(is)), is∈{1,2,...,n}gt=ΔJis(Wt;X(is);X(is)), is∈{1,2,...,n}
表示随机选择的一个梯度方向,
WtWt
表示
tt
时刻的模型参数。
-
E(gt)=ΔJ(Wt)E(gt)=ΔJ(Wt),这里虽然引入了随机性和噪声,但期望仍然等于正确的梯度下降。
-
基本策略可以理解为随机梯度下降像是一个盲人下山,不用每走一步计算一次梯度,但是他总能下到山底,只不过过程会显得扭扭曲曲。
-
评价:
- 优点:
- 虽然 SGD 需要走很多步的样子,但是对梯度的要求很低(计算梯度快)。而对于引入噪声,大量的理论和实践工作证明,只要噪声不是特别大,SGD 都能很好地收敛。
- 应用大型数据集时,训练速度很快。比如每次从百万数据样本中,取几百个数据点,算一个 SGD 梯度,更新一下模型参数。相比于标准梯度下降法的遍历全部样本,每输入一个样本更新一次参数,要快得多。
- 缺点:
- SGD 在随机选择梯度的同时会引入噪声,使得权值更新的方向不一定正确。
- 此外,SGD 也没能单独克服局部最优解的问题。
动量优化法
动量优化方法是在梯度下降法的基础上进行的改变,具有加速梯度下降的作用。一般有标准动量优化方法 Momentum、NAG(Nesterov accelerated gradient)动量优化方法。
NAG在Tensorflow中与Momentum合并在同一函数tf.train.MomentumOptimizer中,可以通过参数配置启用。
1. Momentum
-
使用动量 (Momentum) 的随机梯度下降法(SGD),主要思想是引入一个积攒历史梯度信息动量来加速 SGD。
-
从训练集中取一个大小为
nn
的小批量
{X(1),X(2),...,X(n)}{X(1),X(2),...,X(n)}
样本,对应的真实值分别为
Y(i)Y(i)
,则
Momentum 优化
表达式为:
{vt=αvt−1+ηtΔJ(Wt,X(is),Y(is))Wt+1=Wt−vt{vt=αvt−1+ηtΔJ(Wt,X(is),Y(is))Wt+1=Wt−vt
其中,
vtvt
表示
tt
时刻积攒的加速度。
αα
表示动力的大小,一般取值为 0.9(表示最大速度 10 倍于 SGD)。
ΔJ(Wt,X(is),Y(is))ΔJ(Wt,X(is),Y(is))
含义见 SGD 算法。
WtWt
表示
tt
时刻模型参数。
-
动量主要解决 SGD 的两个问题:一是随机梯度的方法(引入的噪声);二是 Hessian 矩阵病态问题(可以理解为 SGD 在收敛过程中和正确梯度相比来回摆动比较大的问题)。
-
理解策略为:由于当前权值的改变会受到上一次权值改变的影响,类似于小球向下滚动的时候带上了惯性。这样可以加快小球向下滚动的速度。
2. NAG
-
牛顿加速梯度(NAG, Nesterov accelerated gradient)算法,是 Momentum 动量算法的变种。更新模型参数表达式如下:
{vt=αvt−1+ηtΔJ(Wt−αvt−1)Wt+1=Wt−vt{vt=αvt−1+ηtΔJ(Wt−αvt−1)Wt+1=Wt−vt
其中,
vtvt
表示
tt
时刻积攒的加速度;
αα
表示动力的大小;
ηtηt
表示学习率;
WtWt
表示
tt
时刻的模型参数,
ΔJ(Wt−αvt−1)ΔJ(Wt−αvt−1)
表示代价函数关于
WtWt
的梯度。
-
Nesterov 动量梯度的计算在模型参数施加当前速度之后,因此可以理解为往标准动量中添加了一个校正因子。
-
理解策略:在 Momentun 中小球会盲目地跟从下坡的梯度,容易发生错误。所以需要一个更聪明的小球,能提前知道它要去哪里,还要知道走到坡底的时候速度慢下来而不是又冲上另一个坡。计算Wt−αvt−1Wt−αvt−1可以表示小球下一个位置大概在哪里。从而可以提前知道下一个位置的梯度,然后使用到当前位置来更新参数。
-
在凸批量梯度的情况下,Nesterov 动量将额外误差收敛率从O(1/k)(k 步后)O(1/k)(k 步后)改进到O(1/k2)O(1/k2)。然而,在随机梯度情况下,Nesterov 动量对收敛率的作用却不是很大。
自适应学习率优化算法
自适应学习率优化算法针对于机器学习模型的学习率,传统的优化算法要么将学习率设置为常数要么根据训练次数调节学习率。极大忽视了学习率其他变化的可能性。然而,学习率对模型的性能有着显著的影响,因此需要采取一些策略来想办法更新学习率,从而提高训练速度。
目前的自适应学习率优化算法主要有:AdaGrad 算法,RMSProp 算法,Adam 算法以及 AdaDelta 算法。
1.AdaGrad 算法
思想:
- AdaGrad 算法,独立地适应所有模型参数的学习率,缩放每个参数反比于其所有梯度历史平均值总和的平方根。具有代价函数最大梯度的参数相应地有个快速下降的学习率,而具有小梯度的参数在学习率上有相对较小的下降。
算法描述:
-
AdaGrad 算法优化策略一般可以表示为:
Wt+1=Wt−η0∑tt′=1(gt′,i)+ϵ−−−−−−−−−−−−√⊙gt,iWt+1=Wt−η0∑t′=1t(gt′,i)+ϵ⊙gt,i
假定一个多分类问题,
ii
表示第
ii
个分类,
tt
表示第
tt
迭代同时也表示分类
ii
累计出现的次数。
η0η0
表示初始的学习率取值一般为 0.01,
ϵϵ
是一个取值很小的数(一般为 1e-8)为了避免分母为 0。
WtWt
表示
tt
时刻即第
tt
迭代模型的参数,
gt,i=ΔJ(Wt,i)gt,i=ΔJ(Wt,i)
表示
tt
时刻,指定分类
ii
,代价函数
J(⋅)J(⋅)
关于
WW
的梯度。
-
从表达式可以看出,对出现比较多的类别数据,Adagrad 给予越来越小的学习率,而对于比较少的类别数据,会给予较大的学习率。因此 Adagrad 适用于数据稀疏或者分布不平衡的数据集。
-
Adagrad 的主要优势在于不需要人为的调节学习率,它可以自动调节;缺点在于,随着迭代次数增多,学习率会越来越小,最终会趋近于 0。
2.RMSProp 算法
思想:
- RMSProp 算法修改了 AdaGrad 的梯度积累为指数加权的移动平均,使得其在非凸设定下效果更好。
算法描述:
-
RMSProp 算法的一般策略可以表示为:
⎧⎩⎨⎪⎪E[g2]t=αE[g2]t−1+(1−α)g2tWt+1=Wt−η0E[g2]t+ϵ−−−−−−−−√⊙gt{E[g2]t=αE[g2]t−1+(1−α)gt2Wt+1=Wt−η0E[g2]t+ϵ⊙gt
其中,
WtWt
表示
tt
时刻即第
tt
迭代模型的参数,
gt=ΔJ(Wt)gt=ΔJ(Wt)
表示
tt
次迭代代价函数关于
WW
的梯度大小,
E[g2]tE[g2]t
表示前
tt
次的梯度平方的均值。
αα
表示动力(通常设置为 0.9),
η0η0
表示全局初始学习率。
ϵϵ
是一个取值很小的数(一般为 1e-8)为了避免分母为 0。
-
RMSProp 借鉴了 Adagrad 的思想,观察表达式,分母为E[g2]t+ϵ−−−−−−−−√E[g2]t+ϵ。由于取了个加权平均,避免了学习率越来越低的的问题,而且能自适应地调节学习率。
-
RMSProp 算法在经验上已经被证明是一种有效且实用的深度神经网络优化算法。目前它是深度学习从业者经常采用的优化方法之一。
3. AdaDelta 算法
思想:AdaGrad 算法和 RMSProp 算法都需要指定全局学习率,AdaDelta 算法结合两种算法每次参数的更新步长即:
ΔWAdaGrad, t=−η0∑tt′=1(gt′,i)+ϵ−−−−−−−−−−−−√⊙gtΔWRMSProp, t=−η0E[g2]t+ϵ−−−−−−−−√⊙gtΔWAdaGrad, t=−η0∑t′=1t(gt′,i)+ϵ⊙gtΔWRMSProp, t=−η0E[g2]t+ϵ⊙gt
算法描述:
-
AdaDelta 算法策略可以表示为:
⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪E[g2]t=αE[g2]t−1+(1−α)g2tΔWt=−∑t−1i=1ΔWi−−−−−−−−−√E[g2]t+ϵ−−−−−−−−√Wt+1=Wt+ΔWt{E[g2]t=αE[g2]t−1+(1−α)gt2ΔWt=−∑i=1t−1ΔWiE[g2]t+ϵWt+1=Wt+ΔWt
其中
WtWt
为第
tt
次迭代的模型参数,
gt=ΔJ(Wt)gt=ΔJ(Wt)
为代价函数关于
WW
的梯度。
E[g2]tE[g2]t
表示前
tt
次的梯度平方的均值。
∑t−1i=1ΔWi∑i=1t−1ΔWi
表示前
t−1t−1
次模型参数每次的更新步长累加求根。
-
从表达式可以看出,AdaDelta 不需要设置一个默认的全局学习率。
评价:
- 在模型训练的初期和中期,AdaDelta 表现很好,加速效果不错,训练速度快。
- 在模型训练的后期,模型会反复地在局部最小值附近抖动。
4. Adam 算法
思想:
- 首先,Adam 中动量直接并入了梯度一阶矩(指数加权)的估计。其次,相比于缺少修正因子导致二阶矩估计可能在训练初期具有很高偏置的 RMSProp,Adam 包括偏置修正,修正从原点初始化的一阶矩(动量项)和(非中心的)二阶矩估计。
算法描述:
-
AdaDelta 算法策略可以表示为:
⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪mt=β1mt−1+(1−β1)gtvt=β2vt−1+(1−β2)g2tm^t=mt1−βt1, vt=vt1−βt2Wt+1=Wt−ηvt−−√+ϵmt{mt=β1mt−1+(1−β1)gtvt=β2vt−1+(1−β2)gt2mt=mt1−β1t, vt=vt1−β2tWt+1=Wt−ηvt+ϵm^t
其中,
mtmt
和
vtvt
分别为一阶动量项和二阶动量项。
β1,β2β1,β2
为动力值大小通常分别取 0.9 和 0.999;
mt,vtmt,vt
分别为各自的修正值。
WtWt
表示
tt
时刻即第
tt
迭代模型的参数,
gt=ΔJ(Wt)gt=ΔJ(Wt)
表示
tt
次迭代代价函数关于
WW
的梯度大小;
ϵϵ
是一个取值很小的数(一般为 1e-8)为了避免分母为 0
评价:Adam 通常被认为对超参数的选择相当鲁棒,尽管学习率有时需要从建议的默认修改。
各种优化器的比较
终于结束的漫长的理论分析,下面对各种优化器做一些有趣的比较。
1. 可视化比较
(1) 示例一
上图描述了在一个曲面上,6 种优化器的表现,从中可以大致看出:
① 下降速度:
- 三个自适应学习优化器 Adagrad、RMSProp 与 AdaDelta 的下降速度明显比 SGD 要快,其中,Adagrad 和 RMSProp 齐头并进,要比 AdaDelta 要快。
- 两个动量优化器 Momentum 和 NAG 由于刚开始走了岔路,初期下降的慢;随着慢慢调整,下降速度越来越快,其中 NAG 到后期甚至超过了领先的 Adagrad 和 RMSProp。
② 下降轨迹:
- SGD 和三个自适应优化器轨迹大致相同。两个动量优化器初期走了 “岔路”,后期也调整了过来。
(2) 示例二
上图在一个存在鞍点的曲面,比较 6 中优化器的性能表现,从图中大致可以看出:
- 三个自适应学习率优化器没有进入鞍点,其中,AdaDelta 下降速度最快,Adagrad 和 RMSprop 则齐头并进。
- 两个动量优化器 Momentum 和 NAG 以及 SGD 都顺势进入了鞍点。但两个动量优化器在鞍点抖动了一会,就逃离了鞍点并迅速地下降,后来居上超过了 Adagrad 和 RMSProp。
- 很遗憾,SGD 进入了鞍点,却始终停留在了鞍点,没有再继续下降。
(3) 示例三
上图比较了 6 种优化器收敛到目标点(五角星)的运行过程,从图中可以大致看出:
① 在运行速度方面
- 两个动量优化器 Momentum 和 NAG 的速度最快,其次是三个自适应学习率优化器 AdaGrad、AdaDelta 以及 RMSProp,最慢的则是 SGD。
② 在收敛轨迹方面
- 两个动量优化器虽然运行速度很快,但是初中期走了很长的” 岔路”。
- 三个自适应优化器中,Adagrad 初期走了岔路,但后来迅速地调整了过来,但相比其他两个走的路最长;AdaDelta 和 RMSprop 的运行轨迹差不多,但在快接近目标的时候,RMSProp 会发生很明显的抖动。
- SGD 相比于其他优化器,走的路径是最短的,路子也比较正。
2. 应用于简单分类问题的比较
Tensorflow 中封装了一系列的优化器:
1. tf.train.GradientDescentOptimizer
2. tf.train.AdadeltaOptimizer
3. tf.train.AdagradOptimizer
4. tf.train.AdagradDAOptimizer
5. tf.train.MomentumOptimizer
6. tf.train.AdamOptimizer
7. tf.train.FtrlOptimizer
8. tf.train.ProximalGradientDescentOptimizer
9. tf.train.ProximalAdagradOptimizer
10. tf.train.RMSPropOptimizer
下面采用选取几种优化器应用于 UCI 数据集 iris.data 简单的分类问题。为了简单起见,初始代码可以参考机器学习:过拟合、神经网络 Dropout 中没使用 Dropout 之前的代码。修改一行调用优化器的代码:
(1) 使用 SGD 优化器
- 优化器的代码为:
train_step = tf.train.GradientDescentOptimizer(0.2).minimize(loss)
- 运行结果
第1个训练周期训练集的准确率为:33.3%, 测试集的准确率为:32.2%
第2个训练周期训练集的准确率为:33.3%, 测试集的准确率为:32.2%
第3个训练周期训练集的准确率为:38.9%, 测试集的准确率为:35.6%
第4个训练周期训练集的准确率为:62.2%, 测试集的准确率为:62.7%
第5个训练周期训练集的准确率为:66.7%, 测试集的准确率为:66.1%
第6个训练周期训练集的准确率为:66.7%, 测试集的准确率为:67.8%
第7个训练周期训练集的准确率为:66.7%, 测试集的准确率为:67.8%
第8个训练周期训练集的准确率为:67.8%, 测试集的准确率为:67.8%
第9个训练周期训练集的准确率为:67.8%, 测试集的准确率为:67.8%
第10个训练周期训练集的准确率为:67.8%, 测试集的准确率为:67.8%
(2) 使用 AdaGrad 优化器
- 优化器的代码为:
train_step = tf.train.AdagradOptimizer(0.01).minimize(loss)
- 运行结果
第1个训练周期训练集的准确率为:33.3%, 测试集的准确率为:32.2%
第2个训练周期训练集的准确率为:35.6%, 测试集的准确率为:32.2%
第3个训练周期训练集的准确率为:66.7%, 测试集的准确率为:66.1%
第4个训练周期训练集的准确率为:66.7%, 测试集的准确率为:66.1%
第5个训练周期训练集的准确率为:66.7%, 测试集的准确率为:66.1%
第6个训练周期训练集的准确率为:66.7%, 测试集的准确率为:66.1%
第7个训练周期训练集的准确率为:66.7%, 测试集的准确率为:67.8%
第8个训练周期训练集的准确率为:66.7%, 测试集的准确率为:67.8%
第9个训练周期训练集的准确率为:67.8%, 测试集的准确率为:69.5%
第10个训练周期训练集的准确率为:68.9%, 测试集的准确率为:69.5%
- 点评:从运行结果上可以看出使用 AdaGrad 优化器相比于 SGD 似乎没有较大的提升。
(3) 使用 Momentum 优化器
- 优化器的代码为:
train_step = tf.train.MomentumOptimizer(learning_rate=0.01, momentum=0.9).minimize(loss)
- 运行结果
第1个训练周期训练集的准确率为:58.9%, 测试集的准确率为:61.0%
第2个训练周期训练集的准确率为:40.0%, 测试集的准确率为:42.4%
第3个训练周期训练集的准确率为:66.7%, 测试集的准确率为:66.1%
第4个训练周期训练集的准确率为:66.7%, 测试集的准确率为:66.1%
第5个训练周期训练集的准确率为:66.7%, 测试集的准确率为:66.1%
第6个训练周期训练集的准确率为:66.7%, 测试集的准确率为:66.1%
第7个训练周期训练集的准确率为:67.8%, 测试集的准确率为:67.8%
第8个训练周期训练集的准确率为:67.8%, 测试集的准确率为:67.8%
第9个训练周期训练集的准确率为:67.8%, 测试集的准确率为:69.5%
第10个训练周期训练集的准确率为:70.0%, 测试集的准确率为:67.8%
- 点评:Momentum 优化器略优于 AdaGrad 优化器和 SGD,但收敛速度要比后两者快(第 1-2 个训练周期就可以达到 60% 的准确率)。
(4) 使用 NAG 优化器
- 优化器的代码为:
train_step = tf.train.MomentumOptimizer(learning_rate=0.01, momentum=0.9, use_nesterov=True).minimize(loss)
- 运行结果
第1个训练周期训练集的准确率为:37.8%, 测试集的准确率为:39.0%
第2个训练周期训练集的准确率为:66.7%, 测试集的准确率为:66.1%
第3个训练周期训练集的准确率为:66.7%, 测试集的准确率为:66.1%
第4个训练周期训练集的准确率为:66.7%, 测试集的准确率为:66.1%
第5个训练周期训练集的准确率为:66.7%, 测试集的准确率为:66.1%
第6个训练周期训练集的准确率为:66.7%, 测试集的准确率为:66.1%
第7个训练周期训练集的准确率为:66.7%, 测试集的准确率为:67.8%
第8个训练周期训练集的准确率为:67.8%, 测试集的准确率为:69.5%
第9个训练周期训练集的准确率为:70.0%, 测试集的准确率为:69.5%
第10个训练周期训练集的准确率为:71.1%, 测试集的准确率为:69.5%
- 点评:NAG 和 Momentum 结果差不多,NAG 似乎好那么一点点。
(5) 使用 RMSProp 优化器
- 优化器的代码为:
train_step = tf.train.RMSPropOptimizer(0.01).minimize(loss)
- 运行结果(RMSProp 运行结果不稳定,下面是出现比较多的相近结果)
第1个训练周期训练集的准确率为:33.3%, 测试集的准确率为:32.2%
第2个训练周期训练集的准确率为:33.3%, 测试集的准确率为:32.2%
第3个训练周期训练集的准确率为:35.6%, 测试集的准确率为:35.6%
第4个训练周期训练集的准确率为:48.9%, 测试集的准确率为:49.2%
第5个训练周期训练集的准确率为:35.6%, 测试集的准确率为:35.6%
第6个训练周期训练集的准确率为:38.9%, 测试集的准确率为:42.4%
第7个训练周期训练集的准确率为:51.1%, 测试集的准确率为:50.8%
第8个训练周期训练集的准确率为:66.7%, 测试集的准确率为:66.1%
第9个训练周期训练集的准确率为:60.0%, 测试集的准确率为:62.7%
第10个训练周期训练集的准确率为:66.7%, 测试集的准确率为:66.1%
- 点评:RMSProp 优化器的效果有点不理想,而且不稳定。
(6) 使用 Adam 优化器
- 优化器的代码为:
train_step = tf.train.AdamOptimizer(0.001).minimize(loss)
- 运行结果
第1个训练周期训练集的准确率为:33.3%, 测试集的准确率为:33.9%
第2个训练周期训练集的准确率为:36.7%, 测试集的准确率为:37.3%
第3个训练周期训练集的准确率为:66.7%, 测试集的准确率为:66.1%
第4个训练周期训练集的准确率为:66.7%, 测试集的准确率为:66.1%
第5个训练周期训练集的准确率为:66.7%, 测试集的准确率为:67.8%
第6个训练周期训练集的准确率为:67.8%, 测试集的准确率为:67.8%
第7个训练周期训练集的准确率为:67.8%, 测试集的准确率为:67.8%
第8个训练周期训练集的准确率为:71.1%, 测试集的准确率为:67.8%
第9个训练周期训练集的准确率为:71.1%, 测试集的准确率为:69.5%
第10个训练周期训练集的准确率为:71.1%, 测试集的准确率为:69.5%
- 点评:Adam 优化器的表现可圈可点,比 RMSProp 优化器要稳定。
(2) 使用 AdaDelta 优化器 - 优化器的代码为:
train_step = tf.train.AdadeltaOptimizer(1).minimize(loss)
- 运行结果
第1个训练周期训练集的准确率为:60.0%, 测试集的准确率为:64.4%
第2个训练周期训练集的准确率为:66.7%, 测试集的准确率为:66.1%
第3个训练周期训练集的准确率为:66.7%, 测试集的准确率为:66.1%
第4个训练周期训练集的准确率为:66.7%, 测试集的准确率为:67.8%
第5个训练周期训练集的准确率为:67.8%, 测试集的准确率为:69.5%
第6个训练周期训练集的准确率为:70.0%, 测试集的准确率为:69.5%
第7个训练周期训练集的准确率为:72.2%, 测试集的准确率为:71.2%
第8个训练周期训练集的准确率为:73.3%, 测试集的准确率为:76.3%
第9个训练周期训练集的准确率为:75.6%, 测试集的准确率为:84.7%
第10个训练周期训练集的准确率为:76.7%, 测试集的准确率为:88.1%
- 点评:AdaDelta 优化器似乎能在本例中夺魁。
总评:
- 通过对比 10 个训练周期的准确率结果可以看出,其他的优化器(除了 RMSProp,有点意外,可能本例不适合)或多或少都优于 SGD。从收敛速度上看,两个动量优化器 Momentum 和 NAG 的速度相比于除了 AdaDelta 之外的优化器要快,1-2 个周期就能达到 60% 的准确率。而本例中表现最好的优化器是 AdaDelta,无论是收敛速度还是十周期的准确率都比其他优化器要好的多。
优化器的选择
- 那种优化器最好?该选择哪种优化算法?目前还没能够达达成共识。Schaul et al (2014) 展示了许多优化算法在大量学习任务上极具价值的比较。虽然结果表明,具有自适应学习率的优化器表现的很鲁棒,不分伯仲,但是没有哪种算法能够脱颖而出。
- 目前,最流行并且使用很高的优化器(算法)包括 SGD、具有动量的 SGD、RMSprop、具有动量的 RMSProp、AdaDelta 和 Adam。在实际应用中,选择哪种优化器应结合具体问题;同时,也优化器的选择也取决于使用者对优化器的熟悉程度(比如参数的调节等等)。
参考资料
为什么说随机最速下降法 (SGD) 是一个很好的方法?
深度学习最全优化方法总结比较(SGD,Adagrad,Adadelta,Adam,Adamax,Nadam)
Lan Goodfellow: Deep learning. 深度学习【中文版】
常见优化算法 (caffe 和 tensorflow 对应参数)