Optimization的一些优化方案

如果你发现你深的model,跟浅的model比起来,深的model明明弹性比较大,但loss却没有办法比浅的model压得更低,那就代表说你的optimization有问题,你的gradient descent不给力

Saddle Point 与 Local Minima

那么怎么把gradient descent做得更好,那为什么Optimization会失败呢?

随著你的参数不断的update,你的training的loss不会再下降,但是你对这个loss仍然不满意。如果通过与linear model 或者deep model进行对比,发现确实没有发挥出他完整的力量。

那我们可以怀疑现在走到了一个地方,这个地方参数对loss的微分為零

  • 但不是只有local minima的gradient是零,saddle point(鞍点)的gradient也为0
  • 这种gradient為零的点,统称為critical point

image-20210314153005913

卡在local minima,那可能就没有路可以走了,但卡在saddle point的话,saddle point旁边还是有路可以走的。

如何判断一个critical point,到底是local minima,还是saddle point呢?

image-20210314182013101

总结就是:你只要算出一个hessian矩阵,这个矩阵如果它所有的eigen value,都是正的,那就代表我们现在在local minima,如果它有正有负,就代表在saddle point。

经验总结:

所以从经验上看起来,其实local minima并没有那么常见,多数的时候,你觉得你train到一个地方,你gradient真的很小,然后所以你的参数不再update了,往往是因为你卡在了一个saddle point。

梯度下降法的几种改进思路

Batch

实际上在算微分的时候,并不是真的对所有 Data 算出来的 L 作微分,而是把所有的 Data 分成一个一个的 Batch。

所有的 Batch 看过一遍,叫做一个 Epoch

Shuffle 就是在每一个 Epoch 开始之前,会分一次 Batch,使每一个 Epoch 的 Batch 都不一样

在GPU并行计算的技术加持下,大批量计算的时间可能会比小批量计算更加快。小批量在一次Epoch计算的时间反而更长。但是更加随机乱走的小批量计算,反而可能会帮助学习到更好的参数。

  • 批量梯度下降法BGD:使用所有的样本进行对参数进行更新
  • 随机梯度下降法SGD:使用一个的样本进行对参数进行更新
  • 小批量梯度下降法MBGD:使用N个的样本进行对参数进行更新

Momentum

基于物理学中的动量概念,帮助对抗 Saddle Point,或 Local Minima 。

加上 Momentum 以后,每一次我们在移动我们的参数的时候,我们不是只往 Gradient Descent,我们不是只往 Gradient 的反方向来移动参数,我们是 Gradient 的反方向,加上前一步移动的方向,两者加起来的结果,去调整去到我们的参数

image-20210315193703079

Auto set the learning rate

首先,对于不同的参数,我们应该给予不同的学习率。

学习率不变,但梯度随着进行会越来越小,导致训练越来越慢。

如果在某一个方向上,我们的gradient的值很小,非常的平坦,那我们会希望learning rate调大一点,如果在某一个方向上非常的陡峭,坡度很大,那我们其实期待,learning rate可以设得小一点。

Adagrad

image-20210319160639783

σᵢᵗ就是过去,所有算出来的gradient,它的平方和的平均再开根号

然后在把它除learning rate,然后用这一项当作是,新的learning rate来update你的参数

如此我们就可以控制梯度下降的速度,保持均匀。使坡度比较大的时候,learning rate就减小,坡度比较小的时候,learning rate就放大。

RMSProp

动态调整learning rate去满足不同的情况。

不同于Adagrad中 σᵢᵗ 中每一个gradient都有同等的重要性,在RMS Prop裡面,它决定你可以自己调整,现在的这个gradient,你觉得它有多重要

这个α就像learning rate一样,这个你要自己调它,它是一个超参数

  • 如果我今天α设很小趋近於0,就代表我觉得gᵢ¹相较於之前所算出来的gradient而言,比较重要
  • α设很大趋近於1,那就代表我觉得现在算出来的gᵢ¹比较不重要,之前算出来的gradient比较重要

