返回目录

第八节课:梯度下降优化算法

课堂作业

详细介绍三种最具影响力且被广泛引用的梯度下降改进算法:Adam、RMSprop和Momentum。

1. Adam (Adaptive Moment Estimation) 优化器

Adam算法由Kingma和Ba在2014年提出,是目前深度学习中使用最广泛的优化算法之一,其原始论文被引用超过10万次。

1.1 算法思想

Adam结合了动量法(Momentum)和自适应学习率方法(如AdaGrad、RMSprop)的优点,通过计算梯度的一阶矩估计和二阶矩估计来为每个参数动态调整学习率。

1.2 数学原理

设目标函数为 $f(\theta)$,其中 $\theta$ 为模型参数,$g_t = \nabla_\theta f(\theta_t)$ 为时刻 $t$ 的梯度。

步骤1:计算一阶矩估计(动量项)

$m_t = \beta_1 m_{t-1} + (1 - \beta_1) g_t$

步骤2:计算二阶矩估计(梯度平方的指数移动平均)

$v_t = \beta_2 v_{t-1} + (1 - \beta_2) g_t^2$

步骤3:偏差修正

由于 $m_0 = 0$ 和 $v_0 = 0$,在训练初期会产生偏向零的偏差,需要进行修正:

$\hat{m}_t = \frac{m_t}{1 - \beta_1^t}$

$\hat{v}_t = \frac{v_t}{1 - \beta_2^t}$

步骤4:参数更新

$\theta_{t+1} = \theta_t - \frac{\eta}{\sqrt{\hat{v}_t} + \epsilon} \hat{m}_t$

1.3 超参数设置

1.4 算法优势

  1. 自适应学习率:为每个参数自动调整学习率,减少手动调参的需要
  2. 偏差修正:有效处理训练初期的偏差问题
  3. 稀疏梯度友好:对稀疏梯度具有良好的处理能力
  4. 收敛稳定:结合动量和自适应学习率的优点,收敛更加稳定

2. RMSprop (Root Mean Square Propagation)

RMSprop由Geoffrey Hinton在其Coursera课程中提出,虽然没有正式发表的论文,但被广泛采用并成为许多深度学习框架的标准优化器。

2.1 算法思想

RMSprop解决了AdaGrad算法中学习率单调递减导致训练后期学习率过小的问题。通过使用指数移动平均来限制历史梯度平方的累积,使得学习率能够在训练过程中保持合理的水平。

2.2 数学原理

步骤1:计算梯度平方的指数移动平均

$E[g^2]_t = \gamma E[g^2]_{t-1} + (1 - \gamma) g_t^2$

步骤2:参数更新

$\theta_{t+1} = \theta_t - \frac{\eta}{\sqrt{E[g^2]_t + \epsilon}} g_t$

其中:$\gamma$ 为衰减因子(通常为 0.9),$\eta$ 为学习率(通常为 0.001),$\epsilon$ 为防止除零的小常数(通常为 $10^{-8}$)

2.3 与AdaGrad的比较

AdaGrad的更新公式为:$\theta_{t+1} = \theta_t - \frac{\eta}{\sqrt{G_t + \epsilon}} g_t$

其中 $G_t = \sum_{i=1}^{t} g_i^2$ 是所有历史梯度平方的累积和。

RMSprop通过指数移动平均 $E[g^2]_t$ 替代了累积和 $G_t$,避免了学习率的无限递减。

2.4 算法优势

  1. 解决学习率衰减问题:避免了AdaGrad中学习率过度衰减的问题
  2. 适应非平稳目标:对非平稳目标函数具有良好的适应性
  3. 计算效率高:相比于二阶方法,计算开销较小
  4. RNN友好:在循环神经网络训练中表现优异

3. Momentum (动量法)

动量法最早由Polyak在1964年提出,后来Nesterov在1983年提出了加速版本。作为经典的优化方法,其相关工作累计被引用数万次。

3.1 算法思想

动量法借鉴了物理学中的动量概念,通过累积历史梯度信息来加速收敛并减少震荡。就像一个球滚下山坡时会积累动量一样,参数更新也会在一致的方向上积累"动量"。

3.2 标准动量法

数学公式

$v_t = \gamma v_{t-1} + \eta g_t$

