文章目录
1. The reason why Optimization fails
当我们的model无法进一步update参数时候,loss不再下降,我们猜想是因为gradient接近于0。
有很多可能让gradient为零的point,不仅仅是local minima(局部最小),还有saddle point(鞍点)等。我们统称这些点为critical point(临界点)
其中saddle point还可以进一步escape。
1.1 local minima or saddle point ?
我们利用泰勒级数展开式近似loss函数。
g
g
g是一个gradient向量,相乘得到绿框表示到真实值直接的距离。
H
H
H(Hessian)是一个
m
a
t
r
i
x
matrix
matrix,红框的乘积会补足最后红虚线的差距。
当处于critical point时,loss中绿色的一项为0,可以通过红色的一项进行判断。
如果红色框框都大于零,这时是local minima
如果红色框框都小于零,这时是local maxima
如果红色框框有时候小于零有时候大于零(代入不同的值),这时是saddle point
我们可以通过判断矩阵所有的eigen values正负来进行判断。
例如对于
y
=
w
1
w
2
x
y = w_1w_2x
y=w1w2x 这个function的误差曲面如图,最中间的点就是一个saddle point,往右上角会变大,右下角会变小。
我们用公式来进行相同计算,得到了绿框框和红框框的值,我们可以发现对于原点它的绿框框是零,说明是一个critical point。
我们再看它的红框框矩阵,把
w
1
w_1
w1 和
w
2
w_2
w2 = 0代入就能得到这个矩阵的值,计算发现eigen value有正有负,所以它是一个saddle point!
1.2 update forward
H
H
H还可以帮助我们找到update的方向,我们如果把一个
H
H
H的eigen vector(特征向量代入,我们会发现红色框框的值等于特征值乘
u
2
u^2
u2。
所以我们可以根据特征值的正负来判断
l
o
s
s
loss
loss变小的方向(沿着
u
u
u的方向)
u
u
u是特征向量
但是这个方法所需要的计算量较大,所以实际情况下几乎不会使用这种方法来escape the saddle point。
根据实验我们可以发现,其实多数情况下eigenvalue都是有正有负的,所以其实真正的local minima很少
2. Tips for training
2.1 Batch
2.1.1 what is batch?
当我们对
l
o
s
s
loss
loss做微分时,并不是一次对所有data做微分,而是分成了很多batch,每一次更新都只用了一个batch 的资料。所有的batch都训练后一遍,叫做一个epoch。 而每一次epoch后我们还会做一次Shuffle,把每个batch的data与之前选择的不一样。
2.1.2 why shall we use batch?
通过对比我们可以发现,没有使用batch时,我们必须看完所有的资料后才会更新一次。而batch size = 1,每次update参数只需要看一笔资料,比较noisy,容易收影响。
batch size的大小也对学习的时间有所影响,在考虑到平行运算时,其实大的batch更快一些。
参考各自的特点,选择适合的batch size。
2.1.3 Batch Normalization
输入的大小决定了w的影响力,进一步决定了Error Surface。所以我们尽可能让不同的dimension具有同样的数值范围,让优化变得容易,收敛变快。
我们可以对每Feature进行Normalization,之后平均为0,方差是1。
对于多层神经网络,每一层的输出对于下一层也是输入,所以也需要做一次normalization。
因为做了normalization后,每一笔输入之间互相具有了联系(因为需要一起进行平均),所以你的整体的函数变成了一个更复杂的函数(与之前相比),这时需要更强大的算力资源和GPU缓存。所以我们一般只考虑一个batch里的每一笔输入做一个归一化。这适用于batch size比较大的时候,因为大的size才足以表现出整体资料的分布情况。
有时候会加上一组参数,初始设为1和0,代表归一化的成都,让机器自己学习慢慢调整。
在Testing时,pytorch会自动帮你保存一个累计batch的均值,这样就没有积攒到一个batch才能做运算的限制了。
2.2 Momentum
Momentum(动量),利用物理世界中的现象作为启发,每一步更新参数时加上一个**“ 惯性 ”**。
每一步更新的时候考虑前一步走的方向,与梯度的方向结合得到
m
m
m。也可以把
m
m
m当作过去所有gradient的总和。
2.3 Adaptive
有时候当
l
o
s
s
loss
loss不再下降时,gradient其实并没有变得很小。这个时候有可能是在一个山谷两侧反复横跳,并没有真的卡到critical point。
因此我们需要为每一个参数特制learning rate。
我们将原本的learning rate改成一个参数相关(parameter dependent)的值。
2.3.1 Root Mean Square
Root Mean Square利用平均后开根号的方式。这样算出的陡峭的参数学习率大,平滑的学习率小。
2.3.2 RMSProp
RMSProp与Root Mean Square相比,等于做了一个加权,让每个gradient不再是同等地位,又多了一个参数。
注意这里的
α
α
α并没有下标,说明是一个超参数。
Adam:RMSProp + Momentum
今天常用的方法是Adam,实现原理就是:RMSProp + Momentum。
可以直接使用Pytorch调用。
2.3.3 Learning Rate Scheduling
与此同时,小的梯度不断累积导致整体的平均值变小,在过程中就会产生突然的“爆炸”,所以我们使用Learning Rate Decay与Warm Up,在过程中让学习率慢慢降低,类似刹车的作用。
Learning Rate Decay是慢慢变小,Warm Up是先变大后变小。
结合Adam和SGDM,我们可以得到以下两种方法,各有特点:
2.3 Summary of Optimization
这就是最终版本的Optimization,结合了Momentum & RMSProp & 以及Learning rate scheduling
其中,
- Momentum:考虑之前所有的gradient的大小方向,做一个累加,增加一种历史的“惯性”
- RMSProp:取gradient平方,只考虑数值,缓和步伐的大小
- Learning rate scheduling:以超参数的方式人为控制整体的学习趋势
3. Classification(choose loss fuction)
类比回归问题的方法,我们用单位向量表示分的每一个种类,得到的结果通过一个
s
o
f
t
m
a
x
softmax
softmax过程与标签进行对比匹配。
做完Soft-max后,每个
y
y
y的值都在0到1之间,而且会让大的值和小的值之间的差距更大
对于
S
o
f
t
−
m
a
x
Soft-max
Soft−max与
S
i
g
m
o
i
d
Sigmoid
Sigmoid在输出类别为2的情况下,有如下关系:
我们对于Classification的loss function,常用交叉熵(Cross-entropy)的方式,因此pytorch会在你用Cross-entropy函数的时候自动在网络的最后一层增加Soft-max。
对比MSE与Cross-entropy的Error图很直观的能发现在loss大的地方,MSE的gradient是接近0的,所以这时候如果初始化在左上角的位置,很难training到右下角。