本文來源於吳恩達老師的深度學習課程[1]和深度學習課程[2]筆記部分。
作者:黃海廣[3]
備註:筆記和作業(含數據、原始作業文件)、視頻都在 github[4]中下載。
在學習機器學習的過程中我們發現,大部分的機器學習算法的本質都是建立優化模型,通過最優化方法對目標函數(或損失函數)進行優化,從而訓練出最好的模型,梯度下降是最基本的優化算法。本集對梯度下降和其他優化算法進行講解。
目前我在編寫AI基礎系列,目前已經發布:
AI基礎:數據可視化簡易入門(matplotlib和seaborn)
後續持續更新
梯度下降是一個用來求函數最小值的算法,我們將使用梯度下降算法來求出代價函數 的最小值。
梯度下降背後的思想是:開始時我們隨機選擇一個參數的組合 ,計算代價函數,然後我們尋找下一個能讓代價函數值下降最多的參數組合。我們持續這麼做直到找到一個局部最小值(local minimum),因爲我們並沒有嘗試完所有的參數組合,所以不能確定我們得到的局部最小值是否便是全局最小值(global minimum),選擇不同的初始參數組合,可能會找到不同的局部最小值。
想象一下你正站立在山的這一點上,站立在你想象的公園這座紅色山上,在梯度下降算法中,我們要做的就是旋轉360度,看看我們的周圍,並問自己要在某個方向上,用小碎步儘快下山。這些小碎步需要朝什麼方向?如果我們站在山坡上的這一點,你看一下週圍,你會發現最佳的下山方向,你再看看周圍,然後再一次想想,我應該從什麼方向邁着小碎步下山?然後你按照自己的判斷又邁出一步,重複上面的步驟,從這個新的點,你環顧四周,並決定從什麼方向將會最快下山,然後又邁進了一小步,並依此類推,直到你接近局部最低點的位置。
批量梯度下降(batch gradient descent)算法的公式爲:
其中 是學習率(learning rate),它決定了我們沿着能讓代價函數下降程度最大的方向向下邁出的步子有多大,在批量梯度下降中,我們每一次都同時讓所有的參數減去學習速率乘以代價函數的導數。
在梯度下降算法中,還有一個更微妙的問題,梯度下降中,我們要更新 和 ,當 和 時,會產生更新,所以你將更新 和 。實現梯度下降算法的微妙之處是,在這個表達式中,如果你要更新這個等式,你需要同時更新 和 ,我的意思是在這個等式中,我們要這樣更新:
:= ,並更新 := 。
實現方法是:你應該計算公式右邊的部分,通過那一部分計算出 和 的值,然後同時更新 和 。
進一步闡述這個過程:
在梯度下降算法中,這是正確實現同時更新的方法。這裏不打算解釋爲什麼你需要同時更新,同時更新是梯度下降中的一種常用方法。我們之後會講到,同步更新是更自然的實現方法。當人們談到梯度下降時,他們的意思就是同步更新。
如果你已經修過微積分課程,如果你熟悉偏導數和導數,這其實就是這個微分項:
, 。
我們更深入研究一下,更直觀地感受一下這個算法是做什麼的,以及梯度下降算法的更新過程有什麼意義。梯度下降算法如下:
描述:對 賦值,使得 按梯度下降最快方向進行,一直迭代下去,最終得到局部最小值。其中 是學習率(learning rate),它決定了我們沿着能讓代價函數下降程度最大的方向向下邁出的步子有多大。
對於這個問題,求導的目的,基本上可以說取這個紅點的切線,就是這樣一條紅色的直線,剛好與函數相切於這一點,讓我們看看這條紅色直線的斜率,就是這條剛好與函數曲線相切的這條直線,這條直線的斜率正好是這個三角形的高度除以這個水平長度,現在,這條線有一個正斜率,也就是說它有正導數,因此,我得到的新的 , 更新後等於 減去一個正數乘以 。
這就是我梯度下降法的更新規則:
讓我們來看看如果 太小或 太大會出現什麼情況:
如果 太小了,即我的學習速率太小,結果就是隻能這樣像小寶寶一樣一點點地挪動,去努力接近最低點,這樣就需要很多步才能到達最低點,所以如果 太小的話,可能會很慢,因爲它會一點點挪動,它會需要很多步才能到達全局最低點。
如果 太大,那麼梯度下降法可能會越過最低點,甚至可能無法收斂,下一次迭代又移動了一大步,越過一次,又越過一次,一次次越過最低點,直到你發現實際上離最低點越來越遠,所以,如果 太大,它會導致無法收斂,甚至發散。
現在,我還有一個問題,當我第一次學習這個地方時,我花了很長一段時間才理解這個問題,如果我們預先把 放在一個局部的最低點,你認爲下一步梯度下降法會怎樣工作?
假設你將 初始化在局部最低點,在這兒,它已經在一個局部的最優處或局部最低點。結果是局部最優點的導數將等於零,因爲它是那條切線的斜率。這意味着你已經在局部最優點,它使得 不再改變,也就是新的 等於原來的 ,因此,如果你的參數已經處於局部最低點,那麼梯度下降法更新其實什麼都沒做,它不會改變參數的值。這也解釋了爲什麼即使學習速率 保持不變時,梯度下降也可以收斂到局部最低點。
我們來看一個例子,這是代價函數 。
我想找到它的最小值,首先初始化我的梯度下降算法,在那個品紅色的點初始化,如果我更新一步梯度下降,也許它會帶我到這個點,因爲這個點的導數是相當陡的。現在,在這個綠色的點,如果我再更新一步,你會發現我的導數,也即斜率,是沒那麼陡的。隨着我接近最低點,我的導數越來越接近零,所以,梯度下降一步後,新的導數會變小一點點。然後我想再梯度下降一步,在這個綠點,我自然會用一個稍微跟剛纔在那個品紅點時比,再小一點的一步,到了新的紅色點,更接近全局最低點了,因此這點的導數會比在綠點時更小。所以,我再進行一步梯度下降時,我的導數項是更小的, 更新的幅度就會更小。所以隨着梯度下降法的運行,你移動的幅度會自動變得越來越小,直到最終移動幅度非常小,你會發現,已經收斂到局部極小值。
回顧一下,在梯度下降法中,當我們接近局部最低點時,梯度下降法會自動採取更小的幅度,這是因爲當我們接近局部最低點時,很顯然在局部最低時導數等於零,所以當我們接近局部最低時,導數值會自動變得越來越小,所以梯度下降將自動採取較小的幅度,這就是梯度下降的做法。所以實際上沒有必要再另外減小 。
這就是梯度下降算法,你可以用它來最小化任何代價函數 ,不只是線性迴歸中的代價函數 。
如果我們一定需要一個大規模的訓練集,我們可以嘗試使用隨機梯度下降法來代替批量梯度下降法。
在隨機梯度下降法中,我們定義代價函數爲一個單一訓練實例的代價:
隨機梯度下降算法爲:首先對訓練集隨機「洗牌」,然後:Repeat (usually anywhere between1-10){
for {
(for )
} }
隨機梯度下降算法在每一次計算之後便更新參數 ,而不需要首先將所有的訓練集求和,在梯度下降算法還沒有完成一次迭代時,隨機梯度下降算法便已經走出了很遠。但是這樣的算法存在的問題是,不是每一步都是朝着」正確」的方向邁出的。因此算法雖然會逐漸走向全局最小值的位置,但是可能無法站到那個最小值的那一點,而是在最小值點附近徘徊。
小批量梯度下降算法是介於批量梯度下降算法和隨機梯度下降算法之間的算法,每計算常數 次訓練實例,便更新一次參數 。
Repeat {
for {
(for )
} }
通常我們會令 在 2-100 之間。這樣做的好處在於,我們可以用向量化的方式來循環 個訓練實例,如果我們用的線性代數函數庫比較好,能夠支持平行處理,那麼算法的總體表現將不受影響(與隨機梯度下降相同)。
本週將學習優化算法,這能讓你的神經網絡運行得更快。機器學習的應用是一個高度依賴經驗的過程,伴隨着大量迭代的過程,你需要訓練諸多模型,才能找到合適的那一個,所以,優化算法能夠幫助你快速訓練模型。
其中一個難點在於,深度學習沒有在大數據領域發揮最大的效果,我們可以利用一個巨大的數據集來訓練神經網絡,而在巨大的數據集基礎上進行訓練速度很慢。因此,你會發現,使用快速的優化算法,使用好用的優化算法能夠大大提高你和團隊的效率,那麼,我們首先來談談mini-batch梯度下降法。
你之前學過,向量化能夠讓你有效地對所有 個樣本進行計算,允許你處理整個訓練集,而無需某個明確的公式。所以我們要把訓練樣本放大巨大的矩陣 當中去, , 也是如此,
你可以把訓練集分割爲小一點的子集訓練,這些子集被取名爲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梯度下降法訓練樣本的一步,我寫下的代碼也可被稱爲進行「一代」(1 epoch)的訓練。一代這個詞意味着只是一次遍歷了訓練集。
使用batch梯度下降法,一次遍歷訓練集只能讓你做一個梯度下降,使用mini-batch梯度下降法,一次遍歷訓練集,能讓你做5000個梯度下降。當然正常來說你想要多次遍歷訓練集,還需要爲另一個while循環設置另一個for循環。所以你可以一直處理遍歷訓練集,直到最後你能收斂到一個合適的精度。
如果你有一個丟失的訓練集,mini-batch梯度下降法比batch梯度下降法運行地更快,所以幾乎每個研習深度學習的人在訓練巨大的數據集時都會用到,下一個視頻中,我們將進一步深度討論mini-batch梯度下降法,你也會因此更好地理解它的作用和原理。
在上週視頻中,你知道了如何利用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梯度下降法都要高效的多,我們在接下來的視頻中將爲大家一一講解。
我想向你展示幾個優化算法,它們比梯度下降法快,要理解這些算法,你需要用到指數加權平均,在統計中也叫做指數加權移動平均,我們首先講這個,然後再來講更復雜的優化算法。
雖然現在我生活在美國,實際上我生於英國倫敦。比如我這兒有去年倫敦的每日溫度,所以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,根據右邊的公式( ),這是平均了兩天的溫度。
作圖運行後得到黃線。
由於僅平均了兩天的溫度,平均的數據太少,所以得到的曲線有更多的噪聲,有可能出現異常值,但是這個曲線能夠更快適應溫度變化。
所以指數加權平均數經常被使用,再說一次,它在統計學中被稱爲指數加權移動平均值,我們就簡稱爲指數加權平均數。通過調整這個參數( ),或者說後面的算法學習,你會發現這是一個很重要的參數,可以取得稍微不同的效果,往往中間有某個值效果最好, 爲中間值時得到的紅色曲線,比起綠線和黃線更好地平均了溫度。
現在你知道計算指數加權平均數的基本原理,下一個視頻中,我們再聊聊它的本質作用。
上個視頻中,我們講到了指數加權平均數,這是幾個優化算法中的關鍵一環,而這幾個優化算法能幫助你訓練神經網絡。本視頻中,我希望進一步探討算法的本質作用。
回憶一下這個計算指數加權平均數的關鍵方程。
的時候,得到的結果是紅線,如果它更接近於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乘以 ,這是第二項,以此類推,所以選取的是每日溫度,將其與指數衰減函數相乘,然後求和,就得到了 。
結果是,稍後我們詳細講解,不過所有的這些係數(
最後也許你會問,到底需要平均多少天的溫度。實際上 大約爲0.35,這大約是 ,e是自然算法的基礎之一。大體上說,如果有 ,在這個例子中, ,所以 , 約等於 ,大約是0.34,0.35,換句話說,10天后,曲線的高度下降到 ,相當於在峯值的 。
又因此當 的時候,我們說彷彿你在計算一個指數加權平均數,只關注了過去10天的溫度,因爲10天后,權重下降到不到當日權重的三分之一。
相反,如果,那麼0.98需要多少次方纔能達到這麼小的數值? 大約等於 ,所以前50天這個數值比 大,數值會快速衰減,所以本質上這是一個下降幅度很大的函數,你可以看作平均了50天的溫度。因爲在例子中,要代入等式的左邊, ,所以 爲50,我們由此得到公式,我們平均了大約 天的溫度,這裏 代替了 ,也就是說根據一些常數,你能大概知道能夠平均多少日的溫度,不過這只是思考的大致方向,並不是正式的數學證明。
最後講講如何在實際中執行,還記得嗎?我們一開始將 設置爲0,然後計算第一天 ,然後 ,以此類推。
現在解釋一下算法,可以將 , , 等等寫成明確的變量,不過在實際中執行的話,你要做的是,一開始將 初始化爲0,然後在第一天使 ,然後第二天,更新 值, ,以此類推,有些人會把 加下標,來表示 是用來計算數據的指數加權平均數。
再說一次,但是換個說法, ,然後每一天,拿到第 天的數據,把 更新爲 。
指數加權平均數公式的好處之一在於,它佔用極少內存,電腦內存中只佔用一行數字而已,然後把最新數據代入公式,不斷覆蓋就可以了,正因爲這個原因,其效率,它基本上只佔用一行代碼,計算指數加權平均數也只佔用單行數字的存儲和內存,當然它並不是最好的,也不是最精準的計算平均數的方法。如果你要計算移動窗,你直接算出過去10天的總和,過去50天的總和,除以10和50就好,如此往往會得到更好的估測。但缺點是,如果保存所有最近的溫度數據,和過去10天的總和,必須佔用更多的內存,執行更加複雜,計算成本也更加高昂。
所以在接下來的視頻中,我們會計算多個變量的平均值,從計算和內存效率來說,這是一個有效的方法,所以在機器學習中會經常使用,更不用說只要一行代碼,這也是一個優勢。
現在你學會了計算指數加權平均數,你還需要知道一個專業概念,叫做偏差修正,下一個視頻我們會講到它,接着你就可以用它構建更好的優化算法,而不是簡單直接的梯度下降法。
你學過了如何計算指數加權平均數,有一個技術名詞叫做偏差修正,可以讓平均數運算更加準確,來看看它是怎麼運行的。
在上一個視頻中,這個(紅色)曲線對應 的值爲0.9,這個(綠色)曲線對應的 =0.98,如果你執行寫在這裏的公式,在 等於0.98的時候,得到的並不是綠色曲線,而是紫色曲線,你可以注意到紫色曲線的起點較低,我們來看看怎麼處理。
計算移動平均數的時候,初始化 , ,但是 ,所以這部分沒有了( ),所以 ,所以如果一天溫度是40華氏度,那麼 ,因此得到的值會小很多,所以第一天溫度的估測不準。
,如果代入
,然後相乘,所以
有個辦法可以修改這一估測,讓估測變得更好,更準確,特別是在估測初期,也就是不用
,而是用
,t就是現在的天數。舉個具體例子,當
時,
,因此對第二天溫度的估測變成了
在機器學習中,在計算指數加權平均數的大部分時候,大家不在乎執行偏差修正,因爲大部分人寧願熬過初始時期,拿到具有偏差的估測,然後繼續計算下去。如果你關心初始時期的偏差,在剛開始計算指數加權移動平均數的時候,偏差修正能幫助你在早期獲取更好的估測。
所以你學會了計算指數加權移動平均數,我們接着用它來構建更好的優化算法吧!
還有一種算法叫做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的梯度下降算法,我們還可以做別的事情來加快學習算法,我們將在接下來的視頻中探討這些問題。
你們知道了動量(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,如果二者結合起來,你會得到一個更好的優化算法,在下個視頻中我們再好好講一講爲什麼。
在深度學習的歷史上,包括許多知名研究者在內,提出了優化算法,並很好地解決了一些問題,但隨後這些優化算法被指出並不能一般化,並不適用於多種神經網絡,時間久了,深度學習圈子裏的人開始多少有些質疑全新的優化算法,很多人都覺得動量(Momentum)梯度下降法很好用,很難再想出更好的優化算法。所以RMSprop以及Adam優化算法(Adam優化算法也是本視頻的內容),就是少有的經受住人們考驗的兩種算法,已被證明適用於不同的深度學習結構,這個算法我會毫不猶豫地推薦給你,因爲很多人都試過,並且用它很好地解決了許多問題。
Adam優化算法基本上就是將Momentum和RMSprop結合在一起,那麼來看看如何使用Adam算法。
使用Adam算法,首先你要初始化, , , , ,在第 次迭代中,你要計算微分,用當前的mini-batch計算 , ,一般你會用mini-batch梯度下降法。接下來計算Momentum指數加權平均數,所以 (使用 ,這樣就不會跟超參數 混淆,因爲後面RMSprop要用到 ),使用Momentum時我們肯定會用這個公式,但現在不叫它 ,而叫它 。同樣 。
接着你用RMSprop進行更新,即用不同的超參數
,
相當於Momentum更新了超參數 ,RMSprop更新了超參數 。一般使用Adam算法的時候,要計算偏差修正, ,修正也就是在偏差修正之後,
同樣 ,
也使用偏差修正,也就是
最後更新權重,所以
更新後是
根據類似的公式更新
值,
所以Adam算法結合了Momentum和RMSprop梯度下降法,並且是一種極其常用的學習算法,被證明能有效適用於不同神經網絡,適用於廣泛的結構。
本算法中有很多超參數,超參數學習率 很重要,也經常需要調試,你可以嘗試一系列值,然後看哪個有效。 常用的缺省值爲0.9,這是dW的移動平均數,也就是 的加權平均數,這是Momentum涉及的項。至於超參數 ,Adam論文作者,也就是Adam算法的發明者,推薦使用0.999,這是在計算 以及 的移動加權平均值,關於 的選擇其實沒那麼重要,Adam論文的作者建議 爲 ,但你並不需要設置它,因爲它並不會影響算法表現。但是在使用Adam的時候,人們往往使用缺省值即可,