1 致谢
感谢赵老师的讲授!
2 前言
今天在学习Pytorch~记得Johnson助教好像讲过有一个优化算法最好用的,不过忘了是哪一个了,然后就回顾了一下赵老师讲课的视频;
3 最常用的Optimizer算法是Adam方法
最常用的Optimization算法是Adam方法;
(我在Wider Face数据集上用过一次Adam方法,不过用了一下感觉效果不是很好;
后来赵老师在课上讲到这种自适应的方法总存在一些局限性:
“从最后训练的精度上来看,还是SGD方法好一些,虽然训练会慢一些;如果是80个Epoch,可以先用Adam训练30个Epoch.等到最难的地方差不多过去的时候,再用SGD继续进行训练;”
我看了一下这个比例:3/8 = 0.375 = 1 - 0.625,感觉跟黄金比例有点类似0.618,
以后可以再做实验来看看; )
4 优化器函数说明
CLASS torch.optim.Optimizer(params, defaults)
所有优化器算法的基类。
Parameters:
- params (iterable) –
torch.Tensor
s或dict
s的迭代器。
5 常见的Optimizer算法
5.1 基本的符号表示
α \alpha α:学习率
5.1 SGD方法(Stochastic Gradient Descent)
就是最普通的随机梯度下降方法。
5.2 SGD with Momentum
带有动量的SGD优化方法。
其公式如下:
{
v
t
=
γ
v
t
−
1
−
α
⋅
∇
θ
J
(
θ
t
−
1
)
θ
t
=
θ
t
−
1
+
v
t
\left\{\begin{matrix} v_t = \gamma v_{t-1} - \alpha\cdot\nabla_\theta J\left ( \theta_{t-1}\right )\\ \theta_t = \theta_{t-1} + v_t \end{matrix}\right.
{vt=γvt−1−α⋅∇θJ(θt−1)θt=θt−1+vt
4.2 Nesterov方法
根据t时刻速度计算Momentum的方法,
其公式如下:
v
t
+
1
=
μ
∗
v
t
+
α
∗
g
t
p
t
+
1
=
p
t
−
l
r
∗
(
v
t
+
1
+
α
∗
g
t
)
v_{t+1} = \mu*v_{t} + \alpha*g_{t}\\ p_{t+1} = p_t - lr*(v_{t+1} + \alpha*g_{t})
vt+1=μ∗vt+α∗gtpt+1=pt−lr∗(vt+1+α∗gt)
(由于Nesterov方法有多种不同的实现方法,这里我们采用的是PyTorch的官方文档中给出的公式,此公式是我根据PyTorch中原始公式进行相应扩展得出的)
(单凭上面的公式难以直接看出Nesterov方法的含义,我们可以参考一下Nesterov方法的原始论文中的公式,
可以看到
t
+
1
t+1
t+1时刻的速度是由他
t
+
1
t+1
t+1时刻的梯度(即
∇
f
(
θ
t
+
μ
v
t
)
\nabla f\left ( \theta_t + \mu v_t\right )
∇f(θt+μvt))计算出来的)
(具体的推导可以参阅我的博文《深度学习——Nesterov方法的学习笔记》)
4.3 Adam方法
Adam方法的公式如下:
{
g
t
=
∇
θ
f
t
(
θ
t
−
1
)
m
t
=
β
1
⋅
m
t
−
1
+
(
1
−
β
1
)
⋅
g
t
v
t
=
β
2
⋅
v
t
−
1
+
(
1
−
β
2
)
⋅
g
t
2
m
^
t
=
m
t
1
−
β
1
t
v
^
t
=
v
t
1
−
β
2
t
θ
t
=
θ
t
−
1
−
α
⋅
m
^
t
v
^
t
+
ϵ
\left\{\begin{matrix} g_t = \nabla_\theta f_t\left ( \theta_{t-1}\right )\\ m_t = \beta_1\cdot m_{t-1}+\left ( 1 - \beta_1\right ) \cdot g_t\\ v_t = \beta_2\cdot v_{t-1} + \left ( 1 - \beta_2\right ) \cdot {g_t}^2\\ \hat{m}_t = \frac{m_t}{1 - {\beta_1}^t}\\ \hat{v}_t = \frac{v_t}{1 - {\beta_2}^t}\\ \theta_t = \theta_{t-1} - \frac{\alpha \cdot \hat{m}_t}{\sqrt{\hat{v}_t}+\epsilon} \end{matrix}\right.
⎩⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎧gt=∇θft(θt−1)mt=β1⋅mt−1+(1−β1)⋅gtvt=β2⋅vt−1+(1−β2)⋅gt2m^t=1−β1tmtv^t=1−β2tvtθt=θt−1−v^t+ϵα⋅m^t
在PyTorch中的函数形式为:
torch.optim.Adam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0, amsgrad=False)
其中
β
1
\beta_1
β1和
β
2
\beta_2
β2的默认值分别为
0.9
0.9
0.9和
0.999
0.999
0.999;
4.3.1 Adam算法形象化的解释
Adam算法最为优秀之处在于,解决了鞍点的问题,那么我们首先来看看什么是鞍点:
这个GIF的动图能很好地形象化地解释鞍点,以及各个优化器函数的表现;
在Adam算法中,分母v作为惩罚项,用来记录小球的能量;
则在鞍点附近,小球会有如下类似形象化的表现:
如果小球在x方向上震荡,则能量v会不断累计,而由于震荡,梯度一阶估计m则会出现有正有负的情况,从而被削弱,震荡变小;
同时,如果y方向是鞍点真正的落点,则由于小球在该方向上没有震荡,虽然能量也在累计,但是梯度的方向一直朝下,此时相对于x方向上的力而言,y方向上力占主导,从而引导小球向落点滑动,从而更加顺利的走出鞍点,滑向落点;
4.4 AdamW——Adam with decoupled weight decay
(请参见论文《Decoupled Weight Decay Regularization》)
AdamW也就是使用了“decoupled weight decay”的优化器算法,具体表现形式就是在后面加上了一个“衰减的正则项”,
这里的“正则项”是我在网上看到的解释(虽然明明老师也是这样解释的),不过我觉得不是很形象;
在我看来这里的“decoupled weight decay”实际上就是一种滑动平均,(将
η
t
λ
\eta_t\lambda
ηtλ移出来,写成
(
1
−
η
t
λ
)
θ
t
(1-\eta_t\lambda)\boldsymbol{\theta}_t
(1−ηtλ)θt),就可以发现这里的weight-decay实际上实现了一种滑动平均的效果;
(有三老师也说“weight-decay的参数都是为了移动平均”)
5 自适应Optimization算法
自适应最优解算法所解决的根本问题,就是如何解决不同参数朝向不同局部最优解前进时的分歧问题;
6 学习笔记
WeightDecay实际上就是L2-Regularization
这里我们需要记住的是:
WeightDecay实际上就是L2-Regularization。
关于相关的解释,请参考《动手学深度学习 2.0.0 | 4.5.1. 范数与权重衰减》;
一般来说,网络输出层的偏置项不需要正则化
这个观点也是在《动手学深度学习 2.0.0 | 4.5.1. 范数与权重衰减》看到的;