机器学习笔记(二)
神经网络训练中的问题
1.Local Minima & Global minima & Saddle point
描述神经网络中训练的问题之前,先理解三个点的概念
这三个点有一个共同的名字 critical point。我们通过下图可以看出,三个点处的导数都等于0。我们又知道神经网络更新参数的公式为 w 1 ← w 0 − η ∂ L ∂ w ∣ ( w = w 0 ) w_1←w_0-η \frac{∂L}{∂w}|(w=w_0 ) w1←w0−η∂w∂L∣(w=w0)
也就是说当导数等于0时, w n = w n + 1 w_n=w_n+1 wn=wn+1,参数不再更新。但此时真的Loss最小嘛,并不是。
- Local Minima 可以理解成区间内最小值(极小值),Loss在此处的左右都再增加但并不是整个Loss的最小值。
- Global Minima可以理解成最小值,Loss在此处最小,该模型在此处最优。图中的Loss小于0是因为计算Loss的方法有很多,并不一定非要用MAE或者MSE。但事实中模型往往学习不到Global Minima就停止了,几乎不会出现这种情况。
- Saddle point 中文名字是鞍点,这个点在某一个方向后的导数为正,在某一个方向的导数为负,所以也不是区间内的最小值点。但模型会因为此处导数为0而不再移动。
2.General Guidance
神经网络的终极目标是找到在输入和输出之间的函式,而评价函式好坏的标准是Loss。Loss越小代表函式的拟合效果越好。那么当Loss大的时候应该怎么办呢?或者说Model如何一步一步变好呢?先看图:
首先是第一种情况:在training data上的Loss值很大。有两种原因可能导致该结果:
- Model bias:这种情况就是你拟定的Function不适用这么Model,无论怎么改变parameter都不会使得Function特别拟合。这时可以增加更多的features,或者增加更多的层(deep learning),使Model的弹性增大。
- Optimization Issue:这种情况可能是Optimization遇到了local minima或者Saddle point,即模型存在这一个特别低的Loss,但由于Gradient descent的缺陷我们没有办法找到Global minima
如何判断是哪种情况引起的Loss值很大呢?
- 一种建议的办法是一个建议判断的方法,就是你可以透过比较不同的模型,来得知你的model现在到底够不够大,举个例子)http://arxiv.org/abs/1512.03385.
在这篇论文的结果中可以看到,在训练集上随着训练过程的增多,20层的神经网络和56层的神经网络的Loss均成下降趋势,但可以看出56层的神经网络的Loss要高于20层的神经网络。这是Model bias嘛?不是Model bias,该神经网络20层的时候就具备了优秀的能力,随着层数增多效果反而不好。这是过拟合嘛?不是过拟合,过拟合是指在训练集上优秀的模型到测试集上效果降低的现象,但这篇文章中无论是测试集还是训练集56层的网络效果都更差。图中的现象表明56层的network的optimization没有做好。
从这个例子可以看出当在训练集上Loss不理想时,也许你可以先跑一些比较小的,比较浅的network,或甚至用一些不是deep learning的方法,比如说 linear model,support vector machine,它们比较不会有optimization失败的问题,也就是这些model它会竭尽全力的,在它们的能力范围之内,找出一组最好的参数。接下来可以将model加深,如果随着model深度的增加Loss没有办法变得更低,很可能是你的optimization选择出了问题。
然后是第二种情况:在训练集上效果很好,在测试集上效果很差同样有两种原因可以造成这种现象:
- overfitting:函式过于拟合训练集的模型,当遇到新模型的时候由于缺少了某些特征而导致预测失败。
- mismatch:训练集和测试集分布根本就不一样。
如何解决overfitting的问题?
- 增加数据集,或者在原有的数据集上进行拓展。后者往往是非常有用的一种办法,因为数据集的获取不容易,但当我们对现有的数据集做一些改动比如:缩放,左右翻转等往往会获取很多新的特征。但注意要进行合理的变动,如果图片的话进行上下翻转就不可取,因为那种情况在真实的数据中很难出现,容易增加奇怪的信息。
- 让你的模型不要有那么大的弹性,给他一些限制。比如:
- 给它比较少的参数,如果是deep learning的话,就给它比较少的神经元的数目,本来每层一千个神经元,改成一百个神经元之类的,或者是你可以让model共用参数,你可以让一些参数有一样的数值。CNN就采用了这种办法,相比fully-connected network,CNN就缺少了弹性,也正是因为这个在影像上CNN会做的比较好
- 另外一个就是用比较少的features,例如在实际的应用中,下一个模型 y y y的输出从与之前的7个 x x x有关到与6个 x x x有关。
- Dropout,这是另外一个在Deep Learning裡面,常用来限制模型的方法。深度学习网络的训练过程中,对于神经网络单元,按照一定的概率将其暂时从网络中丢弃。这个后面会单独讲。
注意也不要给太多限制,否则会产生model bias。那这就是一个度的问题,究竟怎样选择Model合理呢?常规的办法是这样的,要把Training的资料分成两半,一部分叫作Training Set,一部分是Validation Set。在Training Set上训练出来的模型,你在Validation Set上面去衡量它们的Loss分数,你根据Validation Set上面的分数,去挑选结果,再把这个模型传到Testing Model上。
这个一般都是随机分的,但仍然存在一种情况,这种随机分的方法恰好将一切规律的Data分到了一起,经过Validation Set后还是会出现过拟合。或者Training Data 数量不足以留出validation set否则会导致training set的数量太少为了解决这种碰巧的情况我们引入N-fold Cross Validation。
N-fold Cross Validation就是先把你的训练集切成N等份,在上图例子里我们切成三等份。切完以后,你拿其中一份当作Validation Set,另外两份当Training Set,然后这件事情你要重复三次。
也就是说,你先第一份第二份当Train,第三份当Validation;然后第一份第三份当Train,第二份当Validation;之后第一份当Validation,第二份第三份当Train。
然后接下来你会有三个模型,你不知道哪一个是好的,你就把这三个model在这三个setting(环境)下,在这三个Training跟Validation的data set上面通通跑一次。然后把这三个模型,在这三种状况的结果都平均起来,即把每一个模型在这三种状况的结果都平均起来,再看看谁的结果最好
如果你用这三个fold(层)得出来的结果是这个model 1最好,然后你再把model 1用在全部的Training Set上,然后训练出来的模型再用在Testing Set上面。如何解决mismatch的问题?
在训练集跟测试集,分布是不一样的时候,你训练集再增加,其实也没有帮助了。解决办法后面单独出一章讲。
当模型停止更新的时候如何让模型继续运行?
如何当模型停止更新的时候即导数为0的时候首先要区分遇到了Locall minima 还是 Saddle point? (几乎不会是Global minima或者说Global minima是一种特殊的Locall minima)
虽然神经网络模型特别复杂,我们写不出整体的模型到底长什么样,但某一组特定参数附近的模型我们是可以通过泰勒公式写出来的:
L ( θ ) ≈ L ( θ ′ ) + ( θ − θ ′ ) T g ⃗ + 1 2 ( θ − θ ′ ) T H ⃗ ( θ − θ ′ ) L(θ)\approx L(θ')+(θ-θ')^T\vec g +\frac{1}{2}(θ-θ')^T\vec H(θ-θ') L(θ)≈L(θ′)+(θ−θ′)Tg+21(θ−θ′)TH(θ−θ′)
其中 g ⃗ = ∇ L ( θ ′ ) \vec g=∇L(θ') g=∇L(θ′), H ⃗ i j = ∂ 2 ∂ θ i ∂ θ j L ( θ ′ ) \vec H_{ij}=\frac{\partial^2}{\partial\theta_i\partial\theta_j}L(θ') Hij=∂θi∂θj∂2L(θ′), θ ′ θ' θ′是 θ θ θ附近的点。当走到critical point时,第二项为零,我们通过第三项来判断到底是什么点,为了方便起见,我们把 ( θ − θ ′ ) (θ-θ') (θ−θ′)用 v ⃗ \vec v v这个向量表示。也就是说
- 对任何可能的 v ⃗ \vec v v,如果 v ⃗ T H ⃗ v ⃗ \vec v^T\vec H\vec v vTHv都大於零,那么 L ( θ ) L(θ) L(θ)永远大於 L ( θ ′ ) L(θ') L(θ′),代表 L ( θ ′ ) L(θ') L(θ′)是附近的一个最低点,所以它是local minima
- 对任何可能的 v ⃗ \vec v v,如果 v ⃗ T H ⃗ v ⃗ \vec v^T\vec H\vec v vTHv都小於零,那么 L ( θ ) L(θ) L(θ)永远小於 L ( θ ′ ) L(θ') L(θ′),代表 L ( θ ′ ) L(θ') L(θ′)是附近的一个最高点,所以它是local maxima
- 对任何可能的 v ⃗ \vec v v,如果 v ⃗ T H ⃗ v ⃗ \vec v^T\vec H\vec v vTHv有时候大於零,有时候小於零,那么 L ( θ ) L(θ) L(θ)有时候大於 L ( θ ′ ) L(θ') L(θ′),那么 L ( θ ) L(θ) L(θ)有时候小於 L ( θ ′ ) L(θ') L(θ′),代表 L ( θ ′ ) L(θ') L(θ′)附近有的地方高有的地方低,所以它是Saddle point
当 v ⃗ T H ⃗ v ⃗ \vec v^T\vec H\vec v vTHv都大於零时, H ⃗ \vec H H就是一个正定矩阵,正定矩阵的所有特征值都是正的,也就是说,我们对于遇到critical point只需要计算该点的 H ⃗ \vec H H的特征值,如果特征值都为正该点是local minima,如果都为负是local maxima,如果有正有负是Saddle point。
那当遇到Saddle point如何判断继续更新参数的方向呢?
我们现在假设假设 μ ⃗ \vec \mu μ是 H ⃗ \vec H H的特征向量,然后 λ λ λ是 μ ⃗ \vec \mu μ的特征值。把 v ⃗ \vec v v换成 μ ⃗ \vec \mu μ,把 μ ⃗ \vec \mu μ乘在 H ⃗ \vec H H的左边,跟 H ⃗ \vec H H的右边,也就是 μ ⃗ T H ⃗ μ ⃗ \vec \mu^T\vec H\vec \mu μTHμ, H ⃗ μ ⃗ \vec H\vec \mu Hμ会得到 v ⃗ T H ⃗ v ⃗ = μ ⃗ T ( λ μ ⃗ ) = λ ∣ ∣ μ ∣ ∣ 2 \vec v^T\vec H\vec v=\vec \mu^T(λ \vec \mu)=λ||\mu||^2 vTHv=μT(λμ)=λ∣∣μ∣∣2所以 L ( θ ) ≈ L ( θ ′ ) + μ ⃗ T ( λ μ ⃗ ) = L ( θ ′ ) + λ ∣ ∣ μ ∣ ∣ 2 L(θ)\approx L(θ')+\vec \mu^T(λ \vec \mu)=L(θ')+λ||\mu||^2 L(θ)≈L(θ′)+μT(λμ)=L(θ′)+λ∣∣μ∣∣2
此时, L ( θ ) 和 L ( θ ′ ) L(θ)和 L(θ') L(θ)和L(θ′)的大小完全取决于 λ λ λ的正负,而 θ − θ ′ = μ , θ = θ ′ + μ θ-θ'=\mu,θ=θ'+\mu θ−θ′=μ,θ=θ′+μ,也就是说当 λ λ λ为负的时候,在 θ ′ θ' θ′的位置加上 u ⃗ \vec u u,沿着 u ⃗ \vec u u的方向做update得到 θ θ θ,你就可以让loss变小。
举个具体的例子:假设我现在有Function y = w 1 w 2 x y=w_1w_2x y=w1w2x,而且我们现在只有一组data(1,1),Loss的Error Surface如图所示:
四个角落loss是高的,有一些critical point,原点的地方是critical point,右上三个黑点也是一排critical point,左下三个点也是critical point,从图中可以看出原点往左上,右下这两个方向更新Loss会变大,而往左下,右上这两个方向更新Loss会变小,当我们走到原点时如何确定继续更新的方向呢?
由Fuction和Data可知, L = ( y ^ − w 1 w 2 x ) 2 = ( 1 − w 1 w 2 x ) 2 L=(\hat y-w_1w_2x)^2=(1-w_1w_2x)^2 L=(y^−w1w2x)2=(1−w1w2x)2 ∂ L ∂ w 1 = 2 ( 1 − w 1 w 2 ) ( − w 2 ) = 0 \frac{∂L}{∂w_1 }=2(1-w_1 w_2 )(-w_2 )=0 ∂w1∂L=2(1−w1w2)(−w2)=0 ∂ L ∂ w 2 = 2 ( 1 − w 1 w 2 ) ( − w 1 ) = 0 \frac{∂L}{∂w_2 }=2(1-w_1 w_2 )(-w_1 )=0 ∂w2∂L=2(1−w1w2)(−w1)=0 ∂ 2 L ∂ w 1 2 = 2 ( − w 2 ) ( − w 2 ) = 0 \frac{∂^2L}{∂w_1^2 }=2(- w_2 )(-w_2)=0 ∂w12∂2L=2(−w2)(−w2)=0 ∂ L 2 ∂ w 1 w 2 = − 2 + 4 w 1 w 2 = − 2 \frac{∂L^2}{∂w_1w_2 }=-2+4w_1w_2=-2 ∂w1w2∂L2=−2+4w1w2=−2 ∂ 2 L ∂ w 2 2 = 2 ( − w 1 ) ( − w 1 ) = 0 \frac{∂^2L}{∂w_2^2 }=2(- w_1 )(-w_1)=0 ∂w22∂2L=2(−w1)(−w1)=0 ∂ L 2 ∂ w 2 w 1 = − 2 + 4 w 1 w 2 = − 2 \frac{∂L^2}{∂w_2w_1 }=-2+4w_1w_2=-2 ∂w2w1∂L2=−2+4w1w2=−2 H = [ 0 − 2 − 2 0 ] H=\begin{bmatrix}0&-2\\-2&0\\\end{bmatrix} H=[0−2−20] λ 1 = 2 , λ 2 = − 2 λ_1=2,λ_2=-2 λ1=2,λ2=−2
可以判断出 λ λ λ有正有负,所以该点为saddle point,当 λ = − 2 λ=-2 λ=−2时, λ = λ= λ=的一个特征矩阵为 [ 1 1 ] \begin{bmatrix}{1} \\\\ {1}\end{bmatrix} ⎣⎡11⎦⎤,所以沿着 [ 1 1 ] \begin{bmatrix}{1} \\\\ {1}\end{bmatrix} ⎣⎡11⎦⎤继续更新Loss的值会变得更小。
还有一种避免遇到saddle point或者local minima就停下的办法,就是在原有的Gradient Descent的基础上进行改进。原本的Gradient Descent的形式是这样的: θ 1 = θ 0 − η g 0 θ^1 = θ^0 - {\eta}g^0 θ1=θ0−ηg0 我们在此基础上将Gradient 的反方向,加上前一步移动的方向,两者加起来的结果,去调整去到我们的参数,如图所示:
可以看到我们现在每步的移动方向为
m 0 = 0 m 1 = − η g 0 m 2 = − λ η g 0 − η g 1 . . . m^0 = 0\\ m^1 = -{\eta}g^0\\ m^2 = -{\lambda}{\eta}g^0-{\eta}g^1\\ ... m0=0m1=−ηg0m2=−ληg0−ηg1...
这样我们即使走到了Local minima或者Saddle point,还会因为惯性的原因继续更新参数,甚至可以引起Loss的段幅度上升,如果这个Loss后面是一个坡度没有那么大的段落,很可能跳过这个Loss继续寻找。这个办法叫做Momentum,这种Optimization的办法叫Gradient Descent + Momentum。
到底saddle point跟local minima谁比较常见
打个比方:从三维的空间来看,两个地方之间没有路可以走,但是在高维的空间中是有路可以走的,error surface也一样。一维的包含一个参数的error surface中,会觉得好像到处都是local minima。但是在二维空间来看它就只是一个saddle point。同样在二维的空间中我们没有路可以走,那在更高的维度上,其实有路可以走的。
今天在训练一个network的时候,我们的参数往往动輒百万千万以上,所以我们的error surface其实是在一个非常高的维度中。我们参数有多少就代表我们的error surface的维度有多少,参数是一千万就代表error surface它的维度是一千万。而且从经验上看起来其实local minima并没有那么常见。多数的时候你觉得你train到一个地方,你gradient真的很小,然后所以你的参数不再update了,往是因为你卡在了一个saddle point。