我们考虑以下场景:你开了一家店,需要根据前几年的收入预测今年收入,也就是序列数据的预测问题。这时候最简单的就是取平均值,但是这样就损失了序列数据的特点,即时间上越靠近现在,其数值对当前的影响越大。此时,我们可以使用指数加权平均:
V0=0Vt=βVt−1+(1−β)θt
也即:
V0=0,β=0.7V1=0.7V0+0.3θ1V2=0.7V1+0.3θ2V3=0.7V2+0.3θ3V4=0.7V3+0.3θ4V5=0.7V4+0.3θ5V6=0.7V5+0.3θ6
代入可得:
V6=0.7(0.7V4+0.3θ5)+0.3θ6V6=0.72V4+0.3∗0.7θ5+0.3θ6V6=0.72(0.7V3+0.3θ4)+0.3∗0.7θ5+0.3θ6V6=0.73V3+0.3∗0.72θ4+0.3∗0.7θ5+0.3θ6=0.343V3+0.147θ4+0.21θ5+0.3θ6
所以我们能够看到,之前的数值将以指数模式衰减,所以被称之为指数加权平均。
但是,当我们计算每天的V时,我们会发现,前几天的V会偏小,因为我们的V是按0进行初始化的,这时,我们进行一些修正:
Vtcorrect=1−βtVt
第一天第二天第三天第四天第五天第六天第七天θ100114118117120122?V3055.274.0486.996.83104.38?1−βt0.30.5108570.760.8520.942?Vcorrect100108.2112.6114.3116.4110.8?
在神经网络中,我们会计算各个参数的梯度,然后朝梯度的反方向更新参数,但是这时候有一个问题,神经网络参数很多,参数梯度有时大有时小,有时正有时负,这会让我们的训练不稳定。那么如何稳定梯度呢?我们可以用梯度的指数加权平均来更新参数:
gw=∂w∂Lgb=∂b∂LVw=βVw+(1−β)gwβ=0.9Vb=βVb+(1−β)gbwt+1=wt−rVwbt+1=bt−rVb
RMSProp想解决神经网络不同参数梯度大小不同的问题,其想法是让每个参数的梯度除以一个代表这个梯度平均大小的值,这样各个参数的梯度就差不多大了,训练就稳定了。
方式是计算每个参数梯度平方的指数加权平均值,然后在更新参数时,用当前的参数除以指数加权平均值的平方根,此时由于防止除0,所以加入了一个很小的正值:
gw=∂w∂Lgb=∂b∂LSw=βSw+(1−β)gw2β=0.9Sb=βSb+(1−β)gb2wt+1=wt−rSw+εgwbt+1=bt−rSb+εgb
Adam就是将Momentum和RMSProp进行了结合,并对指数加权平均值进行了修正:
gw=∂w∂LVw=β1Vw+(1−β1)gwβ1=0.9Sw=β2Sw+(1−β2)gw2β2=0.999Vwcorrect=1−β1tVwSwcorrect=1−β2tSwWt+1=wt−rSWcorrect+εVWcorrect
AdamW其实就是在Adam的基础上加了个weight decay:
Wt+1=Wt−rSwcorrect+εVcorrect−rλWt
另外注意,无论是Adam还是AdamW,他们都需要针对每个参数额外保存两个值Sw和Vw,每个值都需要用float32来存储,如果参数用float16存储,这两个值占用大小将是参数量的4倍。