1、梯度下降法
梯度下降是神经网络优化应用最多的算法。
要使用梯度下降法找到一个函数的局部极小值,必须向函数上当前点对应梯度(或者是近似梯度)的反方向的规定步长距离点进行迭代搜索。如果相反地向梯度正方向迭代进行搜索,则会接近函数的局部极大值点;这个过程则被称为梯度上升法。
梯度下降法的缺点包括:
- 靠近局部极小值时速度减慢。
- 直线搜索可能会产生一些问题。
- 可能会“之字型”地下降。
GD 优化公式是:
梯度下降法分成三类,batch GD,stochastic GD,mini-batch GD.
三者分别是使用全量样本、随机一个样本、部分样本计算梯度。具体参考:随机梯度下降法 SGD;
1.1 梯度下降法能保证收敛吗?
梯度下降不一定能够找到全局的最优解,有可能是一个局部最优解。当然,如果损失函数是凸函数,梯度下降法得到的解就一定是全局最优解。
1.2 梯度下降法的神经网络容易收敛到局部最优,为什么应用广泛?
非凸优化的全局最小值点的求解是个NP难问题,除非穷举所有情况不然没可能避免;或者你得用一个凸函数去近似这个非凸函数。
在高维特征空间,梯度为0的情形是鞍点的概率会远大于局部最优点!
mini-batch的梯度下降法使得模型很容易逃离特征空间中的鞍点。
在高维空间里(深度学习问题上)真正可怕的不是局部最优也不是鞍点问题,而是一些特殊地形。比如大面积的平坦区域:
在平坦区域,虽然导数不为0但是却不大。虽然是在不断下降但是路程却非常长。对于优化算法来说,它需要走很多很多步才有可能走过这一片平坦区域。
以下是梯度下降优化算法介绍:
2、动量(Momentum)
动量算法,目的是为了让SGD尽可能地跳出局部最优值。
v t = γ v t ? 1 + η ? θ J ( θ ) θ = θ ? v t v_t = \gamma v_{t-1} + \eta \nabla_\theta J( \theta) \\ \theta = \theta - v_t vt?=γvt?1?+η?θ?J(θ)θ=θ?vt?
可以看出,和传统的SGD相比,增加了一个动量系数 γ γ γ,给上一步算出的梯度一定的权重(类似惯性);
一般,动量系数 γ γ γ设为0.9;也就是说,更新的部分占比更多,更加容易走出局部最优。
3. Nestrov accelerated gradient
Nesterov accelerated gradient (NAG)
v t = γ v t ? 1 + η ? θ J ( θ ? γ v t ? 1 ) θ = θ ? v t \begin{aligned} v_{t} &=\gamma v_{t-1}+\eta \nabla_{\theta} J\left(\theta-\gamma v_{t-1}\right) \\ \theta &=\theta-v_{t} \end{aligned} vt?θ?=γvt?1?+η?θ?J(θ?γvt?1?)=θ?vt??
加速方法是提前按照之前的动量走了一步,然后求导后按梯度再走一步。
3、Adagrad
对每次更新的不同参数 θ i \theta_i θi?(也就是自变量每个维度)使用不同的学习率;频繁出现的特征会使用小的学习率,适用处理稀疏数据。研究发现,Adagrad能提高SGD的鲁棒性。
学习率和过去的梯度有关。
g t , i = ? θ J ( θ t , i ) θ t + 1 , i = θ t , i ? η G t , i i + ? ? g t , i g_{t, i}=\nabla_{\theta} J\left(\theta_{t, i}\right) \\ \theta_{t+1, i} = \theta_{t, i} - \dfrac{\eta}{\sqrt{G_{t, ii} + \epsilon}} \cdot g_{t, i} gt,i?=?θ?J(θt,i?)θt+1,i?=θt,i??Gt,ii?+??η??gt,i?
G t ∈ R d × d G_{t} \in \mathbb{R}^{d \times d} Gt?∈Rd×d是对角矩阵,对角元素是参数 θ i \theta_i θi?的梯度平方和。(这里还是有点疑惑, θ \theta θ 和 G的维度应该是一样, θ \theta θ这是代表矩阵? g t , i g_{t,i} gt,i?应该对于 G t , i G_{t,i} Gt,i??)
等价的另一种表达:
θ t + 1 = θ t ? η G t + ? ⊙ g t \theta_{t+1} = \theta_{t} - \dfrac{\eta}{\sqrt{G_{t} + \epsilon}} \odot g_{t} θt+1?=θt??Gt?+??η?⊙gt?
其中,
G t = G t ? 1 + g t ⊙ g t G_t = G_{t-1} + g_t \odot g_t Gt?=Gt?1?+gt?⊙gt?
目标函数中的自变量中的每个元素的学习率通过按元素运算重新调整了。
这里,把权重参数W代入:
class AdaGrad:def __init__(self, lr=0.01):self.lr = lrself.h = Nonedef update(self, params, grads):if self.h is None:self.h = {
}for key, val in params.items():self.h[key] = np.zeros_like(val)for key in params.keys():self.h[key] += grads[key] * grads[key]params[key] -= self.lr * grads[key] / (np.sqrt(self.h[key]) + 1e-7)
优点:
一开始梯度小,学习率大;后面梯度大,学习率小,收敛快。
缺点
由于 G 是梯度的平方和,所以会不断的累加,最终导致学习率很低,以至于学不到什么东西。
4、 Adadelta
针对Adagrad的缺点,Adadelta 的学习率是和一定长度的积累梯度有关,也就是增加了一个控制计算积累梯度的参数 ω ω ω;
定义一个之前梯度的平均和现在梯度的线性和,并称为衰减平均值:
E [ g 2 ] t = γ E [ g 2 ] t ? 1 + ( 1 ? γ ) g t 2 E[g^2]_t = \gamma E[g^2]_{t-1} + (1 - \gamma) g^2_t E[g2]t?=γE[g2]t?1?+(1?γ)gt2?
因此,用 E 代替 G,有:
Δ θ t = ? η E [ g 2 ] t + ? g t \Delta \theta_t = - \dfrac{\eta}{\sqrt{E[g^2]_t + \epsilon}} g_{t} Δθt?=?E[g2]t?+??η?gt?
5. RMSprop
和Adadelta一样,都是为了解决Adagrad的学习率变得很小的问题。
E [ g 2 ] t = 0.9 E [ g 2 ] t ? 1 + 0.1 g t 2 θ t + 1 = θ t ? η E [ g 2 ] t + ? g t \begin{aligned} E\left[g^{2}\right]_{t} &=0.9 E\left[g^{2}\right]_{t-1}+0.1 g_{t}^{2} \\ \theta_{t+1} &=\theta_{t}-\frac{\eta}{\sqrt{E\left[g^{2}\right]_{t}+\epsilon}} g_{t} \end{aligned} E[g2]t?θt+1??=0.9E[g2]t?1?+0.1gt2?=θt??E[g2]t?+??η?gt??
不同于AdaGrad算法?状态变量st是截?时间步t所有小批量随机梯度gt按元素平?和,RMSProp算法将这些梯度按元素平?做指数加权移动平均。
6. Adam(Adaptive Moment estimation)
Adam算法在RMSProp算法基础上对小批量随机梯度也做了指数加权移动平均。相当于 RMSprop + Momentum。
自适应时刻估计,对学习率进行自动学习。
它主要是,对过去平方梯度的指数衰减平均值,(这个Adadelta也是这样做),同时,Adam 会保持过去梯度的指数衰减平均值。(这个和动量算法是一样的)
m t = β 1 m t ? 1 + ( 1 ? β 1 ) g t v t = β 2 v t ? 1 + ( 1 ? β 2 ) g t 2 m_t = \beta_1 m_{t-1} + (1 - \beta_1) g_t \\ v_t = \beta_2 v_{t-1} + (1 - \beta_2) g_t^2 mt?=β1?mt?1?+(1?β1?)gt?vt?=β2?vt?1?+(1?β2?)gt2?
m t , v t m_t,v_t mt?,vt?分别计算梯度的均值和方差,初始化都是 0 向量。
并且进行偏差修正,
m ^ t = m t 1 ? β 1 t v ^ t = v t 1 ? β 2 t \hat{m}_t = \dfrac{m_t}{1 - \beta^t_1} \\ \hat{v}_t = \dfrac{v_t}{1 - \beta^t_2} m^t?=1?β1t?mt??v^t?=1?β2t?vt??
Adam的更新:
θ t + 1 = θ t ? η v ^ t + ? m ^ t \theta_{t+1} = \theta_{t} - \dfrac{\eta}{\sqrt{\hat{v}_t} + \epsilon} \hat{m}_t θt+1?=θt??v^t??+?η?m^t?
7. AdaMax
p函数的衰减:
v t = β 2 p v t ? 1 + ( 1 ? β 2 p ) ∣ g t ∣ p v_{t}=\beta_{2}^{p} v_{t-1}+\left(1-\beta_{2}^{p}\right)\left|g_{t}\right|^{p} vt?=β2p?vt?1?+(1?β2p?)∣gt?∣p
如果是无穷范数:
u t = β 2 ∞ v t ? 1 + ( 1 ? β 2 ∞ ) ∣ g t ∣ ∞ = max ? ( β 2 ? v t ? 1 , ∣ g t ∣ ) \begin{aligned} u_{t} &=\beta_{2}^{\infty} v_{t-1}+\left(1-\beta_{2}^{\infty}\right)\left|g_{t}\right|^{\infty} \\ &=\max \left(\beta_{2} \cdot v_{t-1},\left|g_{t}\right|\right) \end{aligned} ut??=β2∞?vt?1?+(1?β2∞?)∣gt?∣∞=max(β2??vt?1?,∣gt?∣)?
8. Nadam
g t = ? θ t J ( θ t ) m t = γ m t ? 1 + η g t θ t + 1 = θ t ? m t \begin{aligned} g_{t} &=\nabla_{\theta_{t}} J\left(\theta_{t}\right) \\ m_{t} &=\gamma m_{t-1}+\eta g_{t} \\ \theta_{t+1} &=\theta_{t}-m_{t} \end{aligned} gt?mt?θt+1??=?θt??J(θt?)=γmt?1?+ηgt?=θt??mt??
θ t + 1 = θ t ? ( γ m t ? 1 + η g t ) \theta_{t+1}=\theta_{t}-\left(\gamma m_{t-1}+\eta g_{t}\right) θt+1?=θt??(γmt?1?+ηgt?)
9. 其他
AdamW:和Adam类似,只是加上weight decay的实现有点区别:
ASGD: 平均的SGD
LBFGS:
最近开通了个公众号,主要分享推荐系统,风控等算法相关的内容,感兴趣的伙伴可以关注下。
参考:
- 推荐 梯度优化算法;
- ADAM: A METHOD FOR STOCHASTIC OPTIMIZATION;
- pytorch;
- hinton course ppt;
- 深度学习——优化器算法Optimizer详解(BGD、SGD、MBGD、Momentum、NAG、Adagrad、Adadelta、RMSprop、Adam);
- wiki 梯度下降;
- 梯度下降法的神经网络容易收敛到局部最优,为什么应用广泛?