$\theta_{t+1} = \theta_t - v_t$

其中:

等价形式:$\theta_{t+1} = \theta_t - (\gamma v_{t-1} + \eta g_t)$

3.3 Nesterov加速梯度(NAG)

Nesterov加速梯度是动量法的改进版本,具有"预见性"。

数学公式

$v_t = \gamma v_{t-1} + \eta \nabla f(\theta_t - \gamma v_{t-1})$

$\theta_{t+1} = \theta_t - v_t$

关键思想:NAG首先根据当前动量 $\gamma v_{t-1}$ 进行一个"预测性"跳跃到 $\theta_t - \gamma v_{t-1}$,然后在该位置计算梯度,最后结合这个梯度和动量进行实际的参数更新。

3.4 几何直观

在损失函数的等高线图中:

3.5 算法优势

  1. 加速收敛:在相关方向上积累速度,加快收敛
  2. 减少震荡:在不相关方向上减少震荡
  3. 跳出局部最优:动量可能帮助跳出浅的局部最优解
  4. 简单有效:实现简单,计算开销小

4. 三种算法的比较分析

4.1 收敛特性比较

算法 收敛速度 稳定性 超参数敏感性 内存开销
Momentum 中等 中等
RMSprop 中等 中等
Adam

4.2 适用场景

Momentum适用于

RMSprop适用于

Adam适用于

4.3 实际应用建议

  1. 首选Adam:在大多数情况下,Adam是一个安全的选择
  2. 考虑RMSprop:对于RNN或梯度稀疏的问题
  3. 尝试Momentum:当需要更好的泛化性能或计算资源受限时

5. 算法实现示例

5.1 Adam算法实现

class Adam:
    def __init__(self, lr=0.001, beta1=0.9, beta2=0.999, epsilon=1e-8):
        self.lr = lr
        self.beta1 = beta1
        self.beta2 = beta2
        self.epsilon = epsilon
        self.m = {}  # 一阶矩估计
        self.v = {}  # 二阶矩估计
        self.t = 0   # 时间步
  
    def update(self, params, grads):
        self.t += 1
        for key in params:
            if key not in self.m:
                self.m[key] = np.zeros_like(params[key])
                self.v[key] = np.zeros_like(params[key])
          
            # 更新一阶和二阶矩估计
            self.m[key] = self.beta1 * self.m[key] + (1 - self.beta1) * grads[key]
            self.v[key] = self.beta2 * self.v[key] + (1 - self.beta2) * grads[key]**2
          
            # 偏差修正
            m_hat = self.m[key] / (1 - self.beta1**self.t)
            v_hat = self.v[key] / (1 - self.beta2**self.t)
          
            # 参数更新
            params[key] -= self.lr * m_hat / (np.sqrt(v_hat) + self.epsilon)

5.2 RMSprop算法实现

class RMSprop:
    def __init__(self, lr=0.001, gamma=0.9, epsilon=1e-8):
        self.lr = lr
        self.gamma = gamma
        self.epsilon = epsilon
        self.v = {}  # 梯度平方的指数移动平均
  
    def update(self, params, grads):
        for key in params:
            if key not in self.v:
                self.v[key] = np.zeros_like(params[key])
          
            # 更新梯度平方的指数移动平均
            self.v[key] = self.gamma * self.v[key] + (1 - self.gamma) * grads[key]**2
          
            # 参数更新
            params[key] -= self.lr * grads[key] / (np.sqrt(self.v[key]) + self.epsilon)

5.3 Momentum算法实现

class Momentum:
    def __init__(self, lr=0.01, gamma=0.9):
        self.lr = lr
        self.gamma = gamma
        self.v = {}  # 速度(动量项)
  
    def update(self, params, grads):
        for key in params:
            if key not in self.v:
                self.v[key] = np.zeros_like(params[key])
          
            # 更新速度
            self.v[key] = self.gamma * self.v[key] + self.lr * grads[key]
          
            # 参数更新
            params[key] -= self.v[key]

总结

本作业介绍了三种最具影响力的梯度下降改进算法:

  1. Adam:结合动量和自适应学习率,是目前最流行的优化算法
  2. RMSprop:解决AdaGrad学习率衰减问题,适合非平稳目标函数
  3. Momentum:利用历史梯度信息加速收敛,简单有效