① 優化演算法筆記(一)優化演算法的介紹
(以下描述,均不是學術用語,僅供大家快樂的閱讀)
我們常見常用的演算法有排序演算法,字元串遍歷演算法,尋路演算法等。這些演算法都是為了解決特定的問題而被提出。
演算法本質是一種按照固定步驟執行的過程。
優化演算法也是這樣一種過程,是一種根據概率按照固定步驟尋求問題的最優解的過程。與常見的排序演算法、尋路演算法不同的是,優化演算法不具備等冪性,是一種 概率演算法 。演算法不斷的 迭代 執行同一步驟直到結束,其流程如下圖。
等冪性即 對於同樣的輸入,輸出是相同的 。
比如圖1,對於給定的魚和給定的熊掌,我們在相同的條件下一定可以知道它們誰更重,當然,相同的條件是指魚和熊掌處於相同的重力作用下,且不用考慮水分流失的影響。在這些給定的條件下,我們(無論是誰)都將得出相同的結論,魚更重或者熊掌更重。我們可以認為,秤是一個等冪性的演算法(工具)。
現在把問題變一變,問魚與熊掌你更愛哪個,那麼現在,這個問題,每個人的答案可能不會一樣,魚與熊掌各有所愛。說明喜愛這個演算法不是一個等冪性演算法。當然你可能會問,哪個更重,和更喜歡哪個這兩個問題一個是客觀問題,一個是主觀問題,主觀問題沒有確切的答案的。當我們處理主觀問題時,也會將其轉換成客觀問題,比如給喜歡魚和喜歡熊掌的程度打個分,再去尋求答案,畢竟計算機沒有感情,只認0和1(量子計算機我不認識你)。
說完了等冪性,再來說什麼是概率演算法。簡單來說就是看臉、看人品、看運氣的演算法。
有一場考試,考試的內容全部取自課本,同時老師根據自己的經驗給同學們劃了重點,但是因為試卷並不是該老師所出,也會有考試內容不在重點之內,老師估計試卷中至少80%內容都在重點中。學霸和學渣參加了考試,學霸為了考滿分所以無視重點,學渣為了pass,因此只看了重點。這樣做的結果一定是score(學霸)>=score(學渣)。
當重點跟上圖一樣的時候,所有的內容都是重點的時候,學霸和學渣的學習策略變成了相同的策略,則score(學霸)=score(學渣)。但同時,學渣也要付出跟學霸相同的努力去學習這些內容,學渣心裡苦啊。
當課本如下圖時
學霸?學霸人呢,哪去了快來學習啊,不是說學習一時爽,一直學習一直爽嗎,快來啊,還等什麼。
這時,如果重點內容遠少於書本內容時,學渣的學習策略有了優勢——花費的時間和精力較少。但是同時,學渣的分數也是一個未知數,可能得到80分也可能拿到100分,分數完全取決於重點內容與題目的契合度,契合度越高,分數越高。對學渣來說,自己具體能考多少分無法由自己決定,但是好在能夠知道大概的分數范圍。
學霸的學習策略是一種遍歷性演算法,他會遍歷、通讀全部內容,以保證滿分。
學渣的學習策略則是一種概率演算法,他只會遍歷、學習重點內容,但至於這些重點是不是真重點他也不知道。
與遍歷演算法相比,概率演算法的結果具有不確定性,可能很好,也可能很差,但是會消耗更少的資源,比如時間(人生),空間(記憶)。概率演算法的最大優點就是 花費較少的代價來獲取最高的收益 ,在現實中體現於節省時間,使用很少的時間得到一個不與最優解相差較多的結果。
「莊子:吾生也有涯,而知也無涯;以有涯隨無涯,殆矣。」的意思是:人生是有限的,但知識是無限的(沒有邊界的),用有限的人生追求無限的知識,是必然失敗的。
生活中概率演算法(思想)的應用其實比較廣泛,只是我們很少去注意罷了。關於概率演算法還衍生出了一些有趣的理論,比如墨菲定律和倖存者偏差,此處不再詳述。
上面說到,優化演算法就是不停的執行同樣的策略、步驟直到結束。為什麼要這樣呢?因為優化演算法是一種概率演算法,執行一次操作就得到最優結果幾乎是不可能的,重復多次取得最優的概率也會增大。
栗子又來了,要從1-10這10個數中取出一個大於9的數,只取1次,達到要求的概率為10%,取2次,達到要求的概率為19%。
可以看出取到第10次時,達到要求的概率幾乎65%,取到100次時,達到要求的概率能接近100%。優化演算法就是這樣簡單粗暴的來求解問題的嗎?非也,這並不是一個恰當的例子,因為每次取數的操作之間是相互獨立的,第2次取數的結果不受第1次取數結果的影響,假設前99次都沒達到要求,那麼再取一次達到要求的概率跟取一次達到要求的概率相同。
優化演算法中,後一次的計算會依賴前一次的結果,以保證後一次的結果不會差於前一次的結果。這就不得不談到馬爾可夫鏈了。
由鐵組成的鏈叫做鐵鏈,同理可得,馬爾可夫鏈就是馬爾可夫組成的鏈。
言歸正傳, 馬爾可夫鏈(Markov Chain, MC) ,描述的是 狀態轉移的過程中,當前狀態轉移的概率只取決於上一步的狀態,與其他步的狀態無關 。簡單來說就是當前的結果只受上一步的結果的影響。每當我看到馬爾可夫鏈時,我都會陷入沉思,生活中、或者歷史中有太多太多與馬爾可夫鏈相似的東西。西歐封建等級制度中「附庸的附庸不是我的附庸」與「昨天的努力決定今天的生活,今天的努力決定明天的生活」,你的下一份工作的工資大多由你當前的工資決定,這些都與馬爾可夫鏈有異曲同工之處。
還是從1-10這10個數中取出一個大於9的數的這個例子。基於馬爾可夫鏈的概率演算法在取數時需要使當前取的數不小於上一次取的數。比如上次取到了3,那麼下次只能在3-10這幾個數中取,這樣一來,達到目標的概率應該會顯著提升。還是用數據說話。
取1次達到要求的概率仍然是
取2次內達到要求的概率為
取3次內達到要求的概率為
取4次內……太麻煩了算了不算了
可以看出基於馬爾可夫鏈來取數時,3次內能達到要求的概率與不用馬爾可夫鏈時取6次的概率相當。說明基於馬爾可夫鏈的概率演算法求解效率明顯高於隨機概率演算法。那為什麼不將所有的演算法都基於馬爾可夫鏈呢?原因一,其實現方式不是那麼簡單,例子中我們規定了取數的規則是復合馬爾可夫鏈的,而在其他問題中我們需要建立適當的復合馬爾科夫鏈的模型才能使用。原因二,並不是所有的問題都符合馬爾科夫鏈條件,比如原子內電子出現的位置,女朋友為什麼會生(lou)氣,彩票號碼的規律等,建立模型必須與問題有相似之處才能較好的解決問題。
介紹完了優化演算法,再來討論討論優化演算法的使用場景。
前面說了優化演算法是一種概率演算法,無法保證一定能得到最優解,故如果要求結果必須是確定、穩定的值,則無法使用優化演算法求解。
例1,求城市a與城市b間的最短路線。如果結果用來修建高速、高鐵,那麼其結果必定是唯一確定的值,因為修路寸土寸金,必須選取最優解使花費最少。但如果結果是用來趕路,那麼即使沒有選到最優的路線,我們可能也不會有太大的損失。
例2,求城市a與城市b間的最短路線,即使有兩條路徑,路徑1和路徑2,它們從a到b的距離相同,我們也可以得出這兩條路徑均為滿足條件的解。現在將問題改一下,求城市a到城市b耗時最少的線路。現在我們無法馬上得出確切的答案,因為最短的線路可能並不是最快的路線,還需要考慮到天氣,交通路況等因素,該問題的結果是一個動態的結果,不同的時間不同的天氣我們很可能得出不同的結果。
現實生產、生活中,也有不少的場景使用的優化演算法。例如我們的使用的美圖軟體,停車場車牌識別,人臉識別等,其底層參數可能使用了優化演算法來加速參數計算,其參數的細微差別對結果的影響不太大,需要較快的得出誤差范圍內的參數即可;電商的推薦系統等也使用了優化演算法來加速參數的訓練和收斂,我們會發現每次刷新時,推給我們的商品都有幾個會發生變化,而且隨著我們對商品的瀏覽,系統推給我們的商品也會發生變化,其結果是動態變化的;打車軟體的訂單系統,會根據司機和客人的位置,區域等來派發司機給客人,不同的區域,不同的路況,派發的司機也是動態變化的。
綜上我們可以大致總結一下推薦、不推薦使用優化演算法的場景的特點。
前面說過,優化演算法處理的問題都是客觀的問題,如果遇到主觀的問題,比如「我孰與城北徐公美」,我們需要將這個問題進行量化而轉換成客觀的問題,如身高——「修八尺有餘」,「外貌——形貌昳麗」,自信度——「明日徐公來,孰視之,自以為不如;窺鏡而自視,又弗如遠甚」,轉化成客觀問題後我們可以得到各個解的分數,通過比較分數,我們就能知道如何取捨如何優化。這個轉化過程叫做問題的建模過程,建立的問題模型實際上是一個函數,這個函數對優化演算法來說是一個黑盒函數,即不需要知道其內部實現只需要給出輸入,得到輸出。
在優化演算法中這個黑盒函數叫做 適應度函數 , 優化演算法的求解過程就是尋找適應度函數最優解的過程 ,使用優化演算法時我們最大的挑戰就是如何將抽象的問題建立成具體的模型,一旦合適的模型建立完成,我們就可以愉快的使用優化演算法來求解問題啦。(「合適」二字談何容易)
優化演算法的大致介紹到此結束,後面我們會依次介紹常見、經典的優化演算法,並探究其參數對演算法性能的影響。
——2019.06.20
[目錄]
[下一篇 優化演算法筆記(二)優化演算法的分類]
② 優化演算法總結
本文介紹一下機器學習和深度學習中常用的優化演算法和優化器以及一些其他我知道的優化演算法,部分演算法我也沒有搞懂,就先記錄下來以後慢慢研究吧.*_*.
1.梯度下降演算法(Gradient Descent)
梯度下降法可以參考我另一篇文章 機器學習-線性回歸 里的講解,這里就不在重復敘述.這里需要強調一下,深度學習里常用的SGD,翻譯過來是隨機梯度下降,但是實質是mini-batch梯度下降(mini-batch-gd),或者說是兩者的結合更准確一些.
SGD的優點是,演算法簡單,計算量小,在函數為凸函數時可以找到全局最優解.所以是最常用的優化演算法.缺點是如果函數不是凸函數的話,很容易進入到局部最優解而無法跳出來.同時SGD在選擇學習率上也是比較困難的.
2.牛頓法
牛頓法和擬牛頓法都是求解無約束最優化問題的常用方法,其中牛頓法是迭代演算法,每一步需要求解目標函數的海森矩陣的逆矩陣,計算比較復雜.
牛頓法在求解方程根的思想:在二維情況下,迭代的尋找某一點x,尋找方法是隨機一個初始點x_0,目標函數在該點x_0的切線與x坐標軸的交點就是下一個x點,也就是x_1.不斷迭代尋找x.其中切線的斜率為目標函數在點x_0的導數(梯度),切必過點(x_0,f(x_0)).所以迭代的方程式如圖1,為了求該方程的極值點,還需要令其導數等於0,也就是又求了一次導數,所以需要用到f(x)的二階導數.
在最優化的問題中,牛頓法提供了一種求解的辦法. 假設任務是優化一個目標函數f, 求函數ff的極大極小問題, 可以轉化為求解函數f導數等於0的問題, 這樣求可以把優化問題看成方程求解問題(f的導數等於0). 剩下的問題就和牛頓法求解方程根的思想很相似了.
目標函數的泰勒展開式:
化簡後:
這樣就得到了與圖1相似的公式,這里是二維的,在多維空間上,求二階導數就是求海森矩陣,因為是分母,所以還需要求海森矩陣的逆矩陣.
牛頓法和SGD的區別:
牛頓法是二階求導,SGD是一階求導,所以牛頓法要收斂的更快一些.SGD只考慮當前情況下梯度下降最快的方向,而牛頓法不僅考慮當前梯度下降最快,還有考慮下一步下降最快的方向.
牛頓法的優點是二階求導下降速度快,但是因為是迭代演算法,每一步都需要求解海森矩陣的逆矩陣,所以計算復雜.
3.擬牛頓法(沒搞懂,待定)
考慮到牛頓法計算海森矩陣比較麻煩,所以它使用正定矩陣來代替海森矩陣的逆矩陣,從而簡化了計算過程.
常用的擬牛頓法有DFP演算法和BFGS演算法.
4.共軛梯度法(Conjugate Gradient)
共軛梯度法是介於最速下降法與牛頓法之間的一個方法,它僅需利用一階導數信息,但克服了最速下降法收斂慢的缺點,又避免了牛頓法計算海森矩陣並求逆的缺點.共軛梯度法不僅是解決大型線性方程組最有用的方法之一,也是解大型非線性最優化最有效的演算法之一.
5.拉格朗日法
參考SVM里的講解 機器學習-SVM
6.動量優化法(Momentum)
動量優化法主要是在SGD的基礎上,加入了歷史的梯度更新信息或者說是加入了速度更新.SGD雖然是很流行的優化演算法,但是其學習過程很慢,因為總是以同樣的步長沿著梯度下降的方向.所以動量是為了加速學習的方法.
其中第一行的減號部分是計算當前的梯度,第一行是根據梯度更新速度v,而α是新引進的參數,在實踐中,α的一般取值為 0.5,0.9 和 0.99.和學習率 一樣,α 也會隨著時間不斷調整.一般初始值是一個較小的值,隨後會慢慢變大.
7.Nesterov加速梯度(NAG, Nesterov accelerated gradient)
NAG是在動量優化演算法的基礎上又進行了改進.根據下圖可以看出,Nesterov 動量和標准動量之間的區別體現在梯度計算上, Nesterov 動量中,梯度計算在施加當前速度之後.因此,Nesterov 動量可以解釋為往標准動量方法中添加了一個校正因子
8.AdaGrad演算法
AdaGrad演算法,自適應優化演算法的一種,獨立地適應所有模型參數的學習率,縮放每個參數反比於其所有梯度歷史平均值總和的平方根.具有代價函數最大梯度的參數相應地有個快速下降的學習率,而具有小梯度的參數在學習率上有相對較小的下降.通俗一點的講,就是根據實際情況更改學習率,比如模型快要收斂的時候,學習率步長就會小一點,防止跳出最優解.
其中g是梯度,第一行的分母是計算累計梯度的平方根, 是為了防止分母為0加上的極小常數項,α是學習率.
Adagrad的主要優點是不需要人為的調節學習率,它可以自動調節.但是依然需要設置一個初始的全局學習率.缺點是隨著迭代次數增多,學習率會越來越小,最終會趨近於0.
9.RMSProp演算法
RMSProp修改 AdaGrad 以在非凸設定下效果更好,改變梯度積累為指數加權的移動平均.AdaGrad旨在應用於凸問題時快速收斂.
10.AdaDelta演算法
11.Adam演算法
Adam是Momentum和RMSprop的結合體,也就是帶動量的自適應優化演算法.
12.Nadam演算法
13.模擬退火演算法
14.蟻群演算法
15.遺傳演算法
動量是為了加快學習速度,而自適應是為了加快收斂速度,注意學習速度快不一定收斂速度就快,比如步長大學習速度快,但是很容易跳出極值點,在極值點附近波動,很難達到收斂.
未完待定....
參考:
《統計學習方法》 李航 著
《深度學習》 花書