机器学习优化器

机器学习相关

参考:https://mp.weixin.qq.com/s/5yqsceEdapqIEOn1p5tV-Q

1. 优化器相关

  • 优化器有哪些?有什么区别?
    • 历史演变:SGD -> SGDM -> NAG -> AdaGrad -> AdaDelta -> Adam -> Nadam -> AdamW
    • 统一框架:
      • 定义:待优化参数: \(w\) ,目标函数:\(f(x)\) ,初始学习率: \(\alpha\)

      • 在每个 epoch \(t\) :

        1. 计算目标函数 \(f(x)\) 关于当前参数的梯度:
          • \(g_t = \Delta f(w_t)\) ---(1)
        2. 根据历史梯度 \((g_1, g_2, ..., g_t)\) 计算一阶动量和二阶动量:
          • \(m_t = \phi(g_1, g_2, ..., g_t)\) 和 \(V_t = \Phi(g_1, g_2, ..., g_t)\) -----(2)
        3. 计算当前时刻的下降梯度:
          • \(\eta _t = \alpha \cdot m_t / \sqrt{V_t}\) ----(3)
        4. 根据下降梯度更新:
          • \(w_{t+1} = w_t-\eta _t\) ----(4)
      • 我们拿着这个框架,来照一照各种玄乎其玄的优化算法的真身。步骤3, 4对于各个算 法都是一致的,主要的差别就体现在1和2上,也就是计算一阶动量 \(m_t\) 和二阶动量 \(V_t\) 时采用不同的套路。当计算好二者之后,都是使用固定的学习率 \(\alpha\) 与二者作用得到当前时刻的下降梯度 \(\eta _t\),进而最后更新参数。

    • 分类一(使用一阶 / 二阶动量):
      • 仅使用一阶动量:SGD , SGDM , NAG
      • 仅使用二阶动量:AdaGradAdaDelta
      • 同时使用一阶和二阶动量:Adam, NadamAdamW
    • 分类二 (一阶近似 / 二阶近似):
      • 一阶/二阶 使用函数泰勒展式的几阶项来划分。
      • 这里所有的方法都是一阶近似方法。
      • 二阶方法:牛顿法,BFGS。
    • SGD
      • SGD 没有动量的概念,所以在第(2)步中:
        • \(m_t = g_t\)
        • \(V_t = I^2\)
        • \(\eta_t=\alpha \cdot g_t\)
      • SGD的最大缺点就是下降速度慢,可能会在沟壑两边震荡且停留在局部最优点。
    • SGDM (SGD with Momentum)
      • SGD 上引入一阶动量:
        • \(m_t = \beta_1\cdot m_{t-1}+(1-\beta_1)\cdot g_t\);
        • \(V_t = I^2\)
        • \(\eta_t=\alpha \cdot m_t\)
      • 一阶动量是各个时刻梯度方向的指数移动平均值,约等于最近 \(1/(1-\beta_1)\) 个时刻的梯度向量和的平均值。
      • \(\beta_1\) 的经验值为 0.9
    • NAG (Nesterov Accelerated Gradient)
      • 是在 SGDSGDM 上的基础上进一步改进的,改进的是步骤(1)。
      • 原理是:

        我们知道在时刻 的主要下降方向是由累积动量决定的,自己的梯度方向说了也不算,那与其看当前梯度方向,不如先看看如果跟着累积动量走了一步,那个时候再怎么走。

      • 当前梯度计算为:
        • \(g_t = \Delta f(w_t-\beta_1\cdot m_{t-1}/\sqrt{V_{t-1}})\)
    • AdaGrad
      • 二阶动量的出现,才意味着“自适应学习率”优化算法时代的到来。
      • SGD及其变种以同样的学习率更新每个参数,但深度神经网络往往包含大量的参数,这些参数并不是总会用得到(想想大规模的embedding)。对于经常更新的参数,我们已经积累了大量关于它的知识,不希望被单个样本影响太大,希望学习速率慢一些;对于偶尔更新的参数,我们了解的信息太少,希望能从每个偶然出现的样本身上多学一些,即学习速率大一些.

      • 用二阶动量度量历史更新频率:
        • \(V_t = \sum_{\tau=1}^t g_{\tau}^2\)
        • 步骤(3)中的下降梯度:\(\eta_t=\alpha \cdot m_t/\sqrt{V_t}\)
        • 此时的学习率 \(\alpha = \alpha/\sqrt{V_t}\),其中 \(\sqrt{V_t}\) 是恒大于0的,参数更新越频繁,二阶动量越大,学习率就越小。
      • 存在的问题:过于激进。因为 \(\sqrt{V_t}\) 是单调递增的,会使得学习率单调递减至 0,可能会使得训练过程提前结束,即便后续还有数据也无法学到必要的知识。
    • AdaDelta / RMSProp
      • 类似于 AdaGrad,但是仅使用过去一段时间窗口(Delta)内的平均值。
      • \(V_t = \beta_2\cdot V_{t-1} + (1-\beta_2)\cdot g_t^2\)
      • 然后还是步骤(3)更新梯度(此时 \(m_t = g_t\)):
      • \(\eta _t = \alpha \cdot m_t / \sqrt{V_t}\)
      • 这样避免了二阶动量持续累积、导致训练过程提前结束的问题了。
    • Adam (Adaptive + Momentum)
      • 把一阶动量和二阶动量都用起来。
      • SGDM 的一阶动量:\(m_t = \beta_1\cdot m_{t-1} +(1-\beta_1)\cdot g_t\)
      • 加上 AdaDelta 的二阶动量:
        • \(\hat m_t = \frac{m_t}{1-\beta_1^t}\)
        • \(\hat{V_t} = \frac{V_t}{1-\beta_2^t}\)
      • 这里的两个超参数 \(\beta_1\) 和 \(\beta_2\)分别控制一阶动量和二阶动量。
    • Nadam (Nesterov + Adam)
      • Adam 的基础上加上了 Nesterov
      • 加上 NAG 的一阶动量:
        • \(g_t = \Delta f(w_t-\beta_1\cdot m_{t-1}/\sqrt{V_{t-1}})\)
    • AdamW (Adam with decoupled Weight decay):
      • Adam 的改进版本 (AdamW 就是 Adam 优化器加上 L2 正则,来限制参数值不可太大)
      • 一般的正则项加在 Loss 函数后面(粉色):
        • \(loss = f(w) + 0.5\cdot \gamma\cdot{\| \theta\|}^2\)
      • 但是 AdamW 选择将正则项加在了 Adam 的和等参数被计算完之后、在与学习率相乘之前(绿色)。
上一篇:[Contest on 2021.9.2] 读不懂题啊!


下一篇:CF1450H2 - Multithreading (Hard Version)