深度学习过程中的优化算法
BGD(batch gradient descent) & SGD(stochastic gradient descent) & mini-batch GD
- BGD是每次迭代的时候,使用所有的样本进行梯度下降,这种方法可以找到全局最优解,但是容易陷入局部最优,而且在数据量很大的时候难以进行(对内存的要求太高了,计算很慢)。
- SGD是每次只使用一个样本进行训练并使用GD更新梯度参数,这种方法计算简单,但是每次只使用一个样本,可能会会使得优化的过程中发生震荡、收敛变慢。
- mini-batch GD是每次使用若干个样本进行GD,样本个数为
batch size
,在深度学习训练过程中,一般将min-batch GD直接称为SGD,在训练过程中,建议尽量设置batch size大一些(最终计算时不超过GPU显存大小即可),可以加快收敛过程。 - SGD的更新公式
w : = w − η ⋅ ∂ L o s s ∂ w w: = w - \eta \cdot \frac{{\partial Loss}}{{\partial w}} w:=w−η⋅∂w∂Loss
Momentum SGD
- SGD容易陷入局部极小值,因此引入动量的方法,使得模型优化过程中有一定的速度,具体的参数更新方式如下
v : = α v − η ⋅ ∂ L o s s ∂ w w : = w + v \begin{array}{l} v: = \alpha v - \eta \cdot \frac{{\partial Loss}}{{\partial w}}\\ w: = w + v \end{array} v:=αv−η⋅∂w∂Lossw:=w+v
相对于SGD只需要学习率,momentum SGD还需要初始速度 v 0 v_0 v0,动量参数 α \alpha α。
AdaGrad
- AdaGrad可以自适应调整学习率,它在每次迭代时会累加梯度平方,在梯度下降时,累加和作为分母项,相当于对于优化频率高的样本使用小的学习率,对于优化频率低的样本使用大的学习率。计算公式如下
g : = ∂ L o s s ∂ w r : = r + g ⊙ g w : = w − η δ + r ⊙ g \begin{array}{l} g: = \frac{{\partial Loss}}{{\partial w}}\\ r: = r + g \odot g\\ w: = w - \frac{\eta }{{\delta + \sqrt r }} \odot g \end{array} g:=∂w∂Lossr:=r+g⊙gw:=w−δ+rη⊙g
其中, δ \delta δ是为了防止分母为0,一般可以取 1 0 − 7 10^{-7} 10−7。
RMSProp
- AdaGrad有梯度累积的问题,在后续的优化过程中,梯度更新会越来越慢,学习率几乎为0,针对这个问题,RMSProp参数更新计算方式如下
g : = ∂ L o s s ∂ w r : = ρ r + ( 1 − ρ ) g ⊙ g w : = w − η δ + r ⊙ g \begin{array}{l} g: = \frac{{\partial Loss}}{{\partial w}}\\ r: = \rho r + (1 - \rho )g \odot g\\ w: = w - \frac{\eta }{\delta + {\sqrt r }} \odot g \end{array} g:=∂w∂Lossr:=ρr+(1−ρ)g⊙gw:=w−δ+rη⊙g
Adam
- Adam算法充分利用了之前提到的
AdaGrad
和RMSProp
算法的优点,即可以动态调整学习率,而且它利用了一阶矩和二阶矩,一阶矩与动量SGD类似,二阶矩用于减小学习率,计算公式如下:
g : = ∂ L o s s ∂ w s : = β 1 s + ( 1 − β 1 ) g r : = β 2 r + ( 1 − β 2 ) g ⊙ g s : = s 1 − β 1 t r : = r 1 − β 2 t w : = w − η δ + r s \begin{array}{l} g: = \frac{{\partial Loss}}{{\partial w}}\\ s: = {\beta _1}s + (1 - {\beta _1})g\\ r: = {\beta _2}r + (1 - {\beta _2})g \odot g\\ s: = \frac{s}{{1 - \beta _1^t}}\\ r: = \frac{r}{{1 - \beta _2^t}}\\ w: = w - \frac{\eta }{{\delta + \sqrt r }}s \end{array} g:=∂w∂Losss:=β1s+(1−β1)gr:=β2r+(1−β2)g⊙gs:=1−β1tsr:=1−β2trw:=w−δ+rηs
其中 t t t是迭代的次数。一般超参数可以设置为 β 1 = 0.9 \beta_1 = 0.9 β1=0.9, β 2 = 0.999 \beta_2 = 0.999 β2=0.999, δ = 1 0 − 8 \delta = 10^{-8} δ=10−8。
牛顿法
- 牛顿法计算量大,需要计算矩阵的二阶矩,因而一般不在这种大规模数据集训练的情况下直接使用。
总结
- 在CNN中,一般SGD还是比较常用的,可能会结合一些动态学习率的策略(因子衰减、指数衰减等)来使用,Adam也可以使用,但是超参数调节需要注意一下,最好做一些实验验证选取的超参数。
- 在强化学习中,一般可以使用Adam,会有更好的迭代和收敛效果。