步長與學習率

轉載自https://www.2cto.com/kf/201607/526447.htmlhtml

本章總結優化學習率的知識,而前置知識就是「線性迴歸、梯度降低算法」,所以若是這一章你看的雲裏霧裏甚至連學習率是什麼都不知道的話就須要先吧前置知識搞定了。算法

其餘說明

由於本總結的前置知識是「線性迴歸、梯度降低算法」,因此以後的內容都是以「求目標函數f(x)的極小值」爲目的。函數

不過不用擔憂求極大值的話該怎麼辦,由於直接給f(x)加個負號就將問題轉換爲了求極小值問題了。學習

在順便一提,我的感受正由於研究了這麼多求極小值的東西,因而大夥爲了省事,就凡是遇到求極大值的問題則先將其轉成求極小值,因而乎會常常看到這句話「習慣上咱們將其轉換成求極小值」....優化

什麼是優化學習率

以梯度降低說明。spa

假設我將學習率固定爲1時須要迭代10次纔會收斂的話,那若是我將學習率改成第一次步長爲8,第二次步長爲2,則可能兩次就收斂了。(這裏的數字不太準確,但大概是這樣的意思)htm

很明顯,後者的收斂速度更快,而上面對學習率的調整就是優化學習率。blog

PS:就好像一我的下山,若是他以每步1M步伐下山可能要走10小時,那若他一開始以每步8M,而後等走了一半多了在每步2M的話,則到達山腳的時間會明顯縮短。ci

話說,雖然在寫這片文章時我還沒入這一行,但我聽到的都是些「工做時不少時候就拍腦門選一個學習率就好,若感受收斂太慢就調大些」這樣的內容,感受不必在這上面花費太多功夫。table

不過我的感受,若是能把這個知識掌握了,那工做起來會事半功倍。

怎麼優化學習率

這個得一點點講了。

既然咱們的目標是優化學習率,那咱們須要先轉換下視角:你看啊,對於某個函數,若是咱們的目標就是求函數中的參數x,那咱們就將函數當作是關於x的函數。同理,既然這裏的目標是函數中的學習率α,那咱們就將函數看做是關於α的函數。又由於通常函數模型是:f(xk+αdk),其中dk是搜索方向(如對梯度降低來講,dk是負梯度方向),因此在轉換視角後,咱們將其看做是關於α的函數h(α),即:

h(α)= f(xk+αdk)

PS:通常學習率是大於0的,即α>0

既然已是關於α的函數了,那對於梯度降低來講咱們的目標就從「x爲多少時函數的值最小 -- 注:樣本xk是已知的,當前的搜索方向dk即梯度也能夠求出來,只不過哪一個xk會使函數最小不知道」,即:

arg_xmin f(xk+αdk)

變成了「在給定xk和dk的前提下,尋找α爲多少時,能讓函數降低的最快」,即:求對關於α的函數h(α)求「α = ? 時,函數h(α)最小」。

這就簡單了,對h(α)求導並另導數爲0唄,即:

h’(α)= ▽f(xk+αdk)Tdk= 0

這樣求得的α就是一個對當前xk的一個十分優秀的學習率α。

畫個圖的話就像這樣:

之前學習率固定時,可能每次只降低這麼多:

\

經過上面的方法就能一次性降低這麼多(粉線是切線)

\

不過,若是你細心的話如今應該有點繞,即:h(α) 不就是 f(xk+αdk) 嗎?那我對h(α) 求導後找到個最小值不就是f(xk+αdk)的最小值嗎?按照這裏理論,我不就一次性讓函數收斂了?怎麼上面的圖尚未一次性收斂?你畫錯了吧!

嘛,上面的圖的確有些不許確,是幫助理解而已,所以我要補充下面這句話:對h(α)求導並讓導數爲0後能夠獲得一個對當前xk的十分優秀的學習率α,但這個α可能並不能讓原函數一次性收斂。

