一、变量说明
以下算法均为针对小批量梯度下降的算法,对于每个batch, 计算各个模型参数值为xtx_txt,参数梯度值为gtg_tgt,ttt为更新的步数。
- xtx_txt: 第t次迭代时的模型参数集合
- gtg_tgt: 第t-1次迭代反向传播计算得到的参数梯度集合
- η\etaη: 学习率标量
- ⊙\odot⊙: 按元素相乘
通常称梯度的指数加权平均为一阶矩估计(动量),即下文中的vt\boldsymbol v_tvt,称st\boldsymbol s_tst为二阶矩估计。
此外,除了SGD,后面基于指数平滑的算法都称为适应性算法。
二、算法介绍
2.1 小批量随机梯度下降(SGD)
- 思想:用一个batch的数据计算出梯度,按照如下公式更新
- 更新公式:
xt=xt−1−ηgt\boldsymbol x_t= \boldsymbol x_{t-1} -\eta \boldsymbol g_txt=xt−1−ηgt - 缺点: 由于SGD固定的学习率,如果在某个点因为噪声计算出一个异常梯度,模型将朝着错误的方向更新,如果运气不好,模型可能无法收敛、收敛很慢、或者无法收敛到最优值。
- 空间复杂度:2∗∣x∣2*|\boldsymbol x|2∗∣x∣
2.2 动量法
- 思想:动量法通过对各个自变量的历史梯度进行指数加权平均,避免模型参数来回震荡。
- 更新公式:
vt=γvt−1+ηgtxt=xt−1−vt\boldsymbol v_t = \gamma \boldsymbol v_{t-1}+\eta\boldsymbol g_t \\ \boldsymbol x_t= \boldsymbol x_{t-1} -\boldsymbol v_tvt=γvt−1+ηgtxt=xt−1−vt - 缺点:虽能在一定程度上减缓SGD的劣势,但仍然存在震荡导致的收敛缓慢问题。
- 空间复杂度:3∗∣x∣3*|\boldsymbol x|3∗∣x∣
2.3 AdaGrad
- 思想:对模型中的每个参数,如果计算出梯度比较大,则给它一个较小的学习率。
- 更新公式:
st=st−1+gt⊙gt.xt=xt−1−ηst+ϵ⊙gt\boldsymbol s_t=\boldsymbol s_{t-1}+\boldsymbol g_t \odot \boldsymbol g_t \\.\\ \boldsymbol x_t= \boldsymbol x_{t-1}- \frac{\eta}{\sqrt{\boldsymbol s_t+\epsilon }} \odot \boldsymbol g_tst=st−1+gt⊙gt.xt=xt−1−st+ϵη⊙gt
其中ϵ\epsilonϵ是为了维护数值稳定添加的较小常数。 - 缺点:由于st\boldsymbol s_tst一直在累加,导致学习率可能会不断减小,可能没更新到最佳状态就开始原地踏步了。
- 空间复杂度:3∗∣x∣3*|\boldsymbol x|3∗∣x∣
2.4 RMSProp
- 思想: 对AdaGrad做了一点小修改,对st\boldsymbol s_tst进行加权平均, 避免它只增不减。
- 更新公式:
st=γst−1+(1−γ)gt⊙gt.xt=xt−1−ηst+ϵ⊙gt\boldsymbol s_t=\gamma \boldsymbol s_{t-1}+ (1- \gamma) \boldsymbol g_t \odot \boldsymbol g_t \\ .\\ \boldsymbol x_t= \boldsymbol x_{t-1}- \frac{\eta}{\sqrt{\boldsymbol s_t+\epsilon }} \odot \boldsymbol g_tst=γst−1+(1−γ)gt⊙gt.xt=xt−1−st+ϵη⊙gt - 缺点:增加超参数γ\gammaγ
- 空间复杂度:3∗∣x∣3*|\boldsymbol x|3∗∣x∣
2.5 AdaDelta
- 思想:也是对AdaGrad做修改,而且没有学习率这一超参数,而是使用模型参数的历史变化量代替学习率。
- 更新公式:
st=ρst−1+(1−ρ)gt⊙gt.gt′=Δxt−1+ϵst+ϵ⊙gt.Δxt=ρΔxt−1+(1−ρ)gt′⊙gt′.xt=xt−1−gt′\boldsymbol s_t=\rho \boldsymbol s_{t-1}+ (1- \rho) \boldsymbol g_t \odot \boldsymbol g_t \\ .\\ \boldsymbol g'_t =\sqrt{\frac{\Delta \boldsymbol x_{t-1} + \epsilon}{ \boldsymbol s_t + \epsilon}}\odot \boldsymbol g_t\\ .\\ \Delta \boldsymbol x_{t} = \rho\Delta \boldsymbol x_{t-1} +(1-\rho) \boldsymbol g'_t\odot \boldsymbol g'_t \\ .\\ \boldsymbol x_t= \boldsymbol x_{t-1}- \boldsymbol g'_t st=ρst−1+(1−ρ)gt⊙gt.gt′=st+ϵΔxt−1+ϵ⊙gt.Δxt=ρΔxt−1+(1−ρ)gt′⊙gt′.xt=xt−1−gt′ - 缺点:不知道为什么知名度不如Adam, 可能实验表明吧。
- 空间复杂度:4∗∣x∣4*|\boldsymbol x|4∗∣x∣
2.6 Adam
- 思想:RMSProp 和 动量法的结合版,并针对初始化导致的偏差进行修正(3,4行公式)
- 更新公式:
vt=β1vt−1+(1−β1)gt.st=β2st−1+(1−β2)gt⊙gt.v^t=vt1−β1t.s^t=st1−β2t.gt′=ηv^ts^t+ϵ.xt=xt−1−gt′ \boldsymbol v_t = \beta_1 \boldsymbol v_{t-1}+(1-\beta_1)\boldsymbol g_t \\ .\\ \boldsymbol s_t=\beta_2 \boldsymbol s_{t-1}+ (1- \beta_2) \boldsymbol g_t \odot \boldsymbol g_t \\ .\\ \hat{\boldsymbol v}_t = \frac{\boldsymbol v_t}{1-\beta^t_1} \\ .\\ \hat{\boldsymbol s}_t = \frac{\boldsymbol s_t}{1-\beta^t_2} \\ .\\ \boldsymbol g'_t = \frac{\eta \hat \boldsymbol v_t }{\sqrt{\hat \boldsymbol s_t } + \epsilon} \\ .\\ \boldsymbol x_t= \boldsymbol x_{t-1}- \boldsymbol g'_t vt=β1vt−1+(1−β1)gt.st=β2st−1+(1−β2)gt⊙gt.v^t=1−β1tvt.s^t=1−β2tst.gt′=s^t+ϵηv^t.xt=xt−1−gt′
空间复杂度:4∗∣x∣4*|\boldsymbol x|4∗∣x∣
三、常见问题
-
为什么适应性算法。例如Adam, 如果没有保存优化器参数,只使用之前的模型参数接着训练的话,会出先loss突然增大的问题?
答曰:适应性算法维护的平滑信息消失,相当于在当前点下直接进行SGD算法,丢失了稳定性,如果接着训练,也应该设置很小的初始学习率。(warm up也可以从这个角度解释,预热的过程实际上就是为了给这些算法提供平滑信息,这期间不要急着更新参数。)
关于这方面的知识,推荐这个综述:https://www.jiqizhixin.com/articles/2017-12-06(中文)http://ruder.io/deep-learning-optimization-2017/ (英文)
-
为什么word2vector中使用SGD而不能使用Adam? (不知道答的对不对,欢迎讨论)
答曰:按照word2vector的语言模型思想,一个输入中不存在的词,它对应的向量参数就不应该被更新。但是由于Adam维护的动量信息,会导致之前的动量不为0的所有词向量参数都会被惯性更新。导致过拟合或者说不满足word2vector模型的要求。
但但但但是,那不应该是所有Embedding的模型都会出现这个问题吗?这有两种可能:1. Embedding的实现需要自动屏蔽动量更新。2.在多层神经网络中,允许惯性更新,因为我们的目标往往是单纯你拟合训练数据,管你Embedding咋个跑呢!(希望知道的大神能够回答下这两个哪个对)
909

被折叠的 条评论
为什么被折叠?