Adam

目前最常用的optimization的策略就是Adam。

image-20210319220458633

Adam就是RMS Prop加上Momentum。

Learning Rate Scheduling

image-20210319223155277

learning rate scheduling的意思就是说,我们不要把η当一个常数,我们把它跟时间有关

Learning Rate Decay

随著时间的不断地进行,随著参数不断的update,我们这个η让它越来越小

image-20210319221921888

warm Up

让learning rate,要先变大后变小

image-20210319222229363

经过很多算法的实践,在某些程度上,warm up确实对学习有帮助。

Batch Normalization

假设你的两个参数啊,它们对 Loss 的斜率差别非常大,如果是固定的 learning rate,你可能很难得到好的结果。可能需要上述的一些auto set learning rate的方法才能得到好的结果。

Normalization 归一化

对于不同的维度,让它处于同样的数值范围

image-20210426201611113

Feature Normalization

对特征进行缩放

image-20210426204629991

简述就是把某一个数值x,减掉这个维度的均值,再除掉这个维度的标准差,得到新的数值 $\tilde{x}$。

处理过后,这一排数值的分布就都会在 0 上下。它的 Loss 收敛更快一点,可以让你的 gradient descent,它的训练更顺利一点

Batch Normalization

有了对特征的标准化后,我们考虑在神经网络中,如何对每一层的输出(或者说下一层的输入)做标准化呢?

如何对某一层的输出Z做 Feature Normalization 呢?

image-20210426212301934

步骤同上,就是通过$z^1$ $z^2$ $z^3$,算出 均值$μ$和方差 $\sigma$。再对每一个Z进行标准化操作。

image-20210427084717687

但本来$z^1$ $z^2$ $z^3$是独立分开处理的,但是我们在做 Feature Normalization 以后,这三个 example,它们变得彼此关联了。只要有一个特征改变,其余特征都会跟着改变。

也就是说,你现在有一个比较大的 network

  • 你之前的 network,都只吃一个 input,得到一个 output
  • 现在你有一个比较大的 network,这个大的 network,它是吃一堆 input,用这堆 input 在这个 network 裡面,要算出 $μ$ 跟 $\sigma$,然后接下来产生一堆 output

但是有一个问题,你一定要有一个够大的 batch,你才算得出 $μ$ 跟 $\sigma$。只有你的Batch足够大的时候,这个 batch size 里面的data,就足以表示,整个数据的分布

为了保持原有的数据特征,会对计算后的Z再做线性拟合。那为了防止这个限制会带来什么负面的影响,所以我们把 $β$ 跟 $γ$ 加回去。

image-20210427090245986

Testing时,我们将每个batch训练出来的结果,求平均带入模型中替换 $μ$ 和 $\sigma$。

image-20210427101956211

others

那其实 Batch Normalization,不是唯一的 normalization,normalization 的方法有一把啦,那这边就是列了几个比较知名的,

Batch Renormalization
https://arxiv.org/abs/1702.03275
Layer Normalization
https://arxiv.org/abs/1607.06450
Instance Normalization
https://arxiv.org/abs/1607.08022
Group Normalization
https://arxiv.org/abs/1803.08494
Weight Normalization
https://arxiv.org/abs/1602.07868
Spectrum Normalization
https://arxiv.org/abs/1705.10941

附录:

缩放过程可以分为以下几种:

  1. 缩放到均值为0,方差为1(Standardization——StandardScaler())
  2. 缩放到0和1之间(Standardization——MinMaxScaler())
  3. 缩放到-1和1之间(Standardization——MaxAbsScaler())
  4. 缩放到0和1之间,保留原始数据的分布(Normalization——Normalizer())

参考:

https://github.com/unclestrong/DeepLearning_LHY21_Notes

https://www.bilibili.com/video/BV1Wv411h7kN

https://www.zhihu.com/question/20467170