日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

神经网络训练不起来,怎么办?

發布時間:2024/3/13 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 神经网络训练不起来,怎么办? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Datawhale開源學習,機器學習課程,項目地址:https://github.com/datawhalechina/leeml-notes

Optimization

Critical Point是Saddle Point還是Local Point?

現在我們要講的是Optimization的部分,所以我們要講的東西基本上跟Overfitting沒有什么太大的關聯,我們只討論在做Optimization時,如何把gradient descent做得更好,那為什么Optimization會失敗呢?

你常常在做Optimization時,會發現隨著你的參數不斷的update,你的training的loss不會再下降,但是你對這個loss仍然不滿意,就像我剛才說的,你可以把deep的network,跟linear的model,或比較shallow network比較,發現deep network并沒有做得更好,所以會覺得deep network沒有發揮它完整的力量,所以Optimization顯然是有問題的。但有時候你會甚至發現,一開始你的model就train不起來,一開始你不管怎么update你的參數,你的loss通通都掉不下去,那這時到底發生了什么事情呢?

過去常見的一個猜想,是因為我們現在走到了一個地方,這個地方參數對 L L Loss的微分為零,當你的參數對 L L Loss微分為零的時候,,gradient descent就沒有辦法再update參數了,這個時候training就停下來了,loss當然就不會再下降了。講到gradient為零的時候,大家通常腦海中最先浮現的,可能就是local minima,所以常有人說做deep learning,用gradient descent會卡在local minima,然后所以gradient descent不work,所以deep learning不work。但是如果有一天你要寫,跟deep learning相關paper的時候,你千萬不要講卡在local minima這種事情,別人會覺得你非常沒有水準,為什么

因為不是只有local minima的gradient是零,還有其他可能會讓gradient是零,比如說 saddle point,所謂的saddle point,其實就是gradient是零,但是不是local minima,也不是local maxima的地方,像在右邊這個例子里面紅色的這個點,它在左右這個方向是比較高的,前后這個方向是比較低的,它就像是一個馬鞍的形狀,所以叫做saddle point,那中文就翻成鞍點。

像saddle point這種地方,它也是gradient為零,但它不是local minima。那像這種gradient為零的點,統稱為critical point,所以你可以說你的loss沒有辦法再下降,也許是因為卡在了critical point,但你不能說一定是卡在local minima,因為saddle point也是微分為零的點。但是今天如果你發現你的gradient,真的很靠近零,卡在了某個critical point,我們有沒有辦法知道,到底是local minima,還是saddle point?其實是有辦法的。為什么我們想要知道到底是卡在local minima,還是卡在saddle point呢?

  • 因為如果是卡在local minima,那可能就沒有路可以走了,因為四周都比較高,你現在所在的位置已經是最低的點,loss最低的點了,往四周走loss都會比較高,你會不知道怎么走到其他的地方去。
  • 但saddle point就比較沒有這個問題,如果你今天是**卡在saddle point的話,saddle point旁邊還是有路可以走的,**還是有路可以讓你的loss更低的,你只要逃離saddle point,你就有可能讓你的loss更低。

所以鑒別今天我們走到critical point的時候,到底是local minima,還是saddle point,是一個值得去探討的問題,那怎么知道今天一個critical point,到底是屬于local minima,還是saddle point呢?這邊需要用到一點數學,以下這段其實沒有很難的數學,就只是微積分跟線性代數,但如果你沒有聽懂的話,以下這段skip掉是沒有關系的。那怎么知道說一個點,到底是local minima,還是saddle point呢?你要知道我們loss function的形狀,可是我們怎么知道,loss function的形狀呢,network本身很復雜,用復雜network算出來的loss function,顯然也很復雜,我們怎么知道loss function,長什么樣子,雖然我們沒有辦法完整知道,整個loss function的樣子,但是如果給定某一組參數,比如說藍色的這個 θ ′ θ' θ,在 θ ′ θ' θ附近的loss function,是有辦法被寫出來的,它寫出來就像是這個樣子:

所以這個 L ( θ ) L(θ) L(θ)完整的樣子寫不出來,但是它在 θ ′ θ' θ附近,你可以用這個式子來表示它,這個式子是Tayler Series Appoximation泰勒級數展開,這個假設你在微積分的時候已經學過了,所以我就不會細講這一串是怎么來的,但我們就只講一下它的概念,這一串里面包含什么東西呢?

  • 第一項是 L ( θ ′ ) L(θ') L(θ),就告訴我們當 θ θ θ θ ′ θ' θ很近的時候, L ( θ ) L(θ) L(θ)應該跟 L ( θ ′ ) L(θ') L(θ)還蠻靠近的
  • 第二項是 ( θ ? θ ′ ) T g (θ-θ')^Tg (θ?θ)Tg

g g g是一個向量,這個g就是我們的gradient,我們用綠色的這個g來代表gradient,這個gradient會來彌補, θ ′ θ' θ θ θ θ之間的差距,我們雖然剛才說 θ ′ θ' θ θ θ θ,它們應該很接近,但是中間還是有一些差距的,那這個差距,第一項我們用這個gradient,來表示他們之間的差距,有時候gradient會寫成 ? L ( θ ′ ) ?L(θ') ?L(θ),這個地方的 g g g是一個向量,它的第i個component,就是θ的第i個component對 L L L的微分,光是看 g g g還是沒有,辦法完整的描述 L ( θ ) L(θ) L(θ),你還要看第三項。

  • 第三項跟Hessian有關,這邊有一個 H H H

這個 H H H叫做Hessian,它是一個矩陣,這個第三項是 ( θ ? θ ′ ) T H ( θ ? θ ′ ) (θ-θ')^TH(θ-θ') (θ?θ)TH(θ?θ),第三項會再作為一部分補足,再加上gradient以后,與真正的 L ( θ ) L(θ) L(θ)之間的差距。H里面放的是 L L L的二次微分,它第i個row,第j個column的值,就是把 θ \theta θ的第i個component,對 L L L作微分,再把 θ θ θ的第j個component,對 L L L作微分,再把 θ θ θ的第i個component,對 L L L作微分,做兩次微分以后的結果 就是這個 H i j H_i{_j} Hi?j?。如果這邊你覺得有點聽不太懂的話也沒有關系,反正你就記得這個 L ( θ ) L(θ) L(θ),這個loss function,這個error surface在 θ ′ θ' θ附近,可以寫成這個樣子,這個式子跟兩個東西有關系,跟gradient有關系,跟hessian有關系,gradient就是一次微分,hessian就是里面有二次微分的部分。那如果我們今天走到了一個critical point,意味著gradient為零,也就是綠色的這一項完全都不見了

g g g是一個zero vector,綠色的這一項完全都不見了,只剩下紅色的這一項,所以當在critical point的時候,這個loss function可以被近似為 L ( θ ′ ) L(θ') L(θ)加上紅色的這一項。我們可以根據紅色的這一項來判斷,在 θ ′ θ' θ附近的error surface到底長什么樣子,知道error surface長什么樣子,我就可以判斷 θ ′ θ' θ處的loss function是一個local minima,是一個local maxima,還是一個saddle point我們可以靠這一項來了解,這個error surface的地貌,大概長什么樣子,知道它地貌長什么樣子,我們就可以知道現在是在什么樣的狀態。

那我們就來看一下怎么根據Hessian或者怎么根據紅色的這一項,來判斷 θ ′ θ' θ附近的地貌:

為了符號方便起見,我們把 ( θ ? θ ′ ) (θ-θ') (θ?θ) v v v這個向量來表示:

  • 如果今天對任何可能的 v v v v T H v v^THv vTHv都大于零,也就是說現在 θ θ θ不管代入任何值,v可以是任何的v,也就是 θ θ θ可以是任何值,不管 θ θ θ代任何值,紅色框框里面通通都大于零,那意味著 L ( θ ) > L ( θ ′ ) L(θ)>L(θ') L(θ)>L(θ) L ( θ ) L(θ) L(θ)不管代多少只要在 θ ′ θ' θ附近, L ( θ ) L(θ) L(θ)都大于 L ( θ ′ ) L(θ') L(θ),代表 L ( θ ′ ) L(θ') L(θ)是附近的一個最低點,所以它是local minima
  • 如果今天反過來說,對所有的 v v v而言, v T H v v^THv vTHv都小于零,也就是紅色框框里面永遠都小于零,也就是說 θ θ θ不管代什么值,紅色框框里面都小于零,意味著 L ( θ ) < L ( θ ′ ) L(θ)<L(θ') L(θ)<L(θ),代表 L ( θ ′ ) L(θ') L(θ)是附近最高的一個點,所以它是local maxima
  • 第三個可能是假設, v T H v v^THv vTHv,有時候大于零 有時候小于零,你代不同的v進去 代不同的θ進去,紅色這個框框里面有時候大于零,有時候小于零,意味著說在θ’附近,有時候L(θ)>L(θ’) 有時候L(θ)<L(θ’),在L(θ’)附近,有些地方高 有些地方低,這意味著什么,這意味著這是一個saddle point

但是你這邊是說我們要代所有的 v v v,去看 v T H v v^THv vTHv是大于零,還是小于零。我們怎么有可能把所有的v,都拿來試試看呢,所以有一個更簡便的方法,去確認說這一個條件或這一個條件,會不會發生。這個就直接告訴你結論,線性代數理論上是有教過這件事情的,如果今天對所有的v而言, v T H v v^THv vTHv都大于零,那這種矩陣叫做positive definite 正定矩陣,positive definite的矩陣,它所有的eigen value特征值都是正的(>0)。所以如果你今天算出一個hessian,你不需要把它跟所有的v都乘看看,你只要去直接看這個H的eigen value,如果你發現:

  • 所有eigen value都是正的,那就代表說這個條件成立,就 v T H v v^THv vTHv,會大于零,也就代表說是一個local minima。所以你從hessian metric可以看出,它是不是local minima,你只要算出hessian metric算完以后,看它的eigen value發現都是正的**,它就是local minima**。
  • 那反過來說也是一樣,如果今天在這個狀況,對所有的v而言, v T H v v^THv vTHv小于零,那H是negative definite,那就代表所有eigen value都是負的,就保證他是local maxima
  • 那如果eigen value有正有負,那就代表是saddle point。

那假設在這里你沒有聽得很懂的話,你就可以記得結論,**你只要算出一個東西,這個東西的名字叫做hessian,它是一個矩陣,這個矩陣如果它所有的eigen value,都是正的,那就代表我們現在在local minima,如果它有正有負,就代表在saddle point。**那如果剛才講的仍然讓你沒有聽得很懂的話,我們這邊舉一個例子:我們現在有一個史上最廢的network,輸入一個x,它只有一個neuron,乘上 w 1 w_1 w1?,而且這個neuron,還沒有activation function,所以x乘上 w 1 w_1 w1?之后就輸出,然后再乘上 w 2 w_2 w2?然后就再輸出,就得到最終的數據就是y。總之這個function非常的簡單:
y = w 1 ? w 2 ? x y= w_1*w_2*x y=w1??w2??x

我們有一個史上最廢的training set,這個data set說,我們只有一筆data,這筆data是x = 1的時候,它的level是1所以輸入1進去,你希望最終的輸出跟1越接近越好。而這個史上最廢的training,它的error surface,也是有辦法直接畫出來的,因為反正只有兩個參數 w 1 w_1 w1? w 2 w_2 w2?,連bias都沒有,假設沒有bias,只有 w 1 w_1 w1? w 2 w_2 w2?兩個參數,這個network只有兩個參數 w 1 w_1 w1? w 2 w_2 w2?,那我們可以窮舉所有 w 1 w_1 w1? w 2 w_2 w2?的數值,算出所有 w 1 w_1 w1? w 2 w_2 w2?數值所代來的loss,然后就畫出error surface長這個樣。

四個角落loss是高的,好 那這個圖上你可以看出來,有一些critical point,這個黑點點的地方(0,0)原點的地方是critical point,然后事實上,右上三個黑點也是一排critical point,左下三個點也是一排critical point。如果你更進一步要分析,他們是saddle point,還是local minima的話,那圓心原點這個地方它是saddle point,為什么它是saddle point呢?你往左上這個方向走loss會變大,往右下這個方向走loss會變大,往左下這個方向走loss會變小,往右上這個方向走loss會變小,所以它是一個saddle point。而這兩群critical point,它們都是local minima,所以這個山溝里面,有一排local minima,然后在原點的地方有一個saddle point,這個是我們把error surface,暴力所有的參數,得到的loss function的loss的值以后畫出的error surface,可以得到這樣的結論。

現在假設如果不暴力所有可能的loss,如果要直接算一個點,想要判斷這個點是local minima還是saddle point的話,該怎么算呢?我們可以把loss的function寫出來,這個loss的function 這個 L L L是:
L = ( y ^ ? w 1 w 2 x ) 2 L=(\hat{y}-w_1 w_2 x)^2 L=(y^??w1?w2?x)2

正確答案 y ^ \hat{y} y^?減掉model的輸出 w 1 w 2 x w_1w_2x w1?w2?x后取square error,這邊只有一筆data,所以就不會summation over所有的training data,因為反正只有一筆data,x取1, y ^ \hat{y} y^?取1,我剛才說過只有一筆訓練資料最廢的,所以只有一筆訓練資料,所以loss function就是 L = ( y ^ ? w 1 w 2 x ) 2 L=(\hat{y}-w_1 w_2 x)^2 L=(y^??w1?w2?x)2,那你可以把這一個loss function的gradient求出來, w 1 w_1 w1? L L L的微分, w 2 w_2 w2? L L L的微分寫出來是這個樣子:
? L ? w 1 = 2 ( 1 ? w 1 w 2 ) ( ? w 2 ) \frac{?L}{?w_1 }=2(1-w_1 w_2 )(-w_2 ) ?w1??L?=2(1?w1?w2?)(?w2?)

? L ? w 2 = 2 ( 1 ? w 1 w 2 ) ( ? w 1 ) \frac{?L}{?w_2 }=2(1-w_1 w_2 )(-w_1 ) ?w2??L?=2(1?w1?w2?)(?w1?)

這個東西
[ ? L ? w 1 ? L ? w 2 ] \begin{bmatrix} \frac{?L}{?w_1 }\\\ \frac{?L}{?w_2 } \end{bmatrix} [?w1??L???w2??L??]

就是所謂的g,所謂的gradient,什么時候gradient會零呢,什么時候會到一個critical point呢?舉例來說, w 1 = 0 , w 2 = 0 w_1=0,w_2=0 w1?=0,w2?=0即圓心這地方,若 w 1 w_1 w1?代0, w 2 w_2 w2?代0, w 1 w_1 w1? L L L的微分和 w 2 w_2 w2? L L L的微分,算出來就都是零,這個時候我們就知道原點就是一個critical point,但它是local minima還是saddle point呢,那你就要看hessian才能夠知道。

當然我們剛才已經暴力所有可能的 w 1 w_1 w1? w 2 w_2 w2?了,所以你已經知道它顯然是一個saddle point,但是現在假設還沒有暴力所有可能的loss,所以我們要看看能不能夠用Hessian看出它是什么樣的critical point,那怎么算出這個H呢?

看上圖的二次偏微分,H它是一個矩陣,這個矩陣里面元素就是 L L L的二次微分,所以這個矩陣里面第一個row,第一個coloumn的位置,就是 w 1 w_1 w1? L L L微分兩次;第一個row 第二個coloumn的位置,就是先用 w 2 w_2 w2? L L L作微分,再用 w 1 w_1 w1? L L L作微分;然后這邊第二行第一列就是 w 1 w_1 w1? L L L作微分, w 2 w_2 w2? L L L作微分;然后右下角 w 2 w_2 w2? L L L微分兩次,這四個值組合起來,就是我們的hessian,那這個hessian的值是多少呢?這個hessian的式子,我都已經把它寫出來了,你只要把 w 1 w_1 w1?=0 w 2 w_2 w2?=0代進去,代進去你就得到在原點的地方,hessian是這樣的一個矩陣:
[ 0 ? 2 ? 2 0 ] \begin{bmatrix} {0}&-2\\\ {-2}&0 \end{bmatrix} [0??2??20?]

這個hessian告訴我們,它是local minima,還是saddle point呢,那你就要看這個矩陣的eigen value,算一下發現,這個矩陣有兩個eigen value,2跟-2,eigen value有正有負,代表saddle point,所以我們現在就是用一個例子,跟你操作一下告訴你說,你怎么從hessian看出一個critical point是saddle point還是local minima。

Don’t afraid of saddle point

如果今天你卡的地方是saddle point,也許你就不用那么害怕了,因為如果你今天你發現,你停下來的時候,是因為saddle point停下來了,那其實就有機會可以放心了,因為H它不只可以幫助我們判斷,現在是不是在一個saddle point,它還指出了我們參數,可以update的方向,就之前我們參數update的時候,都是看gradient看g,但是我們走到某個地方以后,發現g變成0了就不能再看g了,g不見了gradient沒有了,但如果是一個saddle point的話,還可以再看H,怎么再看H呢,H怎么告訴我們,怎么update參數呢?

我們這邊假設 μ \mu μ是H的eigen vector特征向量, λ λ λ μ \mu μ的eigen value特征值。如果我們把這邊的 v v v換成 μ \mu μ的話,我們把 μ \mu μ乘在H的左邊,跟H的右邊,也就是 μ T H μ \mu^TH\mu μTHμ H μ H\mu Hμ會得到 λ μ λ\mu λμ,因為 μ \mu μ是一個eigen vector。所以我們在這邊得到 μ T \mu ^ T μT乘上 λ μ \lambda\mu λμ,然后再整理一下,把 μ T \mu^T μT μ \mu μ乘起來,得到 ‖ u ‖ 2 ‖u‖^2 u2,所以得到 λ ‖ μ ‖ 2 λ‖\mu‖^2 λμ2(附近這幾張圖中的 u u u其實就是我們所說的 μ \mu μ

1 2 ( θ ? θ ′ ) T H ( θ ? θ ′ ) = 1 2 λ ∣ ∣ θ ? θ ′ ∣ ∣ 2 \frac{1}{2}(\theta-\theta^{'})^TH(\theta-\theta^{'}) = \frac{1}{2}\lambda||\theta-\theta^{'}||^2 21?(θ?θ)TH(θ?θ)=21?λθ?θ2

對于上式,假設v代的是一個eigen vector,我們這邊 θ θ θ θ ′ θ' θ,放的是一個eigen vector的話,會發現說我們這個紅色的項里面,其實就是 λ ‖ μ ‖ 2 λ‖\mu‖^2 λμ2

?如果 λ λ λ小于零,即eigen value小于零的話,那 λ ‖ μ ‖ 2 λ‖\mu‖^2 λμ2就會小于零(因為 ‖ μ ‖ 2 ‖\mu‖^2 μ2一定是正的,所以eigen value是負的,那這一整項就會是負的),也就是 μ \mu μ的transpose乘上H乘上 μ \mu μ是負的,也就是紅色這個框里是負的。所以這意思是說假設 θ ? θ ′ = μ θ-θ'=\mu θ?θ=μ,那這一項 ( θ ? θ ′ ) T H ( θ ? θ ′ ) (θ-θ')^TH(θ-θ') (θ?θ)TH(θ?θ)就是負的,也就是 L ( θ ) < L ( θ ′ ) L(θ)<L(θ') L(θ)<L(θ)。也就是說若 θ ? θ ′ = μ θ-θ'=\mu θ?θ=μ,你在 θ ′ θ' θ的位置加上 μ \mu μ,沿著 μ \mu μ的方向做update得到 θ θ θ,你就可以讓loss變小。因為根據這個式子,你只要 θ θ θ θ ′ θ' θ等于 μ \mu μ,loss就會變小,所以你今天只要讓 θ θ θ等于 θ ′ θ' θ μ \mu μ,你就可以讓loss變小,你只要沿著 μ \mu μ,也就是eigen vector的方向,去更新改變你的參數,你就可以讓loss變小了。

所以雖然在critical point沒有gradient,如果我們今天是在一個saddle point,你也不一定要驚慌,你只要找出負的eigen value,再找出它對應的eigen vector,用這個eigen vector去加 θ ′ θ' θ,就可以找到一個新的點,這個點的loss比原來還要低

舉具體的例子:

剛才我們已經發現,原點是一個critical point,它的Hessian長這個樣,那現在這個Hessian有一個負的eigen value,這個eigen value等于-2,那它對應的eigen vector會有很多個(其實有無窮多個對應的eigen vector),我們就取一個出來,我們取 [ 1 1 ] \begin{bmatrix}{1} \\\ {1}\end{bmatrix} [1?1?]是它對應的一個eigen vector,那我們其實只要順著這個 μ \mu μ的方向,順著 [ 1 1 ] \begin{bmatrix}{1} \\\ {1}\end{bmatrix} [1?1?]這個vector的方向,去更新我們的參數,就可以找到一個比saddle point的loss還要更低的點。如果以今天這個例子來看的話,你的saddle point在(0,0)這個地方,你在這個地方會沒有gradient,Hessian的eigen vector告訴我們,只要往 [ 1 1 ] \begin{bmatrix}{1} \\\ {1}\end{bmatrix} [1?1?]的方向更新,你就可以讓loss變得更小,也就是說你可以逃離你的saddle point,然后讓你的loss變小,所以從這個角度來看,似乎saddle point并沒有那么可怕。

如果你今天在training的時候,你的gradient你的訓練停下來,你的gradient變成零,訓練停下來是因為saddle point的話,那似乎還有解。但是當然實際上,在實際的implementation里面,你幾乎不會真的把Hessian算出來,這個要是二次微分,要計算這個矩陣的computation,需要的運算量非常非常的大,更遑論你還要把它的eigen value跟eigen vector找出來,所以在實作上,你幾乎沒有看到有人用這一個方法來逃離saddle point。

等一下我們會講其他有機會逃離saddle point的方法,他們的運算量都比要算這個H,還要小很多,那今天之所以我們把這個saddle point跟eigen vector、跟Hessian的eigen vector拿出來講,是想要告訴你,如果是卡在saddle point,也許沒有那么可怕,最糟的狀況下你還有這一招可以告訴你要往哪一個方向走。

Saddle Point v.s. Local Minima

講到這邊你就會有一個問題了,這個問題是:那到底saddle point跟local minima,誰比較常見呢?saddle point其實并沒有很可怕,那如果我們今天常遇到的是saddle point,比較少遇到local minima,那就太好了,那到底saddle point跟local minima哪一個比較常見呢?這邊我們要講一個不相干的故事,先講一個故事吧。

這個故事發生在1543年,1543年發生了什么事呢,那一年君士坦丁堡淪陷,這個是君士坦丁堡淪陷圖,君士坦丁堡本來是東羅馬帝國的領土,然后被鄂圖曼土耳其帝國佔領了,然后東羅馬帝國就滅亡了,在鄂圖曼土耳其人進攻,君士坦丁堡的時候,那時候東羅馬帝國的國王,是君士坦丁十一世,他不知道要怎么對抗土耳其人,有人就獻上了一策,找來了一個魔法師叫做狄奧倫娜。這是真實的故事,出自三體的故事,這個狄奧倫娜這樣說,狄奧倫娜是誰呢,他有一個能力跟張飛一樣,張飛不是可以萬軍從中取上將首級如探囊取物嗎,狄奧倫娜也是一樣,他可以從萬軍中取得蘇丹的頭,大家想說狄奧倫娜怎么這么厲害,他真的有這么強大的魔法嗎,所以大家就要狄奧倫娜先展示一下他的力量,這時候狄奧倫娜就拿出了一個圣杯,大家看到這個圣杯就大吃一驚,為什么大家看到這個圣杯要大吃一驚呢,因為這個圣杯本來是放在圣索菲亞大教堂的地下室,而且它是被放在一個石棺里面,這個石棺是密封的,沒有人可以打開它。但是狄奧倫娜他從里面取得了圣杯,而且還放了一串葡萄進去,君士坦丁十一世為了要驗證狄奧倫娜是不是真的有這個能力,就帶了一堆人真的去撬開了這個石棺,發現圣杯真的被拿走了,里面真的有一串新鮮的葡萄,就知道狄奧倫娜真的有,那為什么迪奧倫娜可以做到這些事呢,那是因為這個石棺你覺得它是封閉的,那是因為你是從三維的空間來看,這個石棺是封閉的,沒有任何路可以進去,但是狄奧倫娜可以進入四維的空間,從高維的空間中,這個石棺是有路可以進去的,它并不是封閉的,至于狄奧倫娜有沒有成功刺殺蘇丹呢,你可以想像一定是沒有嘛,所以君坦丁堡才淪陷,那至于為什么沒有,大家請見于三體。

總之這個**從三維的空間來看,是沒有路可以走的東西,在高維的空間中是有路可以走的,error surface會不會也一樣呢?**所以你在一維的空間中,一維的一個參數的error surface,你會覺得好像到處都是local minima,但是會不會在二維空間來看,它就只是一個saddle point呢,常常會有人畫類似這樣的圖,告訴你說Deep Learning的訓練,是非常的復雜的,如果我們移動某兩個參數,error surface的變化非常的復雜,是這個樣子的,那顯然它有非常多的local minima,我的這邊現在有一個local minima,但是會不會這個local minima只是在二維的空間中,看起來是一個local minima,在更高維的空間中,它看起來就是saddle point,在二維的空間中,我們沒有路可以走,在更高的維度上,雖然我們沒辦法visualize它,沒辦法真的拿出來看,但是會不會在更高維的空間中,其實有路可以走的?那如果維度越高,是不是可以走的路就越多了呢?所以今天我們在訓練一個network的時候,參數往往動輒百萬千萬以上,所以我們的error surface,其實是在一個非常高的維度中,對不對,我們參數有多少,就代表我們的error surface的維度有多少,參數是一千萬就代表error surface的維度是一千萬,竟然維度這么高,會不會其實根本就有非常多的路可以走呢,那既然有非常多的路可以走,會不會其實local minima,根本就很少呢?

而經驗上,如果你自己做一些實驗的話,也支持這個假說

這邊是訓練某一個network的結果,每一個點代表訓練完那個network之后,把它的Hessian拿出來進行計算,所以這邊的每一個點,都代表一個network,就我們訓練某一個network,然后把它訓練訓練,訓練到gradient很小,卡在critical point,把那組參數出來分析,看看它比較像是saddle point,還是比較像是local minima

  • 縱軸代表training的時候的loss,就是我們今天卡住了,那個loss沒辦法再下降了,那個loss是多少,那很多時候,你的loss在還很高的時候,訓練就不動了,就卡在critical point,那很多時候loss可以降得很低,才卡在critical point,這是縱軸的部分。
  • 橫軸的部分是minimum ratio,minimum ratio是eigen value的數目分之正的eigen value的數目,又如果所有的eigen value都是正的,代表我們今天的critical point,是local minima,如果有正有負代表saddle point,那在實作上你會發現說,你幾乎找不到完全所有eigen value都是正的critical point,你看這邊這個例子里面,這個minimum ratio代表eigen value的數目分之正的eigen value的數目,最大也不過0.5到0.6間而已,代表說只有一半的eigen value是正的,還有一半的eigen value是負的,

所以今天雖然在這個圖上,越往右代表我們的critical point越像local minima,但是它們都沒有真的,變成local minima,就算是在最極端的狀況,我們仍然有一半的case,我們的eigen value是負的,這一半的case,eigen value是正的,代表說在所有的維度里面有一半的路,這一半的路如果要讓loss上升,還有一半的路可以讓loss下降。所以從經驗上看起來,其實local minima并沒有那么常見,多數的時候你覺得你train到一個地方,你gradient真的很小,然后所以你的參數不再update了,往往是因為你卡在了一個saddle point。


Batch and Momentum are helpful for crital point

Review: Optimization with Batch

其實我們在使用深度學習對數據進行微分迭代的時候,是將所有數據分成一個一個的Batch(有人叫Mini Batch,其實都是一個含義)。這所有的Batch都訓練一遍,就是一個Epoch。


Batch的大小代表了不同含義,Batch越大,說明一次需要的數據也越多,需要的數據多,那擬合出來的也就越穩定;反之Batch越小,說明一次訓練所需數據也就越少,那擬合出來的也就不那么穩定。使用Batch,若Batch Size = 1的話代表我們每次更新參數時,只需拿一筆Data算Loss。看一筆Data就更新一次參數。如果數據集總共劃分為20筆Data,那在每在一個Epoch里,參數會更新20次。用一筆Data算出來的 Loss顯然是比較Noisy的,所以迭代更新的方向是曲曲折折的。

左邊的方法有一個優點就是它這一步走的是穩的。而右邊這個方法它的缺點就是它每一步走的是不穩的。但是越穩定就一定越好嗎?那也不見得,On Large-Batch Training For Deep Learning,Generalization Gap And Sharp Minima,這篇 Paper 的實驗結果如下:

可以看到在測試集上,小的Batch(SB,Small Batch)明顯效果要比大的Batch效果好。那又為何會就這樣的現象?文章給出了解釋:

假設這個是我們的Training Loss,那在這個Training Loss 上面呢,可能有很多個Local Minima,有不只一個Local Minima,那這些 Local Minima 它們的 Loss 都很低,它們 Loss 可能都趨近于 0,但是這個 Local Minima,還是有好 Minima 跟壞 Minima 之分。如果一個 Local Minima 它在一個峽谷里面,它是壞的 Minima,然后它在一個平原上,它是好的 Minima,為什么會有這樣的差異呢?

因為假設現在 Training 跟 Testing 中間,有一個 Mismatch,Training 的 Loss 跟 Testing 的 Loss,它們那個 Function 不一樣,有可能是本來你 Training 跟 Testing 的 Distribution就不一樣。那也有可能是因為 Training 跟 Testing,你都是從 Sample 的 Data 算出來的,也許 Training 跟 Testing,Sample 到的 Data 不一樣,那所以它們算出來的 Loss,當然是有一點差距。那我們就假設說這個 Training 跟 Testing,它的差距就是把 Training 的 Loss這個 Function 往右平移一點,這時候你會發現,對左邊這個在一個盆地里面的 Minima 來說,它的在 Training 跟 Testing 上面的結果,不會差太多,只差了一點點,但是對右邊這個在峽谷里面的 Minima 來說,一差就可以天差地遠。

它在這個 Training Set 上,算出來的 Loss 很低,但是因為 Training 跟 Testing 之間的不一樣,所以 Testing 的時候,這個 Error Surface 一變,它算出來的 Loss 就變得很大,而很多人相信這個大的 Batch Size,會讓我們傾向于走到峽谷里面,而小的 Batch Size,傾向于讓我們走到盆地里面。那他直覺上的想法是這樣,就是小的 Batch,它有很多的 Loss,它每次 Update 的方向都不太一樣,所以如果今天這個峽谷非常地窄,它可能一個不小心就跳出去了,因為每次 Update 的方向都不太一樣,它的 Update 的方向也就隨機性,所以一個很小的峽谷,沒有辦法困住小的 Batch。

如果峽谷很小,它可能動一下就跳出去,之后停下來如果有一個非常寬的盆地,它才會停下來,那對于大的 Batch Size,反正它就是順著規定 Update,然后它就很有可能,走到一個比較小的峽谷里面。但這只是一個解釋,那也不是每個人都相信這個解釋,那這個其實還是一個尚待研究的問題。

那這邊對大小Batch做一個總結,如圖:

Momentum

Momentum,這也是另外一個有可能可以對抗 Saddle Point 或 Local Minima 的技術,Momentum 的運作是這個樣子的:

它的概念,你可以想像成在物理的世界里面,假設 Error Surface 就是真正的斜坡,而我們的參數是一個球,你把球從斜坡上滾下來,如果今天是 Gradient Descent,它走到 Local Minima 就停住了,走到 Saddle Point 就停住了,但是在物理的世界里,一個球如果從高處滾下來,從高處滾下來就算滾到 Saddle Point,如果有「慣性」,它從左邊滾下來,因為慣性的關系它還是會繼續往右走,甚至它走到一個 Local Minima,如果今天它的動量夠大的話,它還是會繼續往右走,甚至翻過這個小坡然后繼續往右走,那所以今天在物理的世界里面,一個球從高處滾下來的時候,它并不會被 Saddle Point,或 Local Minima卡住,不一定會被 Saddle Point,或 Local Minima 卡住,我們有沒有辦法運用這樣子的概念,到 Gradient Descent 里面呢,那這個就是我們等一下要講的,Momentum 技術。

Vanilla Gradient Descent

那我們先很快的復習一下,原來的 Gradient Descent 長得是什么樣子,這個是 Vanilla 的 Gradient Descent,Vanilla 的意思就是一般的的意思,它直譯是香草的,但就其實是一般的,一般的 Gradient Descent 長什么樣子呢

一般的 Gradient Descent 是說,我們有一個初始的參數叫做 θ 0 θ^0 θ0,我們計算一下 Gradient,然后計算完這個 Gradient 以后呢,我們往 Gradient 的反方向去 Update 參數:
θ 1 = θ 0 ? η g 0 θ^1 = θ^0 - {\eta}g^0 θ1=θ0?ηg0

我們到了新的參數以后,再計算一次 Gradient,再往 Gradient 的反方向,再 Update 一次參數,到了新的位置以后再計算一次 Gradient,再往 Gradient 的反方向去 Update 參數,這個 Process 就一直這樣子下去。

Gradient Descent + Momentum

加上 Momentum 以后,每一次我們在移動我們的參數時,我們不是只往 Gradient Desent 的反方向來移動參數,我們是 Gradient 的反方向,加上前一步移動的方向,兩者加起來的結果,去調整去到我們的參數,

那具體說起來是這個樣子,一樣找一個初始的參數,然后我們假設前一步的參數的 Update 量呢,就設為 0。
m 0 = 0 m^0 = 0 m0=0

接下來在 θ 0 θ^0 θ0 的地方,計算 Gradient 的方向 g 0 g^0 g0,然后接下來你要決定下一步要怎么走,它是 Gradient 的方向加上前一步的方向,不過因為前一步正好是 0,現在是剛初始的時候所以前一步是 0,所以 Update 的方向,跟原來的 Gradient Descent 是一樣的,這沒有什么有趣的地方。

m 1 = λ m 0 ? η g 0 θ 1 = θ 0 + m 1 m^1 = {\lambda}m^0- {\eta}g^0 \\\ θ^1 = θ^0 + m^1 m1=λm0?ηg0?θ1=θ0+m1

但從第二步開始,有加上 Momentum 以后就不太一樣了,從第二步開始,我們計算 g 1 g^1 g1,然后接下來我們 Update 的方向,不是 g 1 g^1 g1的反方向,而是根據上一次 Update 方向,也就是 m 1 m^1 m1 減掉 g 1 g^1 g1,當做我們新的 Update 的方向,這邊寫成 m 2 m^2 m2
m 2 = λ m 1 ? η g 1 m^2 = {\lambda}m^1-{\eta}g^1 m2=λm1?ηg1

那我們就看下面這個圖:

g 1 g^1 g1 告訴我們,Gradient 告訴我們要往紅色反方向這邊走,但是我們不是只聽 Gradient 的話,加上 Momentum 以后,我們不是只根據 Gradient 的反方向,來調整我們的參數,我們也會看前一次 Update 的方向:

  • 如果前一次說要往 m 1 m^1 m1藍色及藍色虛線這個方向走
  • Gradient 說要往紅色反方向這個方向走
  • 把兩者相加起來,走兩者的折中,也就是往藍色 m 2 m^2 m2這一個方向走,所以我們就移動了 m 2 m^2 m2,走到 θ 2 θ^2 θ2 這個地方

接下來就反覆進行同樣的過程,在這個位置我們計算出 Gradient,但我們不是只根據 Gradient 反方向走,我們看前一步怎么走,前一步走這個方向,走這個藍色虛線的方向,我們把藍色的虛線加紅色的虛線,前一步指示的方向跟 Gradient 指示的方向,當做我們下一步要移動的方向。

每一步的移動,我們都用 m 來表示,那這個 m 其實可以寫成之前所有算出來的,Gradient 的 Weighted Sum.從右邊的這個式子,其實就可以輕易的看出來

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=0?m1=?ηg0?m2=?ληg0?ηg1?...

m 0 m^0 m0 我們把它設為 0, m 1 m^1 m1 m 0 m^0 m0 減掉 g 0 g^0 g0 m 0 m^0 m0 為 0,所以 m 1 m^1 m1 就是 g 0 g^0 g0 乘上負的 η \eta η m 2 m^2 m2 λ \lambda λ 乘上 m 1 m^1 m1 λ \lambda λ 就是另外一個參數,就好像 η \eta η 是 Learning Rate 我們要調, λ \lambda λ 是另外一個參數,這個也是需要調的, m 2 m^2 m2 等于 λ \lambda λ 乘上 m 1 m^1 m1,減掉 η \eta η 乘上 g 1 g^1 g1,然后 m 1 m^1 m1 在哪里呢, m 1 m^1 m1 在這邊,你把 m 1 m^1 m1 代進來,就知道說 m 2 m^2 m2,等于負的 λ \lambda λ 乘上 η \eta η 乘以 g 0 g^0 g0,減掉 η \eta η 乘上 g 1 g^1 g1,它是 g 0 g^0 g0 g 1 g^1 g1 的 Weighted Sum。以此類推,所以你會發現說,現在這個加上 Momentum 以后,一個解讀是 Momentum 是,Gradient 的負反方向加上前一次移動的方向,那但另外一個解讀方式是,所謂的 Momentum,當加上 Momentum 的時候,我們 Update 的方向,不是只考慮現在的 Gradient,而是考慮過去所有 Gradient 的總合.

總結就是,Monmentum類似于物理的動量或慣性,在迭代的時候不會因為梯度下降為0則立刻停止,它會有一個向前制動的過程,然后緩慢停止。這帶來的好處就是,不會說遇到梯度下降為0的 critial point 時,無法繼續迭代,讓我們使用者不好判斷到底是 saddle point 還是 local minima。


Adaptive Learning Rate

前面說到,訓練一個network,train到發現loss不再下降的時候,并不一定是梯度為0或者極小,也可能是saddle point,除此之外也可能是我們訓練時,batch-size的大小設置不當導致的。那之前也說到,梯度下降時,是有學習率的,也可能是因為學習率過小導致的(但是學習率太大的話,又有可能在local minima上放反復橫條,如下圖左圖),因為學習率過小,無法到達的話,就如下圖右圖所示:


這個訓練永遠走不到終點,就是因為learning rate已經太小了,可以看到,上圖右圖在左拐的時候,迭代了10萬次仍然只走了一小部分,上面這個地方坡度已經非常的平滑了,這么小的learning rate根本沒有辦法再讓訓練前進。在之前的gradient descend,所有的參數都是設同樣的learning rate。這里我們可以客制化學習率,讓其自動調整,「不會因為」梯度下降時偏微分的值越來越小的同時而保持學習率不變。

那我們要怎么客制化learning rate呢,不同的參數到底需要什么樣的learning rate?從剛才的例子里面,其實我們可以看到一個大原則,如果在某一個方向上,我們的gradient的值很小,非常的平坦,那我們會希望learning rate調大一點,如果在某一個方向上非常的陡峭,坡度很大,那我們其實期待,learning rate可以設得小一點

那么我直接列出一下幾種變化學習率的方式:

1. Root mean square



θ i 2 θ_i^2 θi2?這個方向上loss的變化比較大,所以算出來的gradient都比較大, σ \sigma σ就比較大; σ \sigma σ比較大,update的時候step就比較小。所以有了 σ \sigma σ這一項以后呢,就可以隨著gradient的不同來自動的調整learning rate的大小。但是這個有個問題:就算是同一個參數,它需要的learning rate也會隨著時間而改變。

3. RMSProp



Summary of Optimization

所以我們從最原始的gradient descent,進化到這一個版本:

這個版本里面:

  • 我們有Momentum,也就是說現在不是完全順著gradient的方向,現在不是完全順著這一個時間點,算出來的gradient的方向,來update參數,而是把過去所有算出來gradient的方向,做一個總和當作update的方向,這個是momentum。
  • 接下來應該要update多大的步伐呢,我們要除掉gradient的Root Mean Square。

那么你可能會覺得很困惑,這一個momentum是考慮過去所有的gradient,這個 σ \sigma σ也是考慮過去所有的gradient,一個放在分子一個放在分母,都考慮過去所有的gradient,不就是正好抵銷了嗎,但是其實這個Momentum跟這個 σ \sigma σ,它們在使用過去所有gradient的方式是不一樣的,Momentum是直接把所有的gradient通通都加起來,所以它有考慮方向,它有考慮gradient的正負號,它有考慮gradient是往左走還是往右走;但是這個Root Mean Square,它就不考慮gradient的方向了,它只考慮gradient的大小,記不記得在算 σ \sigma σ時,都要把gradient取一個平方項,我們是把平方的結果加起來,所以我們只考慮gradient的大小,不考慮它的方向,所以Momentum跟這個 σ \sigma σ,算出來的結果并不會互相抵銷掉。

  • 那最后我們還會加上,一個learning rate的scheduling。

最后說說在分類任務上,應該如何優化神經網絡,從optimization的角度,cross-entropy比Mean Square Error更加適合用在分類上。使用cross-entropy這個loss function時,pytorch自動幫你把softmax加到你的Network的最后一層。

以上就是本次學習的內容,理論內容還是非常多的,需要好好消化一下。

總結

以上是生活随笔為你收集整理的神经网络训练不起来,怎么办?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。