瞭解學習速率以及它如何提高深度學習的表現
學習速率是深度學習中的一個重要的超引數,如何調整學習速率是訓練出好模型的關鍵要素之一。這篇文章將著重說明以下幾點:
- 什麼是學習速率? 它的意義是什麼?
- 如何系統地達成一個良好的學習速率?
- 為什麼我們要在訓練期間改變學習速率?
- 在使用預先訓練的模型時,我們如何處理學習速率?
首先,學習速率是什麼呢? 學習速率是一個超引數,它控制了我們在多大程度上調整了我們的網路的權重,並對損失梯度進行了調整。值越低,沿著向下的斜率就越慢。雖然這可能是個好的辦法(使用低學習率),以確保我們不會錯過任何區域性極小值,但這也可能意味著我們要花很長時間才會收斂——尤其是如果我們陷入了停滯不前的區域。下面的公式顯示了這種關係。
new_weight = existing_weight — learning_rate * gradient
梯度下降與小(上)和大(底)學習速率。來源:Coursera的機器學習課程
一般來說,學習速率是由使用者隨意地配置的。在最好的情況下,使用者可以利用過去的經驗(或其他型別的學習材料)來獲得關於設定學習速率的最佳值。
同樣的,我們通常很難把它做對。下圖演示了在配置學習速率時會遇到的不同場景。
不同學習速率對收斂的影響
此外,學習速率影響了我們的模型是如何收斂一個區域性極小值(也就是達到最精確的精度)。因此,從得到的結果中得到正確的結果將意味著我們將花費更少的時間來訓練模型。
訓練時間越少,花在GPU雲端計算上的錢就越少。
有更好的方法來確定學習速率嗎? 在每次迭代中,你都可以通過非常低的學習速率來訓練模型,並將其(線性或指數級)增加,從而估算出良好的學習速率。
每個mini-batch迭代後學習速率提高
如果我們在每次迭代中記錄學習情況,並將學習速率(log)與損失(loss)進行劃分;我們會看到隨著學習速率的增加,會在一個點上,損失停止下降並開始增加。在實踐中,我們的學習速率最好是在留在某個地方,也就是圖表的最低點(如下圖所示)。在這種情況下,最低點的範圍在0.001到0.01之間。
上面的辦法似乎是有用的。
如何開始使用它? 目前,在fast.ai包中,它被作為一個函式來支援,這由傑里米·霍華德開發的人工智慧包,是一種抽象pytorch包的方法(就像Keras是一種對Tensorflow的抽象)。只需輸入以下命令,就可以在訓練神經網路之前找到最優的學習速率。
# learn is an instance of Learner class or one of derived classes like
ConvLearner
learn.lr_find()
learn.sched.plot_lr()
提高效能 我們已經討論了學習速率是什麼,它是很重要的,並且當我們開始訓練我們的模型時,我們如何系統地達到一個最優值。接下來,我們將學習如何使用學習速率來提高我們模型的效能。
通常,當一個人設定好學習速率並訓練模型時,他只會等待學習速率隨著時間的推移而下降,而模型最終會趨於一致。然而,當梯度到達一個穩定狀態時,訓練的損失就會變得更加難以改善。極小化損失的難度來自於鞍點,而不是區域性極小值。
誤差曲面上的一個鞍點。鞍點是一個函式的導數為零的點,但點不是所有軸上的區域性極值。
那麼我們該怎麼辦呢? 我們可以考慮一些選擇。一般來說,如果訓練不再改善我們的損失,我們要改變學習速率每次迭代過程中根據一些迴圈函式f。每次迴圈都有一個固定長度的迭代次數。該方法可以使學習速率在合理的邊界值之間變化。這很有幫助,因為如果我們被卡在鞍點上,增加學習速率就可以讓鞍點達到平穩狀態時更快地遍歷。這有一種“三角形”的方法,在每幾次迭代之後,學習速率就會重新開始。
“三角形”(上)和“三角形2”(下)方法。在上圖中,最小和最大學習速率保持不變。在下圖中,每次迴圈後,差異就減少了一半。
另一種很受歡迎的方法叫做“隨機梯度下降法”。該方法主要使用餘弦函式作為迴圈函式,並在每次迴圈的最大程度上重新啟動學習速率。當學習速率重新啟動時,它並不是從零開始,而是從模型在最後的步驟中收斂的引數開始。
雖然有一些變化,但是下面的圖展示了它的一個實現,其中每個迴圈都被設定為相同的時間週期。
SGDR圖,學習速率vs迭代
因此,我們現在有了一種減少訓練時間的方法,基本上是週期性地在“山峰”(下圖)上跳躍。
標準的學習速率和迴圈的學習速率
除了節省時間,使用這些方法可以在不調整和減少迭代的情況下提高分類精度。
在遷移學習中的學習速率 在解決人工智慧問題時,fast.ai的課程在充分利用預先訓練過的模型方面給予了很大的重視。例如,在解決影象分類問題時,學生們被教如何使用預訓練的模型,比如VGG或Resnet50,並將其與你想預測的任何影象資料集連線起來。
在fast.ai(程式,不要與fast.ai包混淆)中總結模型是如何快速構建的,下面是我們通常採取的8個步驟:
1.啟用資料增強,並設定預計算(precompute)=True 2.使用lrfind()找到最高的學習速率,其中損失仍在明顯改善。 3.為1-2個epoch的預計算啟用訓練最後一層 4.用資料增強的方法(即預計算=False)進行最後一層的訓練,使用cyclelen=1的2-3個週期 5.解凍所有的層 6.將較早的層設定為比下一個更高層的3x-10x降低的學習速率 7.再次使用lr_find() 8.用cycle_mult=2訓練整個網路,直到過度擬合
在最後一節中,我們將討論微分學習。
微分學習是什麼? 微分學習是一種方法,在訓練期間,你將不同的學習速率設定在網路的不同層。這與人們通常如何配置學習速率形成了鮮明的對比,即在訓練過程中,在整個網路中使用相同的速率。
為了更清楚地說明這個概念,我們可以參考下面的圖,在這個圖中,一個預先訓練的模型被劃分為3個組,每個組將被配置成一個遞增的學習速率值。
以微分學習速率抽樣的卷積神經網路(CNN)
這種配置方法背後的直觀看法是,最初的幾層通常包含非常詳細地資料細節,比如線條和邊緣——我們通常不希望改變太多,並希望保留資訊。因此,不需要大量的改變它們的權重。
相反,在之後的層中,比如上面的綠色部分,我們可以看到資料的細節; 並且可能並不需要對它們進行保留。