# **Machine Learning Class4** # **Gradient Descent** 前面預測寶可夢cp值的例子里,已經初步介紹了Gradient Descent的用法: In step 3, we have to solve the following optimization problem: ![](https://i.imgur.com/2CJStlZ.png) L : loss function $θ$ : parameters(上標表示第幾組參數,下標表示這組參數中的第幾個參數) 假設$θ$是參數的集合:Suppose that has two variables {θ~1~,θ~2~} 隨機選取一組起始的參數:Randomly start at $θ^0$ 計算處的梯度gradient:![](https://i.imgur.com/QYc4WtI.png) ![](https://i.imgur.com/hIDwgqm.png) 下圖是將gradient descent在投影到二維坐標系中可視化的樣子,圖上的每一個點都是在(θ~1~,θ~2~,$loss$)該平面的投影 ![](https://i.imgur.com/hQoEKHZ.png) 紅色箭頭是指在(θ~1~,θ~2~)這點的梯度,梯度方向即箭頭方向(從低處指向高處),梯度大小即箭頭長度(表示在點$θ^i$處最陡的那條切線的導數大小,該方向也是梯度上升最快的方向) 藍色曲線代表實際情況下參數θ~1~和θ~2~的更新過程圖,每次更新沿著藍色箭頭方向loss會減小,藍色箭頭方向與紅色箭頭方向剛好相反,代表著梯度下降的方向 因此,++在整個gradient descent的過程中,梯度不一定是遞減的(紅色箭頭的長度可以長短不一),但是沿著梯度下降的方向,函數值loss一定是遞減的,且當gradient=0時,loss下降到了局部最小值++,總結:==梯度下降法指的是函數值loss隨梯度下降的方向減小== 初始隨機在三維坐標系中選取一個點,這個三維坐標系的三個變量分別為(θ~1~,θ~2~,$loss$),我們的目標是找到最小的那個loss也就是三維坐標系中高度最低的那個點,而gradient梯度可以理解為高度上升最快的那個方向,它的反方向就是梯度下降最快的那個方向,於是每次update沿著梯度反方向,update的步長由梯度大小和learning rate共同決定,當某次update完成後,該點的gradient=0,說明到達了局部最小值 下面是關於gradient descent的一點思考: ![](https://i.imgur.com/fqMl4VM.png) ## **Learning rate存在的問題** gradient descent過程中,影響結果的一個很關鍵的因素就是learning rate的大小 + 如果learning rate剛剛好,就可以像下圖中紅色線段一樣順利地到達到loss的最小值 + 如果learning rate太小的話,像下圖中的藍色線段,雖然最後能夠走到local minimal的地方,但是它可能會走得非常慢,以至於你無法接受 + 如果learning rate太大,像下圖中的綠色線段,它的步伐太大了,它永遠沒有辦法走到特別低的地方,可能永遠在這個“山谷”的口上振蕩而無法走下去 + 如果learning rate非常大,就會像下圖中的黃色線段,一瞬間就飛出去了,結果會造成update參數以後,loss反而會越來越大(這一點在上次的demo中有體會到,當lr過大的時候,每次更新loss反而會變大) ![](https://i.imgur.com/8UgYtGC.png) 當參數有很多個的時候(>3),其實我們很難做到將loss隨每個參數的變化可視化出來(因為最多只能可視化出三維的圖像,也就只能可視化三維參數),但是我們可以把update的次數作為唯一的一個參數,將loss隨著update的增加而變化的趨勢給可視化出來(上圖右半部分) 所以做gradient descent一個很重要的事情是,++要把不同的learning rate下,loss隨update次數的變化曲線給可視化出來++,它可以提醒你該如何調整當前的learning rate的大小,直到出現穩定下降的曲線 ## **Adaptive Learning rates** 顯然這樣手動地去調整learning rates很麻煩,因此我們需要有一些自動調整learning rates的方法 最基本、最簡單的大原則是:**learning rate通常是隨著參數的update越來越小的** 因為在起始點的時候,通常是離最低點是比較遠的,這時候步伐就要跨大一點;而經過幾次update以後,會比較靠近目標,這時候就應該減小learning rate,讓它能夠收斂在最低點的地方 舉例:假設到了第t次update,此時![](https://i.imgur.com/39YAfYS.png) 這種方法使所有參數以同樣的方式同樣的learning rate進行update,而最好的狀況是每個參數都給他不同的learning rate去update ### **Adagrad** > Divide the learning rate of each parameter by the root mean square(方均根) of its previous derivatives Adagrad就是將不同參數的learning rate分開考慮的一種算法(adagrad算法update到後面速度會越來越慢,當然這只是adaptive算法中最簡單的一種) ![](https://i.imgur.com/pQFhOew.png) 這里的w是function中的某個參數,t表示第t次update,$g^t$表示Loss對w的偏微分,而$σ^t$是之前所有Loss對w偏微分的方均根(根號下的平方均值),這個值對每一個參數來說都是不一樣的 ![](https://i.imgur.com/vnf0WeQ.png) 由於$η^t$和$σ^t$中都有一個![](https://i.imgur.com/4JbPWwC.png)的因子,兩者相消,即可得到adagrad的最終表達式(分母少了根號): ![](https://i.imgur.com/WjbMcwe.png) #### **Adagrad的contradiction解釋** Adagrad的表達式![](https://i.imgur.com/W4EgJdz.png)裡面有一件很矛盾的事情: 我們在做gradient descent的時候,希望的是當梯度值即微分值$g^t$越大的時候(此時斜率越大,還沒有接近最低點)更新的步伐要更大一些,但是Adagrad的表達式中,分母表示梯度越大步伐越小,分子卻表示梯度越大步伐越大,兩者似乎相互矛盾 ![](https://i.imgur.com/11gLOrD.png) 在一些paper里是這樣解釋的:Adagrad要考慮的是,這個gradient有多surprise,即反差有多大,假設t=4的時候$g^4$與前面的gradient反差特別大,那麽$g^t$與![](https://i.imgur.com/ds5lLtS.png)之間的大小反差就會比較大,它們的商就會把這一反差效果體現出來 ![](https://i.imgur.com/GoKcBil.png) #### **gradient越大,離最低點越遠這件事情在有多個參數的情況下是不一定成立的** 如下圖所示,w1和w2分別是loss function的兩個參數,loss的值投影到該平面中以顏色深度表示大小,分別在w2和w1處垂直切一刀(這樣就只有另一個參數的gradient會變化),對應的情況為右邊的兩條曲線,可以看出,比起a點,c點距離最低點更近,但是它的gradient卻越大 ![](https://i.imgur.com/rgmXOPD.png) 實際上,對於一個二次函數![](https://i.imgur.com/VSyCsAU.png)來說,最小值點的![](https://i.imgur.com/9yXHw0x.png),而對於任意一點x~0~,它邁出最好的步伐長度是![](https://i.imgur.com/fXpEheD.png)(這樣就一步邁到最小值點了),聯系該函數的一階和二階導數![](https://i.imgur.com/bnLKbDA.png)、![](https://i.imgur.com/a8o7qB7.png),可以發現the best step is ![](https://i.imgur.com/RLPdgUO.png),也就是說他不僅跟一階導數(gradient)有關,還跟二階導數有關,因此我們可以通過這種方法重新比較上面的a和c點,就可以得到比較正確的答案 再來回顧Adagrad的表達式:![](https://i.imgur.com/a03ASIG.png) $g^t$就是一次微分,而分母中的![](https://i.imgur.com/wIRNeR3.png)反映了二次微分的大小,所以Adagrad想要做的事情就是,++在不增加任何額外運算的前提下,想辦法去估測二次微分的值++ ![](https://i.imgur.com/XhB6hKN.png) ### Stochastic Gradicent Descent 隨機梯度下降的方法可以讓訓練更快速,傳統的gradient descent的思路是看完所有的樣本點之後再構建loss function,然後去update參數;而stochastic gradient descent的做法是,看到一個樣本點就update一次(batch_size=1),因此它的loss function不是所有樣本點的error平方和,而是這個隨機樣本點的error平方 ![](https://i.imgur.com/7Q4mxKw.png) stochastic gradient descent與傳統gradient descent的效果對比如下: ![](https://i.imgur.com/pxulM5N.png) ### Feature Scaling 特征縮放,當多個特征的分布範圍很不一樣時,最好將這些不同feature的範圍縮放成一樣 ![](https://i.imgur.com/4klWYWQ.png) **原理解釋** ![](https://i.imgur.com/kn9RNTd.png),假設x1的值都是很小的,比如1,2...;x2的值都是很大的,比如100,200... 此時去畫出loss的error surface,如果對w1和w2都做一個同樣的變動$Δw$,那麽w1的變化對y的影響是比較小的,而w2的變化對y的影響是比較大的 ![](https://i.imgur.com/CK5CdIU.png) 左邊的error surface表示,w1對y的影響比較小,所以w1對loss是有比較小的偏微分的,因此在w1的方向上圖像是比較平滑的;w2對y的影響比較大,所以w2對loss的影響比較大,因此在w2的方向上圖像是比較sharp的 如果x1和x2的值,它們的scale是接近的,那麽w1和w2對loss就會有差不多的影響力,loss的圖像接近於圓形,那這樣做對gradient descent有什麽好處呢? #### **對gradient decent的幫助** 之前我們做的demo已經表明了,對於這種長橢圓形的error surface,如果不使用Adagrad之類的方法,是很難搞定它的,因為在像w1和w2這樣不同的參數方向上,會需要不同的learning rate,用相同的lr很難達到最低點 如果有scale的話,loss在參數w1、w2平面上的投影就是一個正圓形,update參數會比較容易 而且gradient descent的每次update並不都是向著最低點走的,每次update的方向是順著等高線的方向(梯度gradient下降的方向),而不是徑直走向最低點;但是當經過對input的scale使loss的投影是一個正圓的話,不管在這個區域的哪一個點,它都會向著圓心走。因此feature scaling對參數update的效率是有幫助的 #### **如何做feature scaling** 假設有R個example(上標i表示第i個樣本點),![](https://i.imgur.com/Fpd3ykR.png),每一筆example,它里面都有一組feature(下標j表示該樣本點的第j個特征) 對每一個demension i,都去算出它的平均值mean=m~i~,以及標準差standard deviation=σ~i~ 對第r個example的第i個component,減掉均值,除以標準差,即![](https://i.imgur.com/bsHGSqR.png) ![](https://i.imgur.com/UMz267v.png) 實際上就是++將每一個參數都歸一化(標準化)成標準常態分布++(Gaussian distribution),即![](https://i.imgur.com/N32u6cq.png),其中x~i~表示第i個參數 ## **Gradient Descent的理論基礎** ### Taylor Series 泰勒表達式:![](https://i.imgur.com/WTNEfGR.png) When x is close to x~0~ : ![](https://i.imgur.com/1GGcyxD.png) 同理,對於二元函數,when x and y is close to x~0~ and y~0~: ![](https://i.imgur.com/718GsUS.png) ### **從泰勒展開式推導出gradient descent** 對於loss圖像上的某一個點(a,b),如果我們想要找這個點附近loss最小的點,就可以用泰勒展開的思想 ![](https://i.imgur.com/MCaXjve.png) 假設用一個red circle限定點的範圍,這個圓足夠小以滿足泰勒展開的精度,那麽此時我們的loss function就可以化簡為: ![](https://i.imgur.com/SLa5MRx.png) 令$s=L(a,b)$,![](https://i.imgur.com/qcsf1xX.png) 則![](https://i.imgur.com/MwMkfOW.png) 假定red circle的半徑為d,則有限制條件:![](https://i.imgur.com/iiSFRWd.png) 此時去求![](https://i.imgur.com/4e4akte.png),這裡有個小技巧,把$L(θ)$轉化為兩個向量的乘積(內積): ![](https://i.imgur.com/ycKQYC5.png) 觀察圖形可知,當向量![](https://i.imgur.com/wiIrkpo.png)與向量$(u,v)$反向,且剛好到達red circle的邊緣時(用$η$去控制向量的長度),$L(θ)$最小 ![](https://i.imgur.com/83QQzko.png) ![](https://i.imgur.com/OxJ7g4l.png)實際上就是![](https://i.imgur.com/JdpXkhi.png),於是$L(θ)$局部最小值對應的參數為中心點減去gradient的加權 ![](https://i.imgur.com/W4T0fLp.png) 這就是gradient descent在數學上的推導,注意它的重要前提是,給定的那個紅色圈圈的範圍要足夠小,這樣泰勒展開給我們的近似才會更精確,而$η$的值是與圓的半徑成正比的,因此理論上learning rate要無窮小才能夠保證每次gradient descent在update參數之後的loss會越來越小,於是當learning rate沒有設置好,泰勒近似不成立,就有可能使gradient descent過程中的loss沒有越來越小 當然泰勒展開可以使用二階、三階乃至更高階的展開,但這樣會使得運算量大大增加,反而降低了運行效率 ## **Gradient Descent的限制** 之前已經討論過,gradient descent有一個問題是它會停在local minima的地方就停止update了 事實上還有一個問題是,微分值是0的地方並不是只有local minima,saddle point(鞍點)的微分值也是0 以上都是理論上的探討,到了實踐的時候,其實當gradient的值接近於0的時候,我們就已經把它停下來了,但是微分值很小,不見得就是很接近local minima,也有可能像下圖一樣在一個高原的地方 ![](https://i.imgur.com/RoqOofN.png) 綜上,gradient descent的限制是,它在gradient即微分值接近於0的地方就會停下來,而這個地方不一定是global minima,它可能是local minima,可能是saddle point鞍點,甚至可能是一個loss很高的plateau平緩高原