緣由是:咱們以前經過「視角轉換」將函數變成了關於α的函數h(α),因此若是畫座標軸的話,那座標軸的x軸就變成了α軸,即:函數圖像會變成關於α的圖像(這和原函數的圖像是不一樣的)。因而對h(α)求導並讓導數爲0後能夠得出一個關於α的圖像的極小值點,這時就獲得了一個「對當前xk的一個十分優秀的學習率α」,但由於「關於α的圖像和原函數的關於x的圖像是兩個圖像」,因此這個α可能並不能讓原函數一次性收斂。

不過,雖然不能讓原函數一次性收斂,但不管如何,也比固定α好,對吧。

如今總結下上面的步驟:

一、使用原函數對α求導,求出學習率α;

二、按照搜索方向更新函數(如梯度降低)

三、重複上面兩步直到收斂。

一個更簡單的方法(二分線性搜索)

說實話啊,雖然上面的步驟沒問題,但若是計算h’(α)=0十分噁心咋辦?

難道(╯‵□′)╯︵┻━┻不求了?

固然能夠!

且聽我一一道來。

首先,對於f(xk+αdk),若是令α = 0的話就有:

h’(0)= ▽f(xk +0*dk)Tdk = ▽f(xk)Tdk

上面的▽f(xk)是梯度(這是對原函數求導啊),dk是搜索方向,若是令dk爲負梯度方向即:dk = -▽f(xk) 的話,就有:h’(0) < 0,即α = 0時,h’(0) < 0。

這時若是咱們找到一個足夠大的α,使得h’(α)>0的話,則必存在某α,可使h’(α)=0,而這個α就是咱們要尋找的學習率。

於!是!使用折半查找就OK了!如:

對於h’(α1)< 0、h’(α2) > 0

若h’( (α12)/2 ) < 0,那就另a1 = (α12)/2

若h’( (α12)/2 ) > 0,那就另a2 = (α12)/2

重複上面的步驟,直到找到h’(α)=0,這樣就找到了α。

再優化一下(回溯線性搜索)

上面的折半查找已經很方便了,但以h’(α)=0做爲是否找到α的條件還有些麻煩,而使用回溯線性搜索的Arimijo準則做爲判斷條件就很方便了。

首先是Armijo準則:首先給一個較大的學習率,而後不斷縮減學習率,若是對於函數f(xk+αdk)當前的學習率使函數從當前的位置f(xk)的減少必定程度後還大於預設的指望值,那這個學習率就符合要求了

什麼意思?你看,對於函數f(xk+αdk),既然是求最小值,那對於當前的值f(xk)減少必定程度後就有個新值f(xk+1),因而,若是咱們將f(xk+1)做爲預設的指望值,即咱們但願f(xk)在某個學習率α的狀況下減少必定程度後能夠到達f(xk+1),那這個α就是咱們但願獲得的α了對吧。而由於 這個減少程度在Armijo準則中是公式:

c1α▽f(xk)Tdk,c1∈(0, 1)

由於dk通常取梯度負方向,因此用式子表達上面的話的話就是:

f(xk+1)= f(xk) + c1α▽f(xk)Tdk,c1∈(0, 1)

可是在計算中實現上面的等號挺麻煩的,由於咱們是不斷縮減學習率,只要咱們縮減的程度沒把握好,就會有「上一個還f(xk+1) < f(xk) + c1α▽f(xk)Tdk,下一個就f(xk+1) > f(xk) +c1α▽f(xk)Tdk」的狀況。

因而爲了方便,只要f(xk+1) ≤ f(xk) + c1α▽f(xk)Tdk就OK了,而這就是Armijo準則的方程

PS:爲何要給一個較大的學習率後還不停的縮減?直接選這個較大的學習率不就行了?

看下圖:

\

若是學習率太大一會兒從x1走到了x2的話,那還求個屁的最小值啊。

因而咱們就先規定個指望值,好比:你此次降低到f(x3)就好了。這樣就能控制學習率爲一個咱們指望的值了。

 

回溯與二分線性搜索的異同

二分線性搜索的目標是求得知足h’(α)≈0的最優步長近似值,而回溯線性搜索放鬆了對步長的約束,只要步長能使函數值有足夠大的變化便可。

 二分線性搜索能夠減小降低次數,但在計算最優步長上花費了很多代價;回溯線性搜索找到一個差很少的步長便可。

