目录
NAG(Nesterov accelerated gradient )
回顾
机器学习3步骤: 1.给定model=function set 2.估计function好坏 3.找到最好的function
其中第2步定了loss function: L, 其参数为一个function(或其参数θ).
第3步, 找最好function=解一个最优解(optimization)问题: 找一组θ, 让L最小.
假设θ是一个参数集, {θ_1, θ_2}
随机选取起始点(一组参数):
$$ \theta^{0} = \begin{bmatrix} \theta_{1}^{0} \\ \theta_{2}^{0} \\ \end{bmatrix} $$
通过偏微分计算梯度, 代入得到更新的一组参数
$$ \theta^{1} = \theta^{0} - \eta\nabla L\left( \theta^{0} \right) $$
$$ \nabla L\left( \theta \right) = \begin{bmatrix} {{\partial L\left\lbrack \theta_{1} \right\rbrack}/{\partial\theta_{1}}} \\ {{\partial L\left\lbrack \theta_{2} \right\rbrack}/{\partial\theta_{2}}} \\ \end{bmatrix} $$
或可写作:
$$ \begin{bmatrix} \theta_{1}^{1} \\ \theta_{2}^{1} \\ \end{bmatrix} = \begin{bmatrix} \theta_{1}^{0} \\ \theta_{2}^{0} \\ \end{bmatrix} - \eta\begin{bmatrix} {{\partial L\left\lbrack \theta_{1}^{0} \right\rbrack}/{\partial\theta_{1}}} \\ {{\partial L\left\lbrack \theta_{2}^{0} \right\rbrack}/{\partial\theta_{2}}} \\ \end{bmatrix} $$
梯度gradient是一个vector, 等高线的法线方向. 用它更新参数, 走的方向是与gradient相反.
小心调整学习率
Tip 1: Tuning your learning rates
在高维空间( 参数很多 ), 没有办法直接对loss与参数可视化.
但可以对参数改变次数与loss改变进行可视化
在做梯度下降的时候, 应该把这个图画出来.
自动调整学习率方法
Adaptive Learning Rates
基本原则: 学习率随参数更新的迭代次数变小.( 最开始一般离最低点很远, 几次更新后更靠近目标, 减小学习率. )
每个不同参数需要不同学习率, 其中最容易的是Adagrad:
w是单个参数( 不是参数集 ). 基本想法是学习率η随迭代次数t变化(time dependent), g为梯度( 偏微分 )
$$ \eta^{t} = \frac{\eta}{\sqrt{t + 1}} $$
$$ g^{t} = \frac{\partial L\left( \theta^{t} \right)}{\partial w} $$
$$ w^{t + 1}\leftarrow w^{t} - \text{η}^{t}g^{t} $$
Adagrad还考虑了σ^t: 过去所有计算过的(对该参数)微分值的均方根RMS(root mean square)
$$ w^{t + 1}\leftarrow w^{t} - \frac{\text{η}^{t}}{\sigma^{t}}g^{t} $$
其学习率为η^t/σ^t, 如:
$$ w^{1}\leftarrow w^{0} - \frac{\text{η}^{0}}{\sigma^{0}}g^{0} $$ $$ \sigma^{0} = \sqrt{\left( g^{0} \right)^{2}} $$
$$ \sigma^{1} = \sqrt{\frac{1}{2}\left\lbrack {\left\lbrack g^{0} \right\rbrack^{2} + \left\lbrack g^{1} \right\rbrack^{2}} \right\rbrack} $$
$$ \sigma^{t} = \sqrt{\frac{1}{t + 1}{\sum_{i = 0}^{t}\left( g^{i} \right)^{2}}} $$
代入η^t和σ^t, Adagrad的式子可以写成:
$$ w^{t + 1}\leftarrow w^{t} - \frac{\eta}{\sqrt{\sum_{i = 0}^{t}\left( g^{i} \right)^{2}}}g^{t} $$
思考:
使用梯度下降法的初衷是, 梯度越大步长越大.
Aagrad的分母也有梯度g, 使得梯度越大时步长越小了. 矛盾吗?
这恰恰是因为Adagrad想要强调的是当前的梯度与过去的梯度反差有多大.
一般的梯度下降法可以这样解释:
设函数y=ax^2+bx+c, 从x_0点走到最优解处, 最佳的步长是(2a*x_0+b)/2a, 其分子刚好是原函数对参数x的一次微分.
但该想法只有在考虑单一参数时才成立,
若多个参数, 则c处比a处更近:
最佳步长(2a*x_0+b)/2a, 不仅与函数一次微分(2a*x_0+b成正比, 还与其二次微分2a成反比.
a点处一次微分( 梯度 )更小, 但同时二次微分也更小,
c点处一次微分( 梯度 )更大, 但同时二次微分也更大,
共同考虑才能真实反映离最优解的距离.
Adagrad式子中, 学习率分子上的g^t代表一次微分, 分母代表二次微分, 直接二次微分太难算了, 所以用它:
$$ \sqrt{\sum_{i = 0}^{t}\left( g^{i} \right)^{2}} $$
当然如果但算一个二次微分, 无法反映其二次微分. 但取够多点可以发现, 在平滑曲线处一次微分通常较小, 陡峭曲线反之.
随机梯度下降SGD
Stochastic Gradient Descent可以让训练更快
Loss是所有训练样本误差的总和, 然后可以做梯度下降. 若线性回归, 则Loss:
$$ L = {\sum_{n}\left( {{\hat{y}}^{n} - \left( {b + ~{\sum{w_{i}x_{i}^{n}}}} \right)} \right)^{2}} $$
stochastic不同, 每次只抽取1个样本( 可按顺序可随机, 随机有帮助 ), loss只考虑一个样本, 更新参数也只考虑一个样本.
$$ L^{n} = \left( {{\hat{y}}^{n} - \left( {b + ~{\sum{w_{i}x_{i}^{n}}}} \right)} \right)^{2} $$
$$ \theta^{i} = \theta^{i - 1} - \eta\nabla L^{n}\left( \theta^{i - 1} \right) $$
对比: 梯度下降是看完所有样本后参数走一步, 比较稳定.
随机梯度下降每看一个样本都更新一次参数. 在梯度下降法走一步的时候, 随机梯度下降法已经走了m步了.
特征归一化
Feature Scaling把两个属性值的分布范围变成相同.
如果属性x_1分布范围很小, 属性x_2分布范围很大, 那么当参数w_1, w_2加一样增量时, w_1*x_1的变化对y的影响更小.
其误差曲面在w1方向平滑, 在w2方向陡峭. 两个方向需要非常不同的学习率. 而其参数移动方向顺着等高线法线(梯度)方向, 并不指向圆心:
如果两属性值范围相似, 画出的loss比较接近圆形, w1, w2对loss有差不多的影响力. 等高线法线(梯度)方向, 指向圆心. 其参数更新更有效率:
Feature Scaling的方法
对每个属性维度i都计算均值m_i, 标准差σ_i.
按该公式特征归一化后所有维度均值0, 方差1:
$$ x_{i}^{r}\leftarrow\frac{x_{i}^{r} - m_{i}}{\sigma_{i}} $$
梯度下降原理
每次更新参数, 得到新的θ, 但不一定得到更小的Loss( 比如学习率太大情况 ).
如果要解一个最优解问题, 找最低点:
给定起始点θ^0, 作圆周,找出圆范围内最低点. 更新参数到最低点, 重新作圆…
那如何找出圆范围内最低点呢?
泰勒展开Taylor series:
函数h在x_0点无穷次可微( infinitely differentiable ), 则可展开:
$$ h\left( x \right) = {\sum_{k = 0}^{\infty}\frac{h^{(k)}\left( x_{0} \right)}{k!}}\left( {x - x_{0}} \right)^{k} \\= h\left( x_{0} \right) + h^{'}\left( x_{0} \right)\left( {x - x_{0}} \right) + \frac{h^{''}\left( x_{0} \right)}{2!}\left( {x - x_{0}} \right)^{2} + \ldots $$
当x接近x_0, (x-x_0)的高次项为高阶无穷小, 可以忽略不计:
$$ h(x) \approx h\left( x_{0} \right) + h^{'}\left( x_{0} \right)\left( {x - x_{0}} \right) $$
泰勒展开也可以有很多个参数:
$$ h({x,y}) \approx h\left( {x_{0},y_{0}} \right) + \frac{\partial h\left( {x_{0},y_{0}} \right)}{\partial x}\left( {x - x_{0}} \right) + \frac{\partial h\left( {x_{0},y_{0}} \right)}{\partial y}\left( {y - y_{0}} \right) $$
那么在刚刚画的很小的圆圈范围内, 可以把损失函数用泰勒展开简化:
$$ L\left( \theta \right) \approx L\left( {a,b} \right) + \frac{\partial L\left( {a,b} \right)}{\partial\theta_{1}}\left( {\theta_{1} - a} \right) + \frac{\partial L\left( {a,b} \right)}{\partial\theta_{2}}\left( {\theta_{2} - b} \right) $$
把该式中的常数分别用字母代替, L可写作:
$$ s = L\left( {a,b} \right)\\u = \frac{\partial L\left( {a,b} \right)}{\partial\theta_{1}},v = \frac{\partial L\left( {a,b} \right)}{\partial\theta_{2}}\\L\left( \theta \right) \approx s + u\left( {\theta_{1} - a} \right) + v\left( {\theta_{2} - b} \right) $$
在圆范围内, 要怎样选择θ_1, θ_2让L最小?
圆范围:
$$ \left( {\theta_{1} - a} \right)^{2} + \left( {\theta_{2} - b} \right)^{2} \leq d^{2}\\ \Delta\theta_{1} = \theta_{1} - a\\ \Delta\theta_{2} = \theta_{2} - b $$
L可以看作向量(u, v)与(Δθ_1, Δθ_2)内积, 当(Δθ_1, Δθ_2)取(u, v)的反向且长度到圆边缘时, 内积L最小. 而学习率η就是这个圆半径:
$$ \begin{bmatrix} {\Delta\theta_{1}} \\ {\Delta\theta_{2}} \\ \end{bmatrix} = - \eta\begin{bmatrix} u \\ v \\ \end{bmatrix}\\ \begin{bmatrix} \theta_{1} \\ \theta_{2} \\ \end{bmatrix} = \begin{bmatrix} a \\ b \\ \end{bmatrix} - \eta\begin{bmatrix} u \\ v \\ \end{bmatrix} = \begin{bmatrix} a \\ b \\ \end{bmatrix} - \eta\begin{bmatrix} \frac{\partial L\left\lbrack {a,b} \right\rbrack}{\partial\theta_{1}} \\ \frac{\partial L\left\lbrack {a,b} \right\rbrack}{\partial\theta_{2}} \\ \end{bmatrix} $$
用该式做梯度下降的前提是: 用泰勒展开近似L是够精确的->学习率η足够小, 画出的圈圈足够小.
有一些方法比如牛顿法, 用到展开到二次式. 但运算会复杂很多(如海瑟矩阵的逆), 在做深度学习时不划算, 所以不太普及.
梯度下降的局限性
局部最优和驻点(settle point)的微分为0, 用微分值判断会卡在局部最优解.
太可爱了, 老师还打开世纪帝国和Minecraft游戏举例子.
Optimization
背景知识
名词:
μ-strong convexity, Lipschitz continuity, Bregman proximal inequality
方法:
SGD, SGD with momentum(SGDM), Adagrad, RMSProp, Adam
记号:
𝜃_𝑡 : 第t次的模型参数( 就是优化的目标 )
∇𝐿(𝜃_𝑡) or 𝑔_𝑡: 𝜃_𝑡处通过Loss的微分计算梯度, 用来计算 𝜃_(𝑡+1)
𝑚_(𝑡+1): momentum 记录了从第0次到第t次梯度信息(也有压缩), 用来计算𝜃_(𝑡+1)
神经网络架构:
input x_t, 送进参数θ_t, 得到预测y_t(可能是过softmax后的几率向量, 或一张生成的图片)
要用optimization做什么事情:
找到参数使所有x的L最小
在线离线On-line vs Off-line
On-line:一次看一对 (𝑥_𝑡, 𝑦_𝑡)
Off-line: 每次都看所有数据
off-line更容易些, 但是可能没有这么多资源塞所有data. 剩下内容主要关注离线训练
Optimization方法
SGD
随机确定θ^0->计算θ^0处的梯度->往梯度反方向移动到θ^1=θ^0-η∇𝐿(𝜃^0)->…->梯度∇𝐿(𝜃^𝑡)接近0
随机梯度动量算法
SGD with Momentum(SGDM)
公式:
$$ m_t=\beta_1 m_{t-1}+(1-\beta_1)g_{t-1} $$
随机确定θ^0
->定义向量movement v^0=0, 计算θ^0处的梯度, 更新movement( 就是把所有过去的SGD中update的方向累加到movement里面 ) v^1=λv^0-η∇𝐿(𝜃^0)
->往动量方向移动到θ^1=θ^0+v^1
当走到驻点和局部最优时, 虽然梯度接近0, 但是有动量momentum存在, 还能继续走, 多看一些位置
Adagrad
$$ \theta_t=\theta_{t-1} - \frac{\eta}{\sqrt{\sum_{i = 0}^{t-1}\left( g_{i} \right)^{2}}}g_{t-1} $$
如果前几步梯度很大, 可能走太多, 到一个更差的位置.
加上这样一个分母(过去所有梯度和), 如果过去梯度全都很大, 说明该处很陡峭, 会走小步一点.
RMSProp
与Adagrad分母的算法不一样, 借用了Momentum思想.
Adagrad直接把过去所有梯度相加; RMSProp给过去累加梯度与当前梯度分配权重(遗忘, 只看近期值).指数移动平均法EMA(Exponential moving average)
$$ \theta_t=\theta_{t-1} - \frac{\eta}{\sqrt{v_t}}g_{t-1}\\ v_1=g_0^2\\ v_t=\alpha v_{t-1}+(1-\alpha)(g_{t-1})^2 $$
但无法解决卡在局部最优问题
Adam
公式:
$$ \theta_t=\theta_{t-1}-\frac{\eta}{\sqrt{\hat v_t}+\varepsilon}\hat m_t $$
Adam=SGDM+ RMSProp
最右侧因子由梯度g改为动量m. 动量m一开始比较小, 所以要先用β^t先放大, m太大后再缩小. 还有ε防止v_1=g_0=0导致分母为0.
Adam vs SGDM区别
Adam:训练更快, 泛化能力下降大( large generalization gap ), 不稳定
SGDM:稳定, 泛化能力下降小, 最后收敛程度可能更好
SWATS
一开始用Adam收敛时用SGDM.
要考虑什么时候转换, 如何转换.
Adam改进
这些算法都是为了动态调整学习率
AMSGrad
处理学习率比较大时的状况.
Adam在梯度普遍较小时, 遇到极大的梯度移动得不够多.
AMSGrad目标是移除过小的梯度造成的过大影响. 在过去的v_(t-1)与v_t只取最大的值.
AdaBound
但依然存在一个问题, 如果前面经过很大的梯度, 后面记忆分母就会巨大, 然后走不动了.
对学习率加一个上界, 下界bound/clip. 改进让分母很大的时候学习率也不能变得太小.
但是有点粗暴.
SGDM改进
SGDM有点慢. 因为Adaptive算法动态调整学习率, 在不重要的地方可以大步走过, 但SGDM不行.
Cyclical LR(learning rate)/ SGDR
帮SGD找到最佳学习率, 不随着时间改变但收敛比较快.
学习率周期性地变大变小, 变大做更多探索, 更小做收敛.
One-cycle LR
只做一个周期, 由三个部分组成: warm-up( 增大 ) + annealing( 退火 ) + fine-tuning( 微调收敛 )
Warm-up(Adam改进2)
Adam已经做了adaptive gradient还需要warm-up吗?
经过实验可以看出, 前10步梯度比较乱, 不知道初始化在哪个地方. 做了warm-up之后会好些.
那如何做warm-up?
1.通常是定义一个曲线, 先增加, 再慢慢减少(工程上常用的做法).
2.另一种方法:
原Adam公式:
$$ \theta_t=\theta_{t-1}-\frac{\eta}{\sqrt{\hat v_t}+\varepsilon}\hat m_t $$
其重点在分母v的改变, 如果一开始梯度很乱, 那么分母EMA梯度开方也会很乱, 所以得到的学习率不太好( 一下走太大步, 一下走太小步 ).
在还不确定合适学习率时, 先走小步一点, 不一定会更好, 但至少梯度不会变化太快差距太大, 会比较稳定.
RAdam
针对刚开始模糊的v, 定了ρ_t(EMA的有效记忆大小), 通过近似v_t的方差判断合适步长. 若方差大, 则走小步求稳, 若方差小, 则很稳定, 走大步.
但若ρ_t≤4, 没有办法使用, 那就先用SGDM:
$$ \theta_t=\theta_{t-1}-\eta\hat m_t $$
等ρ_t>4够大了再切换过来:
$$ \theta_t=\theta_{t-1}-\frac{\eta r_t}{\sqrt{\hat v_t}+\varepsilon}\hat m_t $$
RAdam vs SWATS
RAdam是先SGDM再Adam
SWATS是先Adam再SGDM
RAdam | SWATS | |
解决 | 一开始梯度方差大, 造成学习率(adaptive learning rate)不准 | Adam收敛不好, 泛化不好,SGDM训练慢 |
方式 | 乘一个r(warm-up learning rate ), 让梯度方差大时走小一点. 减少不准确的学习率造成的影响. | 结合优势, 先Adam后SGDM |
转换 | SGDM to RAdam | Adam to SGDM |
转换目的 | warm-up学习率的估计再训练一开始还不能用 | 追求更好的收敛效果 |
转换时间 | 估计的r生效 | 自定义条件, 判断快收敛了 |
Lookahead
是包在优化器外面, 所有算法都能用. ( universal wrapper for all optimizers )
思想: 每走几步检查一下走的方向是否合适. k step forward, 1 step back
在k步中取起始点Φ_(t-1), 取终点θ_(t,k), 返回这两点的α等分点.
For 𝑡 = 1, 2, …(outer loop) 𝜃_(𝑡,0) = 𝜙_(𝑡−1) For 𝑖 = 1, 2, …𝑘 (inner loop) 𝜃_(𝑡,𝑖) = 𝜃_(𝑡,𝑖−1)+O𝑝𝑡𝑖𝑚 (𝐿𝑜𝑠𝑠, 𝑑𝑎𝑡𝑎, 𝜃_( 𝑡,𝑖−1)) 𝜙_𝑡=𝜙_(𝑡−1) + 𝛼(𝜃_(𝑡,k) − 𝜙_(𝑡−1)) |
很陡峭的局部最优一般泛化效果不太好, 更希望找到平坦的minimum. 处往回走的这一步避免了危险的exploration.
NAG(Nesterov accelerated gradient )
利用之前的梯度预测之后的梯度, 看是否要走
SGDM
$$ \theta_t=\theta_{t-1}-m_t=\theta_{t-1}-\lambda m_{t-1}-\eta \nabla L(\theta_{t-1})\\ m_t=\lambda m_{t-1}+\eta \nabla L(\theta_{t-1}) $$
NAG
$$ m_t=\lambda m_{t-1}+\eta \nabla L(\theta_{t-1}-\lambda m_{t-1}) $$
( 原本要保存两份θ_(t-1)其中用了些数学方法替代, 防止浪费空间, 但是这个公式看得我实在想吐 )
$$ m_t=\lambda m_{t-1}+\eta \nabla L(\theta_{t-1}')\\ \theta_t'=\theta_{t-1}'-\lambda m_t-\eta \nabla L(\theta_{t-1}') $$
SGDM与NAG公式区别
在计算θ_t时, SGDM用的是上一步的m, NAG用的是这一步的m. 即m_t超前部署一步
Nadam(Adam改进3)
把NAG的算法用到Adam上面.
$$ \theta_t=\theta_{t-1}-\frac{\eta}{\sqrt{\hat v_t}+\varepsilon}\hat m_t $$
把第一项含t的+1
$$ \hat m_t=\frac{\beta_1 m_t}{1-\beta_1^{t+1}}+\frac{(1-\beta_1)g_{t-1}}{1-\beta_1^t} $$
AdamW&SGDM
之前用的算法一般使用L2 regularization正则化( 把其项γ放在梯度一起算 ), 但算梯度时不考虑, 算完之后再加上γ项效果更好, 即weight decay
有助于Optimization的事情
增加model随机性
Shuffling
data输入的时候, 换一下顺序.
Dropout
Gradient noise
算完梯度后加一个noise, t变大, noise变小( 接近收敛的时候不要加太多东西 )
学习率
Warm-up
一开始学习率设得比较小, 然后再慢慢调大
Curriculum learning
先用简单的数据训练( 决定了学习的大方向 ), 如没有噪声, 靠近平均值, 再加困难的数据, 提高泛化性能.
Fine-tuning
微调
避免极端值影响
Normalization
Regularization
总结
两个梯队的算法:
Team SGD | Team Adam | ||
SGD SGDM Learning rate scheduling NAG SGDWM | SWATS | Adagrad RMSProp Adam AMSGrad AdaBound Learning rate scheduling RAdam Nadam AdamW | |
lookahead |
SGDM与Adam对比:
SGDM | Adam |
慢 收敛更好 稳定 泛化好 | 快 可能不收敛 不稳定 泛化不好 |
算法选择:
SGDM | Adam |
Computer vision image classification segmentation object detection | NLP QA machine translation summary Speech synthesis语音生成 GAN Reinforcement learning |