这位仁兄写的比较全
机器学习中,往往求解目标函数的最优解时,需要对函数进行进行最优化,因此会用到一些比较经典的优化器。总的来说可以分为三类,一类是梯度下降法(Gradient Descent),一类是动量优化法(Momentum),另外就是自适应学习率优化算法。
首先对目标函数
J
(
θ
)
J( heta )
J(θ)关于每一个参数
θ
i
heta_i
θi?求偏导数,把求得的各个参数以向量的形式写出来就是梯度。梯度是函数值变化最快的地方。其计算过程是沿梯度下降的方向求极小值(如果目标函数是凸函数,极小值就是最小值),也可以沿梯度上升的方向求极大值(最大值)。可以表示为:
θ
i
+
1
=
θ
i
?
α
?
θ
J
(
θ
)
heta_{i + 1} = heta_i - \alpha
abla _{ heta}J( heta)
θi+1?=θi??α?θ?J(θ)
这些方法的缺点是:
1.训练速度慢,每次迭代要求所有样本的梯度,需要时间长,这样就产生了很多比较新奇的优化器(SGD,BGD,Mini-batch GD等)。
2.对于非凸函数而言,容易陷入局部最优解
常见的梯度下降法主要有三种
批量梯度下降法(BGD)、随机梯度下降法(SGD)、小批量梯度下降法。
假设有n个样本,则BGD的更新方法是
θ
i
+
1
=
θ
i
?
α
t
∑
i
=
1
n
?
θ
J
(
θ
,
x
i
,
y
i
)
heta_{i + 1} = heta_i - \alpha_t \sum_{i = 1}^n
abla _{ heta}J( heta,x^i,y^i)
θi+1?=θi??αt?i=1∑n??θ?J(θ,xi,yi)
每进行一次参数更新,需要计算整个数据样本集,因此导致批量梯度下降法的速度会比较慢,但是因为每次的下降方向为总体平均梯度,它得到的会是一个全局最优解
SGD的更新方法可以表示为,请记住他的名字随机梯度下降法
θ
i
+
1
=
θ
i
?
α
?
θ
J
(
θ
,
x
i
,
y
i
)
heta_{i + 1} = heta_i - \alpha
abla _{ heta}J( heta,x^i,y^i)
θi+1?=θi??α?θ?J(θ,xi,yi)
SGD每次参数更新仅仅需要计算一个样本的梯度,可能只需要其中一部分样本就能迭代到最优解,由于每次迭代并不是都向着整体最优化方向,导致梯度下降的波动非常大,更容易从一个局部最优跳到另一个局部最优,准确度下降。
从公式可以看出来,SGD的主要缺点是
选择合适的learning rate比较困难;所有参数都是用同样的learning rate;SGD容易收敛到局部最优.
设其mini-batch的size是m,则其更新方法为
θ
i
+
1
=
θ
i
?
α
t
∑
i
=
x
i
=
x
+
m
?
1
?
θ
J
(
θ
,
x
i
,
y
i
)
heta_{i + 1} = heta_i - \alpha_t \sum_{i = x}^{i=x + m - 1}
abla _{ heta}J( heta,x^i,y^i)
θi+1?=θi??αt?i=x∑i=x+m?1??θ?J(θ,xi,yi)
虽然小批量梯度下降法对梯度的要求很低(计算梯度快)。而对于引入噪声,大量的理论和实践工作证明,只要噪声不是特别大,都能很好地收敛。
应用大型数据集时,训练速度很快。
小批量梯度下降法在选择小批量样本时,同时会引入噪声,使得权值更新的方向不一定正确。
动量优化方法引入动量思想,加速梯度下降。
当我们将一个小球从山上滚下来,没有阻力时,它的动量会越来越大,但是如果遇到了阻力,速度就会变小,动量优化法就是借鉴此思想,使得梯度方向在不变的维度上,参数更新变快,梯度有所改变时,更新参数变慢,这样就能够加快收敛并且减少动荡。
参数更新时在一定程度上保留之前更新的方向,同时又利用当前batch的梯度微调最终的更新方向,简言之就是通过积累之前的动量加速当前的梯度。
假设 gradient 表示动量,
μ
\mu
μ表示动量因子,通常取0.9,gradenet0_1表示计算出的之前的梯度。在随机梯度下降法SGD的基础上增加动量,则参数更新公式如下:
g
r
a
d
i
e
n
t
0
=
μ
g
r
a
d
i
e
n
t
+
g
r
a
d
i
e
n
t
0
1
?
d
e
c
a
y
r
a
t
e
gradient0 = \mu gradient + gradient0_1* decay_rate
gradient0=μgradient+gradient01??decayr?ate
θ
=
θ
?
l
r
?
g
r
a
d
i
e
n
t
0
heta = heta - lr * gradient0
θ=θ?lr?gradient0
在梯度方向改变时,momentum能够降低参数更新速度,从而减少震荡;
在梯度方向相同时,momentum可以加速参数更新, 从而加速收敛。
动量移动得更快(因为它积累的所有动量)
动量有机会逃脱局部极小值(因为动量可能推动它脱离局部极小值)
固定学习率可能在下面的情况发挥不了太好的效果。
对于某些参数,通过算法已经优化到了极小值附近,但是有的参数仍然有着很大的梯度。
如果学习率太小,则梯度很大的参数会有一个很慢的收敛速度;
如果学习率太大,则已经优化得差不多的参数可能会出现不稳定的情况。
这些方法主要有AdaGrad算法、RMSProp算法、Adam算法、lazyadam算法等
AdaGrad(Adaptive Gradient)算法,独立地适应所有模型参数的学习率,缩放每个参数反比于其所有梯度历史平均值总和的平方根,使得具有目标函数最大梯度的参数相应地有个快速下降的学习率,而具有小梯度的参数在学习率上有相对较小的下降。
其算法流程可以描述为
AdaGrad (以及其它类似的基于梯度平方的方法,如 RMSProp 和 Adam)更好地避开鞍点。
对出现比较多的类别数据,Adagrad给予越来越小的学习率,
而对于比较少的类别数据,会给予较大的学习率。
Adagrad适用于数据稀疏或者分布不平衡的数据集。
缺点在于,随着迭代次数增多,学习率会越来越小,最终会趋近于0
RMSProp算法采用了指数衰减平均的方式淡化遥远过去的历史对当前步骤参数更新量[公式]的影响。RMSProp引入了一个新的参数
ρ
\rho
ρ(decay_rate),用于控制历史梯度值的衰减速率。
其算法主要流程可以表示为:
### 3.3 Adam算法
Adam 同时兼顾了动量和 RMSProp 的优点。
其算法流程可以表示为
Adam梯度经过偏置校正后,每一次迭代学习率都有一个固定范围,使得参数比较平稳。
结合了Adagrad善于处理稀疏梯度和RMSprop善于处理非平稳目标的优点为不同的参数计算不同的自适应学习率
也适用于大多非凸优化问题——适用于大数据集和高维空间。