机器学习相关
参考:https://mp.weixin.qq.com/s/5yqsceEdapqIEOn1p5tV-Q
1. 优化器相关
- 优化器有哪些?有什么区别?
- 历史演变:
SGD -> SGDM -> NAG -> AdaGrad -> AdaDelta -> Adam -> Nadam -> AdamW
- 统一框架:
-
定义:待优化参数: \(w\) ,目标函数:\(f(x)\) ,初始学习率: \(\alpha\)
-
在每个
epoch
\(t\) :- 计算目标函数 \(f(x)\) 关于当前参数的梯度:
- \(g_t = \Delta f(w_t)\) ---(1)
- 根据历史梯度 \((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)
- 计算当前时刻的下降梯度:
- \(\eta _t = \alpha \cdot m_t / \sqrt{V_t}\) ----(3)
- 根据下降梯度更新:
- \(w_{t+1} = w_t-\eta _t\) ----(4)
- 计算目标函数 \(f(x)\) 关于当前参数的梯度:
-
我们拿着这个框架,来照一照各种玄乎其玄的优化算法的真身。步骤3, 4对于各个算 法都是一致的,主要的差别就体现在1和2上,也就是计算一阶动量 \(m_t\) 和二阶动量 \(V_t\) 时采用不同的套路。当计算好二者之后,都是使用固定的学习率 \(\alpha\) 与二者作用得到当前时刻的下降梯度 \(\eta _t\),进而最后更新参数。
-
- 分类一(使用一阶 / 二阶动量):
- 仅使用一阶动量:
SGD
,SGDM
,NAG
。 - 仅使用二阶动量:
AdaGrad
和AdaDelta
。 - 同时使用一阶和二阶动量:
Adam
,Nadam
和AdamW
- 仅使用一阶动量:
- 分类二 (一阶近似 / 二阶近似):
- 一阶/二阶 使用函数泰勒展式的几阶项来划分。
- 这里所有的方法都是一阶近似方法。
- 二阶方法:牛顿法,BFGS。
- SGD
- SGD 没有动量的概念,所以在第(2)步中:
- \(m_t = g_t\)
- \(V_t = I^2\)
- \(\eta_t=\alpha \cdot g_t\)
- SGD的最大缺点就是下降速度慢,可能会在沟壑两边震荡且停留在局部最优点。
- SGD 没有动量的概念,所以在第(2)步中:
- 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)
- 是在
SGD
和SGDM
上的基础上进一步改进的,改进的是步骤(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
的和等参数被计算完之后、在与学习率相乘之前(绿色)。
-
- 历史演变: