Optimization
- 1.Adaptive Learning Rate
- 2.不同的參數需要不同的學習率
- 3.Root Mean Square
- 4.RMSProp
- 5.Adam
- 6.learning rate scheduling
- 7.warm up
- 總結
critical point不一定是你在訓練一個network時候遇到的最大的障礙。
1.Adaptive Learning Rate
也就是我們要給每個參數不同的Learning rate
往往在訓練一個network的時候,你會把他的loss記錄下來,隨著你參數不斷的update,你的loss呢不再下降了,就卡住了。。那多數時候這個時候大家就會猜說誒,那是不是走到了critical point,因為gradient等于零的關系,所以我們沒有辦法再更新參數。
當我們說走到critical point的時候,意味著gradient非常的小,但是你有確認過,當你的loss不再下降的時候,gradient真的很小嗎?其實并不然。
下面這個例子,當我們的loss不再下降的時候,gradient的這個向量并沒有真的變得很小,在最后訓練的最終結的時候,loss幾乎沒有在減少了,但是gradient卻突然還上升了一下。這個是我們的error surface,現在的gradient在error surface的兩個谷壁間不斷的來回的震蕩,這個時候你的loss不會再下降,所以你會覺得看到這樣子的狀況,但是實際上他真的卡到了critical point、卡到了settle point、卡到了local minima嗎?不是的。它的gradient仍然很大,只是loss不見得在減小了。
所以當你今天你訓練個network,后來發現loss不再下降的時候,可能只是單純的loss沒有辦法在下降,而不是卡在了那些點上。
我們在訓練的時候其實很少卡到settle point或者是local minima,多數時候training在還沒有走到critical point的時候,就已經停止了,但這并不代表說critical point不是一個問題,我們真正當你用gradient descent來做optimization的時候,你真正應該怪罪的對象往往不是critical point,而是其他的原因。
那為什么如果今天critical point不是問題的話,為什么我們的training會卡住呢,我這邊舉一個非常簡單的例子。
你會發現說就連這種convex的error surface,形狀這么簡單的error surface,你用gradient descent都不見得能把它做好
學習率= 1 0 ? 2 10^-2 10?2,時候,在震蕩沒有辦法慢慢的滑到山谷里面,這時試著去調整了這個learning rate
學習率= 1 0 ? 7 10^-7 10?7終于不再震蕩了,終于從這個地方滑滑滑滑滑滑到山谷底,然后終于左轉了,但是你發現說這個訓練永遠走不到終點,因為我的learning rate已經太小了,在這個很斜的地方,這個坡度很陡gradient的值很大,所以還能夠前進一點,左轉后的這個地方坡度已經非常的平滑了,這么小的learning rate根本沒有辦法再讓我們的訓練前進,,
gradient descent這個工具連這么簡單的error surface都做不好,那如果難的問題,他又怎么有可能做好呢
那怎么把gradient descent做得更好呢?在之前我們的gradient descent里面,所有的參數都是設同樣的learning rate,這顯然是不夠的,learning rate應該要為每一個參數特制化。
2.不同的參數需要不同的學習率
大原則:如果在某一個方向上gradient的值很小,在某一個方向上非常的平坦,那我們會希望learning rate調大一點;如果在某一個方向上非常的陡峭,某一個方向上坡度很大,那我learning rate可以設的小一點。
之前在講gradient descent的時候,往往是講所有參數update的式子,為了簡化問題,我們現在只看一個參數,你完全可以把這個方法推廣到所有參數的狀況。
不同的參數我們要給它不同的sigma,同時他也是iteration dependent的,不同的iteration我們也會有不同的sigma。
如何計算這個sigma呢?
一個常見的類型是算gradient的Root Mean Square
3.Root Mean Square
這樣的話坡度比較大的時候learning rate就減小,坡度比較小的時候learning rate就放大。
坡度比較小的時候如 θ 1 \theta_1 θ1?,g小–> σ \sigma σ小—>learning rate就大(你在update的時候的量啊就比較大)
坡度比較大的時候如 θ 2 \theta_2 θ2?,g大–> σ \sigma σ大—>learning rate就小
所以有了 σ \sigma σ這一項以后,你就可以隨著gradient的不同,每個參數gradient的不同,來自動的調整learning rate的大小
上面的這個參數不會隨時間改變,我們剛才的假設是同一個參數,它的gradient的大小就會固定是差不多的值,如果來看這個新月型的error surface,考慮橫軸的話,有的地方地方坡度比較平滑,有的地方地方坡度比較陡峭,所以就算是同個參數,同一個方向,我們也期待說learning rate是可以動態的調整的。
所以就有了RMSProp
4.RMSProp
這個方法沒有論文。
這個方法的第一步跟剛才講的算Root Mean Square一模一樣
第二步算 σ 1 \sigma_1 σ1?的方法和算Root Mean Square的時候不一樣,上一個的每一個gradient都有同等的重要性,但在RMSProp你可以自己調整現在的這個gradient的重要性,
如果我 α \alpha α設很小趨近于零,就代表說我覺得g1相較于之前所算出來的gradient而言比較重要;如果我 α \alpha α設很大趨近于1,那就代表說我覺得現在算出來的g1比較不重要。
這個 α \alpha α就會決定現在剛算出來的 g t g_t gt?它有多重要
如果你用RMSProp的話,你就可以動態調整 σ 1 \sigma_1 σ1?這一項.
比如下面的黑線,是我們的error surface,開始小球一路平坦,說明G算出來很小,G算出來很小,就代表說這個 σ \sigma σ算出來很小, σ \sigma σ算出來很小,就代表說現在update參數的時候,我們會走比較大的步伐;
當滾到斜坡時候,我們gradient變大了,如果是Adam的話,它反應比較慢;但如果你用RMSProp,把 α \alpha α設小,就是讓新看到的gradient影響比較大,那你就可以很快的讓 σ \sigma σ的值變大,然后很快讓你的步伐呢變小。
又走到平滑的地方時候,調整 α \alpha α,讓他比較看重于最近算出來的gradient,所以你gradient變小,它的這個 σ \sigma σ的值變大值呢就變小了,然后呢你走的步伐呢就變大了。
5.Adam
最常用optimization的策略就是Adam:RMSProp+Momentum
我們再看開始的例子,用了第二個的方法后做起來是這個樣子的。這個gradient都取平方,再平均再開根號,然后接下來在左轉的時候,剛才我們update了10萬次卡住了,現在可以繼續走下去,因為這個左右的方向的這個gradient很小,所以learning rate會自動調整,左右這個方向learning rate會自動變大,所以這個步伐呢就可以變大。
但走著走著突然爆炸了,為什么走到這邊突然爆炸了呢?因為我們在算這個 σ \sigma σ的時候是把過去所有看到的gradient都拿來做平均,所以這個縱軸的這個方向,這個縱軸的方向雖然在初始的這個地方感覺gradient很大,但是這邊走了很長一段路以后,這個縱軸的方向gradient算出來都很小,所以縱軸的這個方向就累積了小的 σ \sigma σ,累積到一個地步以后,這個step就變很大,然后就暴走就噴出去了,,
不過噴出去后走到gradient比較大的地方以后, σ \sigma σ又慢慢的變大, σ \sigma σ變大以后,這個參數update的距離,update的這個步伐大小又慢慢的變小,所以就發現說誒走著走著突然往左右噴了一下,但是這個噴這個噴了一下,不會永遠就是震蕩,不會做簡諧運動,他這個左這個這個力道會慢慢變小,讓它慢慢的慢慢的又回到中間這個峽谷了。
這樣怎么辦呢?有一個方法也許可以解決這個問題,這個叫做learning rate schedule
6.learning rate scheduling
我們這個式子還有個參數 η \eta η,他要是跟時間有關的,我們不要把它當成一個常數。
最常見的策略啊叫做learning rate decay,也就是說隨著時間不斷的進行,隨著參數不斷的update,我們這個 η \eta η讓它越來越小,讓這個learning rate越來越小。
為什么要讓這個learning rate越來越小呢?因為一開始我們距離終點很遠,隨著參數不斷update,我們距離終點越來越近,我們參數的更新要能夠慢慢的慢下來。
所以剛才那個狀況,如果加上learning rate decay的話,我們就可以很平順的走到終點。因為在后面這個 η \eta η已經變得非常的小了,雖然說他本來想要左右亂噴,但是會乘上這個非常小的 η \eta η,那就停下來了,就可以慢慢的走到終點。
除了learning rate decay以外,還有另外一個經典非常常用的learning rate schedule的方式叫做warm up。
7.warm up
這個warm up的方法是說我們這個learning rate要先變大后變小
Residual Network這邊特別注明它反其道而行,一開始要設0.01,接下來設0.1,還特別加個注解
同時warm up在transformer里面也用一個式子提了它好,你實際上把它的把這個方程畫出來,就會發現它就2learning rate會先增加,然后接下來再遞減。
所以發現說warm up這個技術,在很多知名的network里面都有被當做一個黑科技,就論文里面不解釋說為什么要用這個,但就偷偷在一個小地方,你沒有注意到。
那為什么需要warm up呢?這個仍然是今天一個可以研究的問題了。
這邊有一個可能的解釋是說,當我們在用Adam、RMSProp時候,我們要計算 σ \sigma σ,這個sigma它是一個統計的結果,告訴我們說某一個方向他到底有多陡或者是多平滑,那這個統計的結果要看了夠多筆數據以后,這個統計才精準,所以我們一開始呢 σ \sigma σ不精準,所以開始不要讓我們的參數走離初始的地方太遠,一開始讓learning rate比較小,是讓他探索搜集一些有關error surface的情報,等sigma統計比較精準以后,再把讓learning ray呢慢慢的爬升,這是一個解釋為什么我們需要warm up的可能性。
如果你想要學更多有關warm up的東西的話,可以看RAdam。
總結
有關optimization的部分,我們從最原始的gradient descent進化到下面這個版本
這個版本我們有momentum,也就是說我們現在不是完全順著這個時間點算出來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的schedule。
這種optimizer除了Adam以外還有各式各樣的變形.