当我们的model无法进一步update参数时候,loss不再下降,我们猜想是因为gradient接近于0。
有很多可能让gradient为零的point,不仅仅是local minima(局部最小),还有saddle point(鞍点)等。我们统称这些点为critical point(临界点)
其中saddle point还可以进一步escape。
我们利用泰勒级数展开式近似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!
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很少
当我们对 l o s s loss loss做微分时,并不是一次对所有data做微分,而是分成了很多batch,每一次更新都只用了一个batch 的资料。所有的batch都训练后一遍,叫做一个epoch。 而每一次epoch后我们还会做一次Shuffle,把每个batch的data与之前选择的不一样。
通过对比我们可以发现,没有使用batch时,我们必须看完所有的资料后才会更新一次。而batch size = 1,每次update参数只需要看一笔资料,比较noisy,容易收影响。
batch size的大小也对学习的时间有所影响,在考虑到平行运算时,其实大的batch更快一些。
参考各自的特点,选择适合的batch size。
输入的大小决定了w的影响力,进一步决定了Error Surface。所以我们尽可能让不同的dimension具有同样的数值范围,让优化变得容易,收敛变快。
我们可以对每Feature进行Normalization,之后平均为0,方差是1。
对于多层神经网络,每一层的输出对于下一层也是输入,所以也需要做一次normalization。
因为做了normalization后,每一笔输入之间互相具有了联系(因为需要一起进行平均),所以你的整体的函数变成了一个更复杂的函数(与之前相比),这时需要更强大的算力资源和GPU缓存。所以我们一般只考虑一个batch里的每一笔输入做一个归一化。这适用于batch size比较大的时候,因为大的size才足以表现出整体资料的分布情况。
有时候会加上一组参数,初始设为1和0,代表归一化的成都,让机器自己学习慢慢调整。
在Testing时,pytorch会自动帮你保存一个累计batch的均值,这样就没有积攒到一个batch才能做运算的限制了。
Momentum(动量),利用物理世界中的现象作为启发,每一步更新参数时加上一个**“ 惯性 ”**。
每一步更新的时候考虑前一步走的方向,与梯度的方向结合得到 m m m。也可以把 m m m当作过去所有gradient的总和。
有时候当 l o s s loss loss不再下降时,gradient其实并没有变得很小。这个时候有可能是在一个山谷两侧反复横跳,并没有真的卡到critical point。
因此我们需要为每一个参数特制learning rate。
我们将原本的learning rate改成一个参数相关(parameter dependent)的值。
Root Mean Square利用平均后开根号的方式。这样算出的陡峭的参数学习率大,平滑的学习率小。
RMSProp与Root Mean Square相比,等于做了一个加权,让每个gradient不再是同等地位,又多了一个参数。
注意这里的 α α α并没有下标,说明是一个超参数。
Adam:RMSProp + Momentum
今天常用的方法是Adam,实现原理就是:RMSProp + Momentum。
可以直接使用Pytorch调用。
与此同时,小的梯度不断累积导致整体的平均值变小,在过程中就会产生突然的“爆炸”,所以我们使用Learning Rate Decay与Warm Up,在过程中让学习率慢慢降低,类似刹车的作用。
Learning Rate Decay是慢慢变小,Warm Up是先变大后变小。
结合Adam和SGDM,我们可以得到以下两种方法,各有特点:
这就是最终版本的Optimization,结合了Momentum & RMSProp & 以及Learning rate scheduling
其中,
类比回归问题的方法,我们用单位向量表示分的每一个种类,得到的结果通过一个 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到右下角。