回溯線性搜索代碼(出自小象學院的鄒博老師)

\

紅框:若傳來的學習率a不知足h’(a) > 0就將a擴大2倍,所以到達綠色框的代碼時a已經知足h’(a) > 0。或者說紅框中是爲了找到「第一個」不知足函數降低的學習率。正常狀況下,只要沿着負梯度方向降低微小的值,next<now是恆成立的,所以,不斷執行紅框的代碼,能夠不斷擡高學習率,直到發現不知足條件的(即:「步子太大」),從而保證接下來綠框中的有效執行。< p="">

綠框: 若是學習率不知足Armijo準則,就把學習率a降一半,看看新的學習率是否知足。

最後返回學習率。

回溯線性搜索的改進-二次插值法

怎麼還沒完啊?

我也這樣想過,但改進是永無止境的,認命吧- -....

不過在介紹插值法以前還得再說個很簡單的預備知識,以下:

若是知道3個點,那就能夠肯定一個二次曲線通過這三個已知點,換句話說爲了肯定一個二次曲線就須要3個類型的信息,所以咱們就能夠這樣想:若是題目給定了在一個點x1處的函數值y1=f(x1)、在該點處的切線值即x1處的導數值f’(x1)、x2點處的函數值y2=f(x2),那麼也是能惟一的肯定一個二次函數,看下圖:

\

而若是x1=0,x2=a的話,那這個二次函數的方程就是下面的樣子:

\

PS:這個是這樣算出來的: 假設這個二次函數的方程是 f(x) = px2 + qx + z,由於f(0)、f’(0)、f(a)是已知的,f’(x)的能夠求出來,即f’(x) = 2px + q,那把這三個值代入f(x)和f’(x)就能夠把p、q、z求出來了,就得出上面的式子了。

對這個式子求極值的方法是:

假設式子爲:h(a) = qx2 + px + z

則x在 - p/(2q) 處能夠取得極值

這是初中的知識,因此別問爲何,像初中生同樣直接拿去用就好。

好了預備知識說完了,下面介紹插值法。

通過前面的內容已經知道:咱們找學習率a的方法是,找一個h’(a) < 0,一個h’(a) > 0,而後不停的二分查找,直到h’(a) = 0。

那有沒有一個更好的方法?有的。

首先,對於學習率a,其函數h(a)是一個二次函數。

PS:一個a代入h(a)有一個值,最後就是在以a爲橫軸h(a)爲縱軸的座標軸上畫了一條彎曲的曲線,這是個二次曲線沒問題吧

而後對於這個二次函數咱們總結下已知的信息:

1,h(a)必定通過兩個點:a=0處的值h(0)、當前的準備嘗試的學習率a0的值h(a0)。其中h(0)就是當前的函數值f(xk),由於對於h(α) = f(xk+αdk),若是a=0,就有h(0) = f(xk);而當前準備嘗試的學習率若是知足Armijo準則就直接返回該學習率,不然才須要找個更好的學習率。

2,當前xk處的的導數能夠求出來,即f’(xk)已知,也就是h’(0)已知。

即 :已知h(0)、h’(0)、h(a0)

接下來利用剛纔的預備知識,咱們就能夠構造出一個二次函數來近似學習率a的曲線了,即:

\

PS:這個只是近似,由於只是經過3個數據來肯定的曲線,和真正的h(a)是有些不一樣的,不過,雖然這條曲線和真正的曲線有些偏差,但可使用,這就足夠了。

而咱們的目標是什麼來着?對,求h’(a)=0時的a,也就是求h(a)的極值,那就直接利用初中的知識

\式1

求hq(a)的極值就OK了,這多簡單,初中生都會。

過程總結

1,利用式1求a1

2,若a1知足Armijo準則,則輸出該學習率,不然繼續迭代。

代碼(出自小象學院的鄒博老師)

\

最後總結

通常的說,回溯線性搜索和二次插值線性搜索可以基本知足實踐中的須要。

相關文章
相關標籤/搜索