Optimization的一些优化方案
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。
卡在local minima,那可能就没有路可以走了,但卡在saddle point的话,saddle point旁边还是有路可以走的。
如何判断一个critical point,到底是local minima,还是saddle point呢?
总结就是:你只要算出一个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 的反方向,加上前一步移动的方向,两者加起来的结果,去调整去到我们的参数
Auto set the learning rate
首先,对于不同的参数,我们应该给予不同的学习率。
学习率不变,但梯度随着进行会越来越小,导致训练越来越慢。
如果在某一个方向上,我们的gradient的值很小,非常的平坦,那我们会希望learning rate调大一点,如果在某一个方向上非常的陡峭,坡度很大,那我们其实期待,learning rate可以设得小一点。
Adagrad
σᵢᵗ就是过去,所有算出来的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。
Adam就是RMS Prop加上Momentum。
Learning Rate Scheduling
learning rate scheduling的意思就是说,我们不要把η当一个常数,我们把它跟时间有关。
Learning Rate Decay
随著时间的不断地进行,随著参数不断的update,我们这个η让它越来越小。
warm Up
让learning rate,要先变大后变小。
经过很多算法的实践,在某些程度上,warm up确实对学习有帮助。
Batch Normalization
假设你的两个参数啊,它们对 Loss 的斜率差别非常大,如果是固定的 learning rate,你可能很难得到好的结果。可能需要上述的一些auto set learning rate的方法才能得到好的结果。
Normalization 归一化
对于不同的维度,让它处于同样的数值范围
Feature Normalization
对特征进行缩放
简述就是把某一个数值x,减掉这个维度的均值,再除掉这个维度的标准差,得到新的数值 $\tilde{x}$。
处理过后,这一排数值的分布就都会在 0 上下。它的 Loss 收敛更快一点,可以让你的 gradient descent,它的训练更顺利一点。
Batch Normalization
有了对特征的标准化后,我们考虑在神经网络中,如何对每一层的输出(或者说下一层的输入)做标准化呢?
如何对某一层的输出Z做 Feature Normalization 呢?
步骤同上,就是通过$z^1$ $z^2$ $z^3$,算出 均值$μ$和方差 $\sigma$。再对每一个Z进行标准化操作。
但本来$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再做线性拟合。那为了防止这个限制会带来什么负面的影响,所以我们把 $β$ 跟 $γ$ 加回去。
Testing时,我们将每个batch训练出来的结果,求平均带入模型中替换 $μ$ 和 $\sigma$。
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
附录:
缩放过程可以分为以下几种:
- 缩放到均值为0,方差为1(Standardization——StandardScaler())
- 缩放到0和1之间(Standardization——MinMaxScaler())
- 缩放到-1和1之间(Standardization——MaxAbsScaler())
- 缩放到0和1之间,保留原始数据的分布(Normalization——Normalizer())
参考:
https://github.com/unclestrong/DeepLearning_LHY21_Notes