之前的状态是只对优化器有个大概的了解,但是深入的细节原理不是太清楚,目前项目中也因此遇到了一定瓶颈,遂决定过一遍优化器的原理,以确保后续能选取更好的优化器算法和优化器参数来提高算法的性能。
梯度下降算法:
- 批梯度下降BGD(batch gradient descent)
- 随机梯度下降SGD(stochastic gradient descent)
- 小批梯度下降MBGD(Mini-batch gradient descent)
1. BGD
每次用全部的数据样本计算loss,在进行梯度下降,公式为:
θ
=
θ
−
η
⋅
∇
θ
J
(
θ
)
\theta = \theta - \eta \cdot \nabla_{\theta}J(\theta)
θ=θ−η⋅∇θJ(θ)
其中是
θ
\theta
θ是需要训练的参数,
∇
θ
J
(
θ
)
\nabla_{\theta}J(\theta)
∇θJ(θ)是计算的参数梯度,
η
\eta
η是学习率。
BGD的缺点:
a. 容易陷入局部最优;
b. 比较耗时,数据量较大时,显卡内存无法加载。
2. SGD
随机梯度下降是BGD的另一个计算,每次会对每个样本都计算loss,然后进行梯度下降更新:
θ
=
θ
−
η
⋅
∇
θ
J
(
θ
;
x
i
;
y
i
)
\theta = \theta - \eta \cdot \nabla_{\theta}J(\theta;x^i;y^i)
θ=θ−η⋅∇θJ(θ;xi;yi)
优点是可以解决BGD的两个缺点,但是问题是做了很多冗余计算,收敛速度不亏,容易震荡。
3. MBGD
MBGD是BGD与SGD的中和,每次取m个样本, 计算loss,然后进行梯度下降更新:
θ
=
θ
−
η
⋅
∇
θ
J
(
θ
;
x
i
:
i
+
m
;
y
i
:
i
+
m
)
\theta = \theta - \eta \cdot \nabla_{\theta}J(\theta;x^{i:i+m};y^{i:i+m})
θ=θ−η⋅∇θJ(θ;xi:i+m;yi:i+m)
MBGD相对前两种更优秀一些,优点:
a. 跟SGD相比,减少计算次数,梯度下降更稳定;
b. 跟BGD相比,可以充分利用并行计算,提高计算效率。
MBGD遇到的一些问题:
a. 对于GD来说,挑选一个固定学习率是比较困难的。选小了,收敛太慢;选大了,阻碍收敛甚至会造成震荡直至发散。
b. 一般我们使用动态改变学习率的方式,随着epoch数去减小学习率(lr退火),这种不能根据当前的batch数据去动态的变化,相比固定学习率有比较大的提高。
c. 所有参数都用的是一个学习率,不能自适应地调节。
d. 很容易陷入到局部最优。
针对上述问题进行针对性修改,在GD的梯度更新上改动:
1. Momentum动量
具体的含义就是保持惯性操作,保持沿着原始下降的方向,这样可以跨过局部最优值,迈向全局最优解,定义的更新公式如下:
V
t
=
γ
V
t
−
1
+
η
∇
θ
J
(
θ
)
V_t=\gamma V_{t-1} + \eta \nabla_{\theta}J(\theta)
Vt=γVt−1+η∇θJ(θ)
θ
=
θ
−
V
t
\theta = \theta - V_t
θ=θ−Vt
2.NAG
更新方式修改为:
θ
′
=
θ
−
γ
V
t
−
1
\theta' = \theta - \gamma V_{t-1}
θ′=θ−γVt−1
V
t
=
γ
V
t
−
1
+
η
∇
θ
J
(
θ
′
)
V_t=\gamma V_{t-1}+\eta \nabla_{\theta}J(\theta')
Vt=γVt−1+η∇θJ(θ′)
θ
=
θ
−
V
t
\theta=\theta-V_t
θ=θ−Vt
主要是修正收惯性影响太大,提高当前计算的影响力