【机器学习基础】优化算法详解
本文來源于吳恩達老師的深度學習課程[1]和深度學習課程[2]筆記部分。
作者:黃海廣[3]
備注:筆記和作業(含數據、原始作業文件)、視頻都在?github[4]中下載。
導語
在學習機器學習的過程中我們發現,大部分的機器學習算法的本質都是建立優化模型,通過最優化方法對目標函數(或損失函數)進行優化,從而訓練出最好的模型,梯度下降是最基本的優化算法。本文對梯度下降和其他優化算法進行講解。
一 梯度下降(Gradient Descent)
1.1 梯度下降概述
梯度下降是一個用來求函數最小值的算法,我們將使用梯度下降算法來求出代價函數?的最小值。
梯度下降背后的思想是:開始時我們隨機選擇一個參數的組合,計算代價函數,然后我們尋找下一個能讓代價函數值下降最多的參數組合。我們持續這么做直到找到一個局部最小值(local minimum),因為我們并沒有嘗試完所有的參數組合,所以不能確定我們得到的局部最小值是否便是全局最小值(global minimum),選擇不同的初始參數組合,可能會找到不同的局部最小值。
想象一下你正站立在山的這一點上,站立在你想象的公園這座紅色山上,在梯度下降算法中,我們要做的就是旋轉360度,看看我們的周圍,并問自己要在某個方向上,用小碎步盡快下山。這些小碎步需要朝什么方向?如果我們站在山坡上的這一點,你看一下周圍,你會發現最佳的下山方向,你再看看周圍,然后再一次想想,我應該從什么方向邁著小碎步下山?然后你按照自己的判斷又邁出一步,重復上面的步驟,從這個新的點,你環顧四周,并決定從什么方向將會最快下山,然后又邁進了一小步,并依此類推,直到你接近局部最低點的位置。
1.2 批量梯度下降
批量梯度下降(batch gradient descent)算法的公式為:
其中是學習率(learning rate),它決定了我們沿著能讓代價函數下降程度最大的方向向下邁出的步子有多大,在批量梯度下降中,我們每一次都同時讓所有的參數減去學習速率乘以代價函數的導數。
在梯度下降算法中,還有一個更微妙的問題,梯度下降中,我們要更新和?,當??和時,會產生更新,所以你將更新和。實現梯度下降算法的微妙之處是,在這個表達式中,如果你要更新這個等式,你需要同時更新和,我的意思是在這個等式中,我們要這樣更新:
:=??,并更新:=?。
實現方法是:你應該計算公式右邊的部分,通過那一部分計算出和的值,然后同時更新和。
進一步闡述這個過程:
在梯度下降算法中,這是正確實現同時更新的方法。這里不打算解釋為什么你需要同時更新,同時更新是梯度下降中的一種常用方法。我們之后會講到,同步更新是更自然的實現方法。當人們談到梯度下降時,他們的意思就是同步更新。
如果你已經修過微積分課程,如果你熟悉偏導數和導數,這其實就是這個微分項:
,。
1.3 梯度下降的直觀理解
我們更深入研究一下,更直觀地感受一下這個算法是做什么的,以及梯度下降算法的更新過程有什么意義。梯度下降算法如下:
描述:對賦值,使得按梯度下降最快方向進行,一直迭代下去,最終得到局部最小值。其中是學習率(learning rate),它決定了我們沿著能讓代價函數下降程度最大的方向向下邁出的步子有多大。
對于這個問題,求導的目的,基本上可以說取這個紅點的切線,就是這樣一條紅色的直線,剛好與函數相切于這一點,讓我們看看這條紅色直線的斜率,就是這條剛好與函數曲線相切的這條直線,這條直線的斜率正好是這個三角形的高度除以這個水平長度,現在,這條線有一個正斜率,也就是說它有正導數,因此,我得到的新的,更新后等于減去一個正數乘以。
這就是我梯度下降法的更新規則:
讓我們來看看如果太小或太大會出現什么情況:
如果太小了,即我的學習速率太小,結果就是只能這樣像小寶寶一樣一點點地挪動,去努力接近最低點,這樣就需要很多步才能到達最低點,所以如果太小的話,可能會很慢,因為它會一點點挪動,它會需要很多步才能到達全局最低點。
如果太大,那么梯度下降法可能會越過最低點,甚至可能無法收斂,下一次迭代又移動了一大步,越過一次,又越過一次,一次次越過最低點,直到你發現實際上離最低點越來越遠,所以,如果太大,它會導致無法收斂,甚至發散。
現在,我還有一個問題,當我第一次學習這個地方時,我花了很長一段時間才理解這個問題,如果我們預先把放在一個局部的最低點,你認為下一步梯度下降法會怎樣工作?
假設你將初始化在局部最低點,在這兒,它已經在一個局部的最優處或局部最低點。結果是局部最優點的導數將等于零,因為它是那條切線的斜率。這意味著你已經在局部最優點,它使得不再改變,也就是新的等于原來的,因此,如果你的參數已經處于局部最低點,那么梯度下降法更新其實什么都沒做,它不會改變參數的值。這也解釋了為什么即使學習速率保持不變時,梯度下降也可以收斂到局部最低點。
我們來看一個例子,這是代價函數。
我想找到它的最小值,首先初始化我的梯度下降算法,在那個品紅色的點初始化,如果我更新一步梯度下降,也許它會帶我到這個點,因為這個點的導數是相當陡的。現在,在這個綠色的點,如果我再更新一步,你會發現我的導數,也即斜率,是沒那么陡的。隨著我接近最低點,我的導數越來越接近零,所以,梯度下降一步后,新的導數會變小一點點。然后我想再梯度下降一步,在這個綠點,我自然會用一個稍微跟剛才在那個品紅點時比,再小一點的一步,到了新的紅色點,更接近全局最低點了,因此這點的導數會比在綠點時更小。所以,我再進行一步梯度下降時,我的導數項是更小的,更新的幅度就會更小。所以隨著梯度下降法的運行,你移動的幅度會自動變得越來越小,直到最終移動幅度非常小,你會發現,已經收斂到局部極小值。
回顧一下,在梯度下降法中,當我們接近局部最低點時,梯度下降法會自動采取更小的幅度,這是因為當我們接近局部最低點時,很顯然在局部最低時導數等于零,所以當我們接近局部最低時,導數值會自動變得越來越小,所以梯度下降將自動采取較小的幅度,這就是梯度下降的做法。所以實際上沒有必要再另外減小。
這就是梯度下降算法,你可以用它來最小化任何代價函數,不只是線性回歸中的代價函數。
1.4 隨機梯度下降法
如果我們一定需要一個大規模的訓練集,我們可以嘗試使用隨機梯度下降法來代替批量梯度下降法。
在隨機梯度下降法中,我們定義代價函數為一個單一訓練實例的代價:
隨機梯度下降算法為:首先對訓練集隨機“洗牌”,然后:Repeat (usually anywhere between1-10){
for?{
? ? ? ? ?
? ? ? ? ? ?(for?)
} }
隨機梯度下降算法在每一次計算之后便更新參數??,而不需要首先將所有的訓練集求和,在梯度下降算法還沒有完成一次迭代時,隨機梯度下降算法便已經走出了很遠。但是這樣的算法存在的問題是,不是每一步都是朝著”正確”的方向邁出的。因此算法雖然會逐漸走向全局最小值的位置,但是可能無法站到那個最小值的那一點,而是在最小值點附近徘徊。
1.5 小批量梯度下降
小批量梯度下降算法是介于批量梯度下降算法和隨機梯度下降算法之間的算法,每計算常數次訓練實例,便更新一次參數 ??。
Repeat?{
for?{
? ? ???
? ? ? ? ? ? ?(for?)
? ? ? ? ? ? ? ? ??
} }
通常我們會令??在 2-100 之間。這樣做的好處在于,我們可以用向量化的方式來循環?個訓練實例,如果我們用的線性代數函數庫比較好,能夠支持平行處理,那么算法的總體表現將不受影響(與隨機梯度下降相同)。
二、優化算法 (Optimization algorithms)
2.1?Mini-batch 梯度下降(Mini-batch gradient descent)
本周將學習優化算法,這能讓你的神經網絡運行得更快。機器學習的應用是一個高度依賴經驗的過程,伴隨著大量迭代的過程,你需要訓練諸多模型,才能找到合適的那一個,所以,優化算法能夠幫助你快速訓練模型。
其中一個難點在于,深度學習沒有在大數據領域發揮最大的效果,我們可以利用一個巨大的數據集來訓練神經網絡,而在巨大的數據集基礎上進行訓練速度很慢。因此,你會發現,使用快速的優化算法,使用好用的優化算法能夠大大提高你和團隊的效率,那么,我們首先來談談mini-batch梯度下降法。
你之前學過,向量化能夠讓你有效地對所有個樣本進行計算,允許你處理整個訓練集,而無需某個明確的公式。所以我們要把訓練樣本放大巨大的矩陣當中去,,也是如此,,所以的維數是,的維數是,向量化能夠讓你相對較快地處理所有個樣本。如果很大的話,處理速度仍然緩慢。比如說,如果是500萬或5000萬或者更大的一個數,在對整個訓練集執行梯度下降法時,你要做的是,你必須處理整個訓練集,然后才能進行一步梯度下降法,然后你需要再重新處理500萬個訓練樣本,才能進行下一步梯度下降法。所以如果你在處理完整個500萬個樣本的訓練集之前,先讓梯度下降法處理一部分,你的算法速度會更快,準確地說,這是你可以做的一些事情。
你可以把訓練集分割為小一點的子集訓練,這些子集被取名為mini-batch,假設每一個子集中只有1000個樣本,那么把其中的到取出來,將其稱為第一個子訓練集,也叫做mini-batch,然后你再取出接下來的1000個樣本,從到,然后再取1000個樣本,以此類推。
接下來我要說一個新的符號,把到稱為,到稱為,如果你的訓練樣本一共有500萬個,每個mini-batch都有1000個樣本,也就是說,你有5000個mini-batch,因為5000乘以1000就是5000萬。
你共有5000個mini-batch,所以最后得到是
對也要進行相同處理,你也要相應地拆分的訓練集,所以這是,然后從到,這個叫,一直到。
mini-batch的數量組成了和,這就是1000個訓練樣本,包含相應的輸入輸出對。
在繼續課程之前,先確定一下我的符號,之前我們使用了上角小括號表示訓練集里的值,所以是第個訓練樣本。我們用了上角中括號來表示神經網絡的層數,表示神經網絡中第層的值,我們現在引入了大括號來代表不同的mini-batch,所以我們有和,檢查一下自己是否理解無誤。
和的維數:如果是一個有1000個樣本的訓練集,或者說是1000個樣本的值,所以維數應該是,的維數應該是,以此類推。因此所有的子集維數都是,而這些()的維數都是。
解釋一下這個算法的名稱,batch梯度下降法指的是我們之前講過的梯度下降法算法,就是同時處理整個訓練集,這個名字就是來源于能夠同時看到整個batch訓練集的樣本被處理,這個名字不怎么樣,但就是這樣叫它。
相比之下,mini-batch梯度下降法,指的是我們在下一張幻燈片中會講到的算法,你每次同時處理的單個的mini-batch?和,而不是同時處理全部的和訓練集。
那么究竟mini-batch梯度下降法的原理是什么?在訓練集上運行mini-batch梯度下降法,你運行for t=1……5000,因為我們有5000個各有1000個樣本的組,在for循環里你要做得基本就是對和執行一步梯度下降法。假設你有一個擁有1000個樣本的訓練集,而且假設你已經很熟悉一次性處理完的方法,你要用向量化去幾乎同時處理1000個樣本。
首先對輸入也就是,執行前向傳播,然后執行,之前我們這里只有,但是現在你正在處理整個訓練集,你在處理第一個mini-batch,在處理mini-batch時它變成了,即,然后執行,之所以用大寫的是因為這是一個向量內涵,以此類推,直到,這就是你的預測值。注意這里你需要用到一個向量化的執行命令,這個向量化的執行命令,一次性處理1000個而不是500萬個樣本。接下來你要計算損失成本函數,因為子集規模是1000,,說明一下,這()指的是來自于mini-batch和中的樣本。
如果你用到了正則化,你也可以使用正則化的術語,,因為這是一個mini-batch的損失,所以我將損失記為上角標,放在大括號里()。
你也會注意到,我們做的一切似曾相識,其實跟之前我們執行梯度下降法如出一轍,除了你現在的對象不是,,而是和。接下來,你執行反向傳播來計算的梯度,你只是使用和,然后你更新加權值,實際上是,更新為,對做相同處理,。這是使用mini-batch梯度下降法訓練樣本的一步,我寫下的代碼也可被稱為進行“一代”(1 epoch)的訓練。一代這個詞意味著只是一次遍歷了訓練集。
使用batch梯度下降法,一次遍歷訓練集只能讓你做一個梯度下降,使用mini-batch梯度下降法,一次遍歷訓練集,能讓你做5000個梯度下降。當然正常來說你想要多次遍歷訓練集,還需要為另一個while循環設置另一個for循環。所以你可以一直處理遍歷訓練集,直到最后你能收斂到一個合適的精度。
如果你有一個丟失的訓練集,mini-batch梯度下降法比batch梯度下降法運行地更快,所以幾乎每個研習深度學習的人在訓練巨大的數據集時都會用到,下一個視頻中,我們將進一步深度討論mini-batch梯度下降法,你也會因此更好地理解它的作用和原理。
2.2 理解mini-batch梯度下降法(Understanding mini-batch gradient descent)
在上周視頻中,你知道了如何利用mini-batch梯度下降法來開始處理訓練集和開始梯度下降,即使你只處理了部分訓練集,即使你是第一次處理,本視頻中,我們將進一步學習如何執行梯度下降法,更好地理解其作用和原理。
使用batch梯度下降法時,每次迭代你都需要歷遍整個訓練集,可以預期每次迭代成本都會下降,所以如果成本函數是迭代次數的一個函數,它應該會隨著每次迭代而減少,如果在某次迭代中增加了,那肯定出了問題,也許你的學習率太大。
使用mini-batch梯度下降法,如果你作出成本函數在整個過程中的圖,則并不是每次迭代都是下降的,特別是在每次迭代中,你要處理的是和,如果要作出成本函數的圖,而只和,有關,也就是每次迭代下你都在訓練不同的樣本集或者說訓練不同的mini-batch,如果你要作出成本函數的圖,你很可能會看到這樣的結果,走向朝下,但有更多的噪聲,所以如果你作出的圖,因為在訓練mini-batch梯度下降法時,會經過多代,你可能會看到這樣的曲線。沒有每次迭代都下降是不要緊的,但走勢應該向下,噪聲產生的原因在于也許和是比較容易計算的mini-batch,因此成本會低一些。不過也許出于偶然,和是比較難運算的mini-batch,或許你需要一些殘缺的樣本,這樣一來,成本會更高一些,所以才會出現這些擺動,因為你是在運行mini-batch梯度下降法作出成本函數圖。
你需要決定的變量之一是mini-batch的大小,就是訓練集的大小,極端情況下,如果mini-batch的大小等于,其實就是batch梯度下降法,在這種極端情況下,你就有了mini-batch ?和,并且該mini-batch等于整個訓練集,所以把mini-batch大小設為可以得到batch梯度下降法。
另一個極端情況,假設mini-batch大小為1,就有了新的算法,叫做隨機梯度下降法,每個樣本都是獨立的mini-batch,當你看第一個mini-batch,也就是和,如果mini-batch大小為1,它就是你的第一個訓練樣本,這就是你的第一個訓練樣本。接著再看第二個mini-batch,也就是第二個訓練樣本,采取梯度下降步驟,然后是第三個訓練樣本,以此類推,一次只處理一個。
看在兩種極端下成本函數的優化情況,如果這是你想要最小化的成本函數的輪廓,最小值在那里,batch梯度下降法從某處開始,相對噪聲低些,幅度也大一些,你可以繼續找最小值。
相反,在隨機梯度下降法中,從某一點開始,我們重新選取一個起始點,每次迭代,你只對一個樣本進行梯度下降,大部分時候你向著全局最小值靠近,有時候你會遠離最小值,因為那個樣本恰好給你指的方向不對,因此隨機梯度下降法是有很多噪聲的,平均來看,它最終會靠近最小值,不過有時候也會方向錯誤,因為隨機梯度下降法永遠不會收斂,而是會一直在最小值附近波動,但它并不會在達到最小值并停留在此。
實際上你選擇的mini-batch大小在二者之間,大小在1和之間,而1太小了,太大了,原因在于如果使用batch梯度下降法,mini-batch的大小為,每個迭代需要處理大量訓練樣本,該算法的主要弊端在于特別是在訓練樣本數量巨大的時候,單次迭代耗時太長。如果訓練樣本不大,batch梯度下降法運行地很好。
相反,如果使用隨機梯度下降法,如果你只要處理一個樣本,那這個方法很好,這樣做沒有問題,通過減小學習率,噪聲會被改善或有所減小,但隨機梯度下降法的一大缺點是,你會失去所有向量化帶給你的加速,因為一次性只處理了一個訓練樣本,這樣效率過于低下,所以實踐中最好選擇不大不小的mini-batch尺寸,實際上學習率達到最快。你會發現兩個好處,一方面,你得到了大量向量化,上個視頻中我們用過的例子中,如果mini-batch大小為1000個樣本,你就可以對1000個樣本向量化,比你一次性處理多個樣本快得多。另一方面,你不需要等待整個訓練集被處理完就可以開始進行后續工作,再用一下上個視頻的數字,每次訓練集允許我們采取5000個梯度下降步驟,所以實際上一些位于中間的mini-batch大小效果最好。
用mini-batch梯度下降法,我們從這里開始,一次迭代這樣做,兩次,三次,四次,它不會總朝向最小值靠近,但它比隨機梯度下降要更持續地靠近最小值的方向,它也不一定在很小的范圍內收斂或者波動,如果出現這個問題,可以慢慢減少學習率,我們在下個視頻會講到學習率衰減,也就是如何減小學習率。
如果mini-batch大小既不是1也不是,應該取中間值,那應該怎么選擇呢?其實是有指導原則的。
首先,如果訓練集較小,直接使用batch梯度下降法,樣本集較小就沒必要使用mini-batch梯度下降法,你可以快速處理整個訓練集,所以使用batch梯度下降法也很好,這里的少是說小于2000個樣本,這樣比較適合使用batch梯度下降法。不然,樣本數目較大的話,一般的mini-batch大小為64到512,考慮到電腦內存設置和使用的方式,如果mini-batch大小是2的次方,代碼會運行地快一些,64就是2的6次方,以此類推,128是2的7次方,256是2的8次方,512是2的9次方。所以我經常把mini-batch大小設成2的次方。在上一個視頻里,我的mini-batch大小設為了1000,建議你可以試一下1024,也就是2的10次方。也有mini-batch的大小為1024,不過比較少見,64到512的mini-batch比較常見。
最后需要注意的是在你的mini-batch中,要確保和要符合CPU/GPU內存,取決于你的應用方向以及訓練集的大小。如果你處理的mini-batch和CPU/GPU內存不相符,不管你用什么方法處理數據,你會注意到算法的表現急轉直下變得慘不忍睹,所以我希望你對一般人們使用的mini-batch大小有一個直觀了解。事實上mini-batch大小是另一個重要的變量,你需要做一個快速嘗試,才能找到能夠最有效地減少成本函數的那個,我一般會嘗試幾個不同的值,幾個不同的2次方,然后看能否找到一個讓梯度下降優化算法最高效的大小。希望這些能夠指導你如何開始找到這一數值。
你學會了如何執行mini-batch梯度下降,令算法運行得更快,特別是在訓練樣本數目較大的情況下。不過還有個更高效的算法,比梯度下降法和mini-batch梯度下降法都要高效的多,我們在接下來的視頻中將為大家一一講解。
2.3 指數加權平均數(Exponentially weighted averages)
我想向你展示幾個優化算法,它們比梯度下降法快,要理解這些算法,你需要用到指數加權平均,在統計中也叫做指數加權移動平均,我們首先講這個,然后再來講更復雜的優化算法。
雖然現在我生活在美國,實際上我生于英國倫敦。比如我這兒有去年倫敦的每日溫度,所以1月1號,溫度是40華氏度,相當于4攝氏度。我知道世界上大部分地區使用攝氏度,但是美國使用華氏度。在1月2號是9攝氏度等等。在年中的時候,一年365天,年中就是說,大概180天的樣子,也就是5月末,溫度是60華氏度,也就是15攝氏度等等。夏季溫度轉暖,然后冬季降溫。
你用數據作圖,可以得到以下結果,起始日在1月份,這里是夏季初,這里是年末,相當于12月末。
這里是1月1號,年中接近夏季的時候,隨后就是年末的數據,看起來有些雜亂,如果要計算趨勢的話,也就是溫度的局部平均值,或者說移動平均值。
你要做的是,首先使,每天,需要使用0.9的加權數之前的數值加上當日溫度的0.1倍,即,所以這里是第一天的溫度值。
第二天,又可以獲得一個加權平均數,0.9乘以之前的值加上當日的溫度0.1倍,即,以此類推。
第二天值加上第三日數據的0.1,如此往下。大體公式就是某天的等于前一天值的0.9加上當日溫度的0.1。
如此計算,然后用紅線作圖的話,便得到這樣的結果。
你得到了移動平均值,每日溫度的指數加權平均值。
看一下上一張幻燈片里的公式,,我們把0.9這個常數變成,將之前的0.1變成,即
由于以后我們要考慮的原因,在計算時可視大概是的每日溫度,如果是0.9,你會想,這是十天的平均值,也就是紅線部分。
我們來試試別的,將設置為接近1的一個值,比如0.98,計算,這就是粗略平均了一下,過去50天的溫度,這時作圖可以得到綠線。
這個高值要注意幾點,你得到的曲線要平坦一些,原因在于你多平均了幾天的溫度,所以這個曲線,波動更小,更加平坦,缺點是曲線進一步右移,因為現在平均的溫度值更多,要平均更多的值,指數加權平均公式在溫度變化時,適應地更緩慢一些,所以會出現一定延遲,因為當,相當于給前一天的值加了太多權重,只有0.02的權重給了當日的值,所以溫度變化時,溫度上下起伏,當?較大時,指數加權平均值適應地更緩慢一些。
我們可以再換一個值試一試,如果是另一個極端值,比如說0.5,根據右邊的公式(),這是平均了兩天的溫度。
作圖運行后得到黃線。
由于僅平均了兩天的溫度,平均的數據太少,所以得到的曲線有更多的噪聲,有可能出現異常值,但是這個曲線能夠更快適應溫度變化。
所以指數加權平均數經常被使用,再說一次,它在統計學中被稱為指數加權移動平均值,我們就簡稱為指數加權平均數。通過調整這個參數(),或者說后面的算法學習,你會發現這是一個很重要的參數,可以取得稍微不同的效果,往往中間有某個值效果最好,為中間值時得到的紅色曲線,比起綠線和黃線更好地平均了溫度。
現在你知道計算指數加權平均數的基本原理,下一個視頻中,我們再聊聊它的本質作用。
2.4 理解指數加權平均數(Understanding exponentially weighted averages)
上個視頻中,我們講到了指數加權平均數,這是幾個優化算法中的關鍵一環,而這幾個優化算法能幫助你訓練神經網絡。本視頻中,我希望進一步探討算法的本質作用。
回憶一下這個計算指數加權平均數的關鍵方程。
的時候,得到的結果是紅線,如果它更接近于1,比如0.98,結果就是綠線,如果小一點,如果是0.5,結果就是黃線。
我們進一步地分析,來理解如何計算出每日溫度的平均值。
同樣的公式,
使,寫下相應的幾個公式,所以在執行的時候,從0到1到2到3,的值在不斷增加,為了更好地分析,我寫的時候使得的值不斷減小,然后繼續往下寫。
首先看第一個公式,理解是什么?我們調換一下這兩項(),。
那么是什么?我們就代入這個公式(),所以:
。
那么是什么?你可以用這個公式計算(),把公式代進去,所以:
。
以此類推,如果你把這些括號都展開,
所以這是一個加和并平均,100號數據,也就是當日溫度。我們分析的組成,也就是在一年第100天計算的數據,但是這個是總和,包括100號數據,99號數據,97號數據等等。畫圖的一個辦法是,假設我們有一些日期的溫度,所以這是數據,這是,所以100號數據有個數值,99號數據有個數值,98號數據等等,為100,99,98等等,這就是數日的溫度數值。
然后我們構建一個指數衰減函數,從0.1開始,到,到,以此類推,所以就有了這個指數衰減函數。
計算是通過,把兩個函數對應的元素,然后求和,用這個數值100號數據值乘以0.1,99號數據值乘以0.1乘以,這是第二項,以此類推,所以選取的是每日溫度,將其與指數衰減函數相乘,然后求和,就得到了。
結果是,稍后我們詳細講解,不過所有的這些系數(),相加起來為1或者逼近1,我們稱之為偏差修正,下個視頻會涉及。
最后也許你會問,到底需要平均多少天的溫度。實際上大約為0.35,這大約是,e是自然算法的基礎之一。大體上說,如果有,在這個例子中,,所以,約等于,大約是0.34,0.35,換句話說,10天后,曲線的高度下降到,相當于在峰值的。
又因此當的時候,我們說仿佛你在計算一個指數加權平均數,只關注了過去10天的溫度,因為10天后,權重下降到不到當日權重的三分之一。
相反,如果,那么0.98需要多少次方才能達到這么小的數值?大約等于,所以前50天這個數值比大,數值會快速衰減,所以本質上這是一個下降幅度很大的函數,你可以看作平均了50天的溫度。因為在例子中,要代入等式的左邊,,所以為50,我們由此得到公式,我們平均了大約天的溫度,這里代替了,也就是說根據一些常數,你能大概知道能夠平均多少日的溫度,不過這只是思考的大致方向,并不是正式的數學證明。
最后講講如何在實際中執行,還記得嗎?我們一開始將設置為0,然后計算第一天,然后,以此類推。
現在解釋一下算法,可以將,,等等寫成明確的變量,不過在實際中執行的話,你要做的是,一開始將初始化為0,然后在第一天使,然后第二天,更新值,,以此類推,有些人會把加下標,來表示是用來計算數據的指數加權平均數。
再說一次,但是換個說法,,然后每一天,拿到第天的數據,把更新為。
指數加權平均數公式的好處之一在于,它占用極少內存,電腦內存中只占用一行數字而已,然后把最新數據代入公式,不斷覆蓋就可以了,正因為這個原因,其效率,它基本上只占用一行代碼,計算指數加權平均數也只占用單行數字的存儲和內存,當然它并不是最好的,也不是最精準的計算平均數的方法。如果你要計算移動窗,你直接算出過去10天的總和,過去50天的總和,除以10和50就好,如此往往會得到更好的估測。但缺點是,如果保存所有最近的溫度數據,和過去10天的總和,必須占用更多的內存,執行更加復雜,計算成本也更加高昂。
所以在接下來的視頻中,我們會計算多個變量的平均值,從計算和內存效率來說,這是一個有效的方法,所以在機器學習中會經常使用,更不用說只要一行代碼,這也是一個優勢。
現在你學會了計算指數加權平均數,你還需要知道一個專業概念,叫做偏差修正,下一個視頻我們會講到它,接著你就可以用它構建更好的優化算法,而不是簡單直接的梯度下降法。
2.5 指數加權平均的偏差修正(Bias correction in exponentially weighted averages)
你學過了如何計算指數加權平均數,有一個技術名詞叫做偏差修正,可以讓平均數運算更加準確,來看看它是怎么運行的。
在上一個視頻中,這個(紅色)曲線對應的值為0.9,這個(綠色)曲線對應的=0.98,如果你執行寫在這里的公式,在等于0.98的時候,得到的并不是綠色曲線,而是紫色曲線,你可以注意到紫色曲線的起點較低,我們來看看怎么處理。
計算移動平均數的時候,初始化,,但是,所以這部分沒有了(),所以,所以如果一天溫度是40華氏度,那么,因此得到的值會小很多,所以第一天溫度的估測不準。
,如果代入,然后相乘,所以,假設和都是正數,計算后要遠小于和,所以不能很好估測出這一年前兩天的溫度。
有個辦法可以修改這一估測,讓估測變得更好,更準確,特別是在估測初期,也就是不用,而是用,t就是現在的天數。舉個具體例子,當時,,因此對第二天溫度的估測變成了,也就是和的加權平均數,并去除了偏差。你會發現隨著增加,接近于0,所以當很大的時候,偏差修正幾乎沒有作用,因此當較大的時候,紫線基本和綠線重合了。不過在開始學習階段,你才開始預測熱身練習,偏差修正可以幫助你更好預測溫度,偏差修正可以幫助你使結果從紫線變成綠線。
在機器學習中,在計算指數加權平均數的大部分時候,大家不在乎執行偏差修正,因為大部分人寧愿熬過初始時期,拿到具有偏差的估測,然后繼續計算下去。如果你關心初始時期的偏差,在剛開始計算指數加權移動平均數的時候,偏差修正能幫助你在早期獲取更好的估測。
所以你學會了計算指數加權移動平均數,我們接著用它來構建更好的優化算法吧!
2.6 動量梯度下降法(Gradient descent with Momentum)
還有一種算法叫做Momentum,或者叫做動量梯度下降法,運行速度幾乎總是快于標準的梯度下降算法,簡而言之,基本的想法就是計算梯度的指數加權平均數,并利用該梯度更新你的權重,在本視頻中,我們呢要一起拆解單句描述,看看你到底如何計算。
例如,如果你要優化成本函數,函數形狀如圖,紅點代表最小值的位置,假設你從這里(藍色點)開始梯度下降法,如果進行梯度下降法的一次迭代,無論是batch或mini-batch下降法,也許會指向這里,現在在橢圓的另一邊,計算下一步梯度下降,結果或許如此,然后再計算一步,再一步,計算下去,你會發現梯度下降法要很多計算步驟對吧?
慢慢擺動到最小值,這種上下波動減慢了梯度下降法的速度,你就無法使用更大的學習率,如果你要用較大的學習率(紫色箭頭),結果可能會偏離函數的范圍,為了避免擺動過大,你要用一個較小的學習率。
另一個看待問題的角度是,在縱軸上,你希望學習慢一點,因為你不想要這些擺動,但是在橫軸上,你希望加快學習,你希望快速從左向右移,移向最小值,移向紅點。所以使用動量梯度下降法,你需要做的是,在每次迭代中,確切來說在第次迭代的過程中,你會計算微分,,我會省略上標,你用現有的mini-batch計算,。如果你用batch梯度下降法,現在的mini-batch就是全部的batch,對于batch梯度下降法的效果是一樣的。如果現有的mini-batch就是整個訓練集,效果也不錯,你要做的是計算,這跟我們之前的計算相似,也就是,的移動平均數,接著同樣地計算,,然后重新賦值權重,,同樣,這樣就可以減緩梯度下降的幅度。
例如,在上幾個導數中,你會發現這些縱軸上的擺動平均值接近于零,所以在縱軸方向,你希望放慢一點,平均過程中,正負數相互抵消,所以平均值接近于零。但在橫軸方向,所有的微分都指向橫軸方向,因此橫軸方向的平均值仍然較大,因此用算法幾次迭代后,你發現動量梯度下降法,最終縱軸方向的擺動變小了,橫軸方向運動更快,因此你的算法走了一條更加直接的路徑,在抵達最小值的路上減少了擺動。
動量梯度下降法的一個本質,這對有些人而不是所有人有效,就是如果你要最小化碗狀函數,這是碗的形狀,我畫的不太好。
它們能夠最小化碗狀函數,這些微分項,想象它們為你從山上往下滾的一個球,提供了加速度,Momentum項相當于速度。
想象你有一個碗,你拿一個球,微分項給了這個球一個加速度,此時球正向山下滾,球因為加速度越滾越快,而因為?稍小于1,表現出一些摩擦力,所以球不會無限加速下去,所以不像梯度下降法,每一步都獨立于之前的步驟,你的球可以向下滾,獲得動量,可以從碗向下加速獲得動量。我發現這個球從碗滾下的比喻,物理能力強的人接受得比較好,但不是所有人都能接受,如果球從碗中滾下這個比喻,你理解不了,別擔心。
最后我們來看具體如何計算,算法在此。
所以你有兩個超參數,學習率以及參數,控制著指數加權平均數。最常用的值是0.9,我們之前平均了過去十天的溫度,所以現在平均了前十次迭代的梯度。實際上為0.9時,效果不錯,你可以嘗試不同的值,可以做一些超參數的研究,不過0.9是很棒的魯棒數。那么關于偏差修正,所以你要拿和除以,實際上人們不這么做,因為10次迭代之后,因為你的移動平均已經過了初始階段。實際中,在使用梯度下降法或動量梯度下降法時,人們不會受到偏差修正的困擾。當然初始值是0,要注意到這是和擁有相同維數的零矩陣,也就是跟擁有相同的維數,的初始值也是向量零,所以和擁有相同的維數,也就是和是同一維數。
最后要說一點,如果你查閱了動量梯度下降法相關資料,你經常會看到一個被刪除了的專業詞匯,被刪除了,最后得到的是。用紫色版本的結果就是,所以縮小了倍,相當于乘以,所以你要用梯度下降最新值的話,要根據相應變化。實際上,二者效果都不錯,只會影響到學習率的最佳值。我覺得這個公式用起來沒有那么自然,因為有一個影響,如果你最后要調整超參數,就會影響到和,你也許還要修改學習率,所以我更喜歡左邊的公式,而不是刪去了的這個公式,所以我更傾向于使用左邊的公式,也就是有的這個公式,但是兩個公式都將設置為0.9,是超參數的常見選擇,只是在這兩個公式中,學習率的調整會有所不同。
所以這就是動量梯度下降法,這個算法肯定要好于沒有Momentum的梯度下降算法,我們還可以做別的事情來加快學習算法,我們將在接下來的視頻中探討這些問題。
2.7 RMSprop
你們知道了動量(Momentum)可以加快梯度下降,還有一個叫做RMSprop的算法,全稱是root mean square prop算法,它也可以加速梯度下降,我們來看看它是如何運作的。
回憶一下我們之前的例子,如果你執行梯度下降,雖然橫軸方向正在推進,但縱軸方向會有大幅度擺動,為了分析這個例子,假設縱軸代表參數,橫軸代表參數,可能有,或者其它重要的參數,為了便于理解,被稱為和。
所以,你想減緩方向的學習,即縱軸方向,同時加快,至少不是減緩橫軸方向的學習,RMSprop算法可以實現這一點。
在第次迭代中,該算法會照常計算當下mini-batch的微分,,所以我會保留這個指數加權平均數,我們用到新符號,而不是,因此,澄清一下,這個平方的操作是針對這一整個符號的,這樣做能夠保留微分平方的加權平均數,同樣,再說一次,平方是針對整個符號的操作。
接著RMSprop會這樣更新參數值,,,我們來理解一下其原理。記得在橫軸方向或者在例子中的方向,我們希望學習速度快,而在垂直方向,也就是例子中的方向,我們希望減緩縱軸上的擺動,所以有了和,我們希望會相對較小,所以我們要除以一個較小的數,而希望又較大,所以這里我們要除以較大的數字,這樣就可以減緩縱軸上的變化。你看這些微分,垂直方向的要比水平方向的大得多,所以斜率在方向特別大,所以這些微分中,較大,較小,因為函數的傾斜程度,在縱軸上,也就是b方向上要大于在橫軸上,也就是方向上。的平方較大,所以也會較大,而相比之下,會小一些,亦或平方會小一些,因此會小一些,結果就是縱軸上的更新要被一個較大的數相除,就能消除擺動,而水平方向的更新則被較小的數相除。
RMSprop的影響就是你的更新最后會變成這樣(綠色線),縱軸方向上擺動較小,而橫軸方向繼續推進。還有個影響就是,你可以用一個更大學習率,然后加快學習,而無須在縱軸上垂直方向偏離。
要說明一點,我一直把縱軸和橫軸方向分別稱為和,只是為了方便展示而已。實際中,你會處于參數的高維度空間,所以需要消除擺動的垂直維度,你需要消除擺動,實際上是參數,等的合集,水平維度可能,等等,因此把和分開只是方便說明。實際中是一個高維度的參數向量,也是一個高維度參數向量,但是你的直覺是,在你要消除擺動的維度中,最終你要計算一個更大的和值,這個平方和微分的加權平均值,所以你最后去掉了那些有擺動的方向。所以這就是RMSprop,全稱是均方根,因為你將微分進行平方,然后最后使用平方根。
最后再就這個算法說一些細節的東西,然后我們再繼續。下一個視頻中,我們會將RMSprop和Momentum結合起來,我們在Momentum中采用超參數,為了避免混淆,我們現在不用,而采用超參數以保證在Momentum和RMSprop中采用同一超參數。要確保你的算法不會除以0,如果的平方根趨近于0怎么辦?得到的答案就非常大,為了確保數值穩定,在實際操練的時候,你要在分母上加上一個很小很小的,是多少沒關系,是個不錯的選擇,這只是保證數值能穩定一些,無論什么原因,你都不會除以一個很小很小的數。所以RMSprop跟Momentum有很相似的一點,可以消除梯度下降中的擺動,包括mini-batch梯度下降,并允許你使用一個更大的學習率,從而加快你的算法學習速度。
所以你學會了如何運用RMSprop,這是給學習算法加速的另一方法。關于RMSprop的一個有趣的事是,它首次提出并不是在學術研究論文中,而是在多年前Jeff Hinton在Coursera的課程上。我想Coursera并不是故意打算成為一個傳播新興的學術研究的平臺,但是卻達到了意想不到的效果。就是從Coursera課程開始,RMSprop開始被人們廣為熟知,并且發展迅猛。
我們講過了Momentum,我們講了RMSprop,如果二者結合起來,你會得到一個更好的優化算法,在下個視頻中我們再好好講一講為什么。
2.8 Adam 優化算法(Adam optimization algorithm)
在深度學習的歷史上,包括許多知名研究者在內,提出了優化算法,并很好地解決了一些問題,但隨后這些優化算法被指出并不能一般化,并不適用于多種神經網絡,時間久了,深度學習圈子里的人開始多少有些質疑全新的優化算法,很多人都覺得動量(Momentum)梯度下降法很好用,很難再想出更好的優化算法。所以RMSprop以及Adam優化算法(Adam優化算法也是本視頻的內容),就是少有的經受住人們考驗的兩種算法,已被證明適用于不同的深度學習結構,這個算法我會毫不猶豫地推薦給你,因為很多人都試過,并且用它很好地解決了許多問題。
Adam優化算法基本上就是將Momentum和RMSprop結合在一起,那么來看看如何使用Adam算法。
使用Adam算法,首先你要初始化,,,,,在第次迭代中,你要計算微分,用當前的mini-batch計算,,一般你會用mini-batch梯度下降法。接下來計算Momentum指數加權平均數,所以(使用,這樣就不會跟超參數混淆,因為后面RMSprop要用到),使用Momentum時我們肯定會用這個公式,但現在不叫它,而叫它。同樣。
接著你用RMSprop進行更新,即用不同的超參數,,再說一次,這里是對整個微分進行平方處理,。
相當于Momentum更新了超參數,RMSprop更新了超參數。一般使用Adam算法的時候,要計算偏差修正,,修正也就是在偏差修正之后,
,
同樣,
也使用偏差修正,也就是,。
最后更新權重,所以更新后是(如果你只是用Momentum,使用或者修正后的,但現在我們加入了RMSprop的部分,所以我們要除以修正后的平方根加上)。
根據類似的公式更新值,。
所以Adam算法結合了Momentum和RMSprop梯度下降法,并且是一種極其常用的學習算法,被證明能有效適用于不同神經網絡,適用于廣泛的結構。
本算法中有很多超參數,超參數學習率很重要,也經常需要調試,你可以嘗試一系列值,然后看哪個有效。常用的缺省值為0.9,這是dW的移動平均數,也就是的加權平均數,這是Momentum涉及的項。至于超參數,Adam論文作者,也就是Adam算法的發明者,推薦使用0.999,這是在計算以及的移動加權平均值,關于的選擇其實沒那么重要,Adam論文的作者建議為,但你并不需要設置它,因為它并不會影響算法表現。但是在使用Adam的時候,人們往往使用缺省值即可,,和都是如此,我覺得沒人會去調整,然后嘗試不同的值,看看哪個效果最好。你也可以調整和,但我認識的業內人士很少這么干。
為什么這個算法叫做Adam?Adam代表的是Adaptive Moment Estimation,用于計算這個微分(),叫做第一矩,用來計算平方數的指數加權平均數(),叫做第二矩,所以Adam的名字由此而來,但是大家都簡稱Adam權威算法。
這就是關于Adam優化算法的全部內容,有了它,你可以更加快速地訓練神經網絡,在結束本周課程之前,我們還要講一下超參數調整,以及更好地理解神經網絡的優化問題有哪些。下個視頻中,我們將講講學習率衰減。
2.9 學習率衰減(Learning rate decay)
加快學習算法的一個辦法就是隨時間慢慢減少學習率,我們將之稱為學習率衰減,我們來看看如何做到,首先通過一個例子看看,為什么要計算學習率衰減。
假設你要使用mini-batch梯度下降法,mini-batch數量不大,大概64或者128個樣本,在迭代過程中會有噪音(藍色線),下降朝向這里的最小值,但是不會精確地收斂,所以你的算法最后在附近擺動,并不會真正收斂,因為你用的是固定值,不同的mini-batch中有噪音。
但要慢慢減少學習率的話,在初期的時候,學習率還較大,你的學習還是相對較快,但隨著變小,你的步伐也會變慢變小,所以最后你的曲線(綠色線)會在最小值附近的一小塊區域里擺動,而不是在訓練過程中,大幅度在最小值附近擺動。
所以慢慢減少的本質在于,在學習初期,你能承受較大的步伐,但當開始收斂的時候,小一些的學習率能讓你步伐小一些。
你可以這樣做到學習率衰減,記得一代要遍歷一次數據,如果你有以下這樣的訓練集,
你應該拆分成不同的mini-batch,第一次遍歷訓練集叫做第一代。第二次就是第二代,依此類推,你可以將學習率設為(decay-rate稱為衰減率,epoch-num為代數,為初始學習率),注意這個衰減率是另一個你需要調整的超參數。
這里有一個具體例子,如果你計算了幾代,也就是遍歷了幾次,如果為0.2,衰減率decay-rate為1,那么在第一代中,,這是在代入這個公式計算(),此時衰減率是1而代數是1。在第二代學習率為0.67,第三代變成0.5,第四代為0.4等等,你可以自己多計算幾個數據。要理解,作為代數函數,根據上述公式,你的學習率呈遞減趨勢。如果你想用學習率衰減,要做的是要去嘗試不同的值,包括超參數,以及超參數衰退率,找到合適的值,除了這個學習率衰減的公式,人們還會用其它的公式。
比如,這個叫做指數衰減,其中相當于一個小于1的值,如,所以你的學習率呈指數下降。
人們用到的其它公式有或者(為mini-batch的數字)。
有時人們也會用一個離散下降的學習率,也就是某個步驟有某個學習率,一會之后,學習率減少了一半,一會兒減少一半,一會兒又一半,這就是離散下降(discrete stair cease)的意思。
到現在,我們講了一些公式,看學習率究竟如何隨時間變化。人們有時候還會做一件事,手動衰減。如果你一次只訓練一個模型,如果你要花上數小時或數天來訓練,有些人的確會這么做,看看自己的模型訓練,耗上數日,然后他們覺得,學習速率變慢了,我把調小一點。手動控制當然有用,時復一時,日復一日地手動調整,只有模型數量小的時候有用,但有時候人們也會這么做。
所以現在你有了多個選擇來控制學習率。你可能會想,好多超參數,究竟我應該做哪一個選擇,我覺得,現在擔心為時過早。下一周,我們會講到,如何系統選擇超參數。對我而言,學習率衰減并不是我嘗試的要點,設定一個固定的,然后好好調整,會有很大的影響,學習率衰減的確大有裨益,有時候可以加快訓練,但它并不是我會率先嘗試的內容,但下周我們將涉及超參數調整,你能學到更多系統的辦法來管理所有的超參數,以及如何高效搜索超參數。
這就是學習率衰減,最后我還要講講神經網絡中的局部最優以及鞍點,所以能更好理解在訓練神經網絡過程中,你的算法正在解決的優化問題,下個視頻我們就好好聊聊這些問題。
2.10 局部最優的問題(The problem of local optima)
在深度學習研究早期,人們總是擔心優化算法會困在極差的局部最優,不過隨著深度學習理論不斷發展,我們對局部最優的理解也發生了改變。我向你展示一下現在我們怎么看待局部最優以及深度學習中的優化問題。
這是曾經人們在想到局部最優時腦海里會出現的圖,也許你想優化一些參數,我們把它們稱之為和,平面的高度就是損失函數。在圖中似乎各處都分布著局部最優。梯度下降法或者某個算法可能困在一個局部最優中,而不會抵達全局最優。如果你要作圖計算一個數字,比如說這兩個維度,就容易出現有多個不同局部最優的圖,而這些低維的圖曾經影響了我們的理解,但是這些理解并不正確。事實上,如果你要創建一個神經網絡,通常梯度為零的點并不是這個圖中的局部最優點,實際上成本函數的零梯度點,通常是鞍點。
也就是在這個點,這里是和,高度即成本函數的值。
但是一個具有高維度空間的函數,如果梯度為0,那么在每個方向,它可能是凸函數,也可能是凹函數。如果你在2萬維空間中,那么想要得到局部最優,所有的2萬個方向都需要是這樣,但發生的機率也許很小,也許是,你更有可能遇到有些方向的曲線會這樣向上彎曲,另一些方向曲線向下彎,而不是所有的都向上彎曲,因此在高維度空間,你更可能碰到鞍點。
就像下面的這種:
而不會碰到局部最優。至于為什么會把一個曲面叫做鞍點,你想象一下,就像是放在馬背上的馬鞍一樣,如果這是馬,這是馬的頭,這就是馬的眼睛,畫得不好請多包涵,然后你就是騎馬的人,要坐在馬鞍上,因此這里的這個點,導數為0的點,這個點叫做鞍點。我想那確實是你坐在馬鞍上的那個點,而這里導數為0。
所以我們從深度學習歷史中學到的一課就是,我們對低維度空間的大部分直覺,比如你可以畫出上面的圖,并不能應用到高維度空間中。適用于其它算法,因為如果你有2萬個參數,那么函數有2萬個維度向量,你更可能遇到鞍點,而不是局部最優點。
如果局部最優不是問題,那么問題是什么?結果是平穩段會減緩學習,平穩段是一塊區域,其中導數長時間接近于0,如果你在此處,梯度會從曲面從從上向下下降,因為梯度等于或接近0,曲面很平坦,你得花上很長時間慢慢抵達平穩段的這個點,因為左邊或右邊的隨機擾動,我換個筆墨顏色,大家看得清楚一些,然后你的算法能夠走出平穩段(紅色筆)。
我們可以沿著這段長坡走,直到這里,然后走出平穩段。
所以此次視頻的要點是,首先,你不太可能困在極差的局部最優中,條件是你在訓練較大的神經網絡,存在大量參數,并且成本函數被定義在較高的維度空間。
第二點,平穩段是一個問題,這樣使得學習十分緩慢,這也是像Momentum或是RMSprop,Adam這樣的算法,能夠加速學習算法的地方。在這些情況下,更成熟的優化算法,如Adam算法,能夠加快速度,讓你盡早往下走出平穩段。
因為你的網絡要解決優化問題,說實話,要面臨如此之高的維度空間,我覺得沒有人有那么好的直覺,知道這些空間長什么樣,而且我們對它們的理解還在不斷發展,不過我希望這一點能夠讓你更好地理解優化算法所面臨的問題。
參考資料
[1]機器學習課程:?https://www.coursera.org/course/ml
[2]深度學習課程:?https://mooc.study.163.com/university/deeplearning_ai
[3]黃海廣:?https://github.com/fengdu78
[4]github:
https://github.com/fengdu78/Coursera-ML-AndrewNg-Notes
https://github.com/fengdu78/deeplearning_ai_books
總結
以上是生活随笔為你收集整理的【机器学习基础】优化算法详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【推荐】新冠肺炎的最新数据集和可视化和预
- 下一篇: 【职场】如何才能成功的创业,创业成功的本