您的位置:首頁>正文

什麼是學習率,以及它是如何影響深度學習的

編者按:當大家在訓練神經網路時, 相信不少人曾深受超參數困擾, 學習率(Leraning Rate)、權值初始化(Weight Initialization)……這些數位深刻影響著神經網路的性能, 卻只能靠經驗和實驗來得出合適值。 那麼, 學習率究竟是什麼?它是怎麼影響網路的呢?對於這個問題, 澳大利亞最大招聘網站的資料科學家Hafidz Zulkifli近日給出了他的解答。

本文將主要關注以下幾點:

什麼是學習率?它有什麼意義?

如何系統地獲得合適的學習率?

為什麼我們需要在訓練期間改變學習率?

如何用預訓練模型來處理學習率?

什麼是學習率

學習率是一個重要的超參數, 它控制著我們基於損失梯度調整神經網路權值的速度, 大多數優化演算法(如SGD、RMSprop、Adam)對它都有涉及。 學習率越小, 我們沿著損失梯度下降的速度越慢。 從長遠來看, 這種謹慎慢行的選擇可能還不錯, 因為可以避免錯過任何局部最優解, 但它也意味著我們要花更多時間來收斂,

尤其是如果我們處於曲線的至高點。

以下等式顯示了這種關係:

新權值 = 當前權值 - 學習率 × 梯度

通常, 學習率是用戶自己隨意設的, 你可以根據過去的經驗或書本資料選擇一個最佳值, 或憑直覺估計一個合適值。 這樣做可行,

但並非永遠可行。 事實上選擇學習率是一件比較困難的事, 下圖顯示了應用不同學習率後出現的各類情況:

可以發現, 學習率直接影響我們的模型能夠以多快的速度收斂到局部最小值(也就是達到最好的精度)。 一般來說, 學習率越大, 神經網路學習速度越快。

如果學習率太小, 網路很可能會陷入局部最優;但是如果太大, 超過了極值, 損失就會停止下降, 在某一位置反復震盪。

也就是說, 如果我們選擇了一個合適的學習率, 我們不僅可以在更短的時間內訓練好模型, 還可以節省各種雲的花費。

有沒有更好的方法來確定學習率?

Leslie N. Smith在Cyclical Learning Rates for Training Neural Networks的第3.3節中指出, 如果你先設置一個較低的學習率, 然後隨著訓練反覆運算逐漸增大這個值, 最終你可以獲得一個較好的學習率。

學習率增加情況

如果我們記錄每次訓練反覆運算, 畫出相應的學習率(對數)和loss變化, 我們可以發現, 隨著學習率不斷提高, loss會在一段時間不斷下降, 並在觸及最低點後開始回升。 在實踐中, 最理想的學習率應該是使loss曲線到達最低點的那個值, 以下圖為例, 圖中模型的最佳學習率在0.001到0.01之間。

看起來很有道理,那麼具體該怎麼操作?

上述這種調試學習率的方法已經被封裝進fast.ai包,你可以調用它的函數lr_find直接使用。

learn.lr_find()learn.sched.plot_lr()

如何用學習率提高模型性能

現在我們已經知道了什麼是學習率,那麼當我們開始訓練模型時,我們該如何用學習率來提高模型性能呢?

前人的智慧

通常情況下,當我們用設定好的學習率訓練模型時,我們只能等它隨著時間的推移慢慢下降,直到模型完成收斂。但是,如下圖所示,很多時候隨著梯度到達高值,模型的loss會變得很難收斂。對於這一點,Dauphin等人在他們的文章中指出,影響loss降低的主要因素是曲面鞍點,而不是局部最小值。因為如果模型如果陷入了一個“精心設計”的“山谷”,這時它過低的學習率無法產生,或者說是無法在短時間內產生足夠的梯度來使模型越過這道“坎”。

因此定期提高學習率將有助於模型更好地收斂。

loss曲面上的鞍點,在這一點上函數的導數為0,但它並不是全域最優點

注:不少學習演算法在訓練過程中,隨著誤差的減少,反覆運算次數的增加,步長變化越來越小,訓練誤差越來越小直到變為零,局部探索到一個駐點,如果這個點是誤差曲面的鞍點,即不是最大值也不是最小值的平滑曲面,那麼一般結果表現為性能比較差;如果這個駐點是局部極小值,那麼表現為性能較好,但不是全域最優值。目前大多數訓練演算法在碰到無論是鞍點還是局部極值點的時候,因為此刻學習率已經變得非常小,所以會陷入非全域最優值不能自拔。——張俊林

那麼該怎麼避免這種情況呢?

對於這個問題,一個可行的方法是在訓練過程中使用“動態”的學習率,並讓它隨時間不斷下降。

如果發現訓練時模型的loss不再發生變化,我們可以視情況引入一些迴圈函數f,來改變每次反覆運算的學習率數值。由於每個週期的反覆運算次數都是固定的,這可以把學習率控制在合理範圍內迴圈調試。如果剛好是卡在鞍點上,學習率的週期性提高可以讓模型跳出當前局限,去“更遠的地方”看一看。

Leslie Smith等人在2015年提出的Triangular迴圈學習率正是基於這種思想。它的做法是在每次反覆運算後從頭開始調試學習率。

Triangular:學習率隨反覆運算次數發生的變化

Triangular2:學習率隨反覆運算次數發生的變化

此外,另一種流行的方法是由Loshchilov和Hutter提出的加入了熱重啟(Warm Restart)的隨機梯度下降。這種方法把余弦函數作為迴圈函數f,並在每一輪反覆運算開始時重設一個最大學習率。它的“熱(warm)”表現在重設學習率時,它取的不是初始值,而是模型上次收斂時的參數。

下圖是這一方法的視覺化圖像,它每輪反覆運算的學習率相同,但在實際操作中它可以有多種變化。

SGDR:學習率隨反覆運算次數發生的變化

依靠這些方法,我們能週期性跳出loss曲面鞍點,這也意味著能減少訓練時間。

左:固定的學習率;右:動態的學習率

相關研究還表明,這些週期性調整學習率的方法還可以在不對模型做出調整的情況下提高分類準確率,並減少反覆運算次數。

遷移學習中的學習率

這裡需要提到一個和deeplearning.ai齊名的深度學習熱門課程fast.ai,如果說吳恩達專注於傳播理論基礎,那有深厚kaggle背景的fast.ai則更關注如何讓你成為一名“老司機”。正是基於這個重視實踐的定位,fast.ai特別強調預訓練模型,假如你準備訓練一個圖像分類模型,那fast.ai的老師會強烈建議你用VGG或Resnet50等現成模型先在資料集上試試,再根據具體情況調整參數。

如果你想做一些fast.ai專案,以下是我歸納的基本步驟:

進行資料增強,precompute=True;

在loss保持下降時用lr_find()找出最佳學習率;

用precompute的值調整最後一層的參數,訓練最後一層1-2個epoch;

設置cycle_len = 1,用增強後的資料(precompute=False)訓練最後一層2–3個epoch;

把所有層設為可訓練;

將前一層的學習率設為後一層的1/10-1/3;

再次調用lr_find();

設置cycle_mult=2,訓練整個神經網路,直到它過擬合。

注:在fastai中,週期性提高學習率是通過設置learner.fit中的cyclelen和cyclemult參數來實現的。

可以發現,上述的步驟2、步驟5和步驟7都是關於學習率的。我們在上文中只介紹了步驟2的操作方法,即如何在訓練模型前確定最佳學習率。因此在接下去的內容中,我們將把注意力放在如何用SGDR縮短訓練時間、提高模型準確率上,即通過重新調整學習率避免梯度接近0。

其中最後一節會重點介紹差異性學習,談談訓練模型和預訓練模型相結合時它是怎麼調整學習率的。

什麼是差異性學習

差異性學習是指在訓練期間為神經網路的不同層設置不同學習率的方法,它和一般做法不同,因為通常整個神經網路使用的是同一學習率。

在寫這篇文章的時候,Jeremy 和Sebastian Ruder剛發了一篇論文Fine-tuned Language Models for Text Classification,深入探討了差異性學習這個問題。如果你對NLP有所瞭解,那差異性學習一個更常規的名稱是判別式微調(discriminative fine-tuning)。

為了更清楚地說明這個概念,我們可以看下方這張圖,它把預訓練模型分為紅、藍、綠三組,並賦予逐漸遞增的學習率。

包含不同學習率的CNN

這樣設置學習率的初衷是前幾個層會包含大量非常細微的重要資料細節,如線條、邊緣等,我們需要把它們原封不動的保留下來。而後面的層,如上圖中的綠色區域,包含眼睛、鼻子、嘴巴等資料的詳細特徵,這些內容可有可無。

和其他微調方法的對比

有人認為微調這種方法代價過高,它可能會使一些CNN超過100層,效率太低。因此很多人會通過一層層微調來確定參數。但這樣做也有缺點,首先你要保證調試順序是正確的,其次這種割裂式做法影響了平行計算,最後由於要多次經過資料集,最後模型很可能會過擬合。

對於這個擔憂,之前提到的這篇Fine-tuned Language Models for Text Classification已經提出了一種能在NLP任務中兼顧預測準確率和出錯率的方法,具體可以查看論文自行掌握。

看起來很有道理,那麼具體該怎麼操作?

上述這種調試學習率的方法已經被封裝進fast.ai包,你可以調用它的函數lr_find直接使用。

learn.lr_find()learn.sched.plot_lr()

如何用學習率提高模型性能

現在我們已經知道了什麼是學習率,那麼當我們開始訓練模型時,我們該如何用學習率來提高模型性能呢?

前人的智慧

通常情況下,當我們用設定好的學習率訓練模型時,我們只能等它隨著時間的推移慢慢下降,直到模型完成收斂。但是,如下圖所示,很多時候隨著梯度到達高值,模型的loss會變得很難收斂。對於這一點,Dauphin等人在他們的文章中指出,影響loss降低的主要因素是曲面鞍點,而不是局部最小值。因為如果模型如果陷入了一個“精心設計”的“山谷”,這時它過低的學習率無法產生,或者說是無法在短時間內產生足夠的梯度來使模型越過這道“坎”。

因此定期提高學習率將有助於模型更好地收斂。

loss曲面上的鞍點,在這一點上函數的導數為0,但它並不是全域最優點

注:不少學習演算法在訓練過程中,隨著誤差的減少,反覆運算次數的增加,步長變化越來越小,訓練誤差越來越小直到變為零,局部探索到一個駐點,如果這個點是誤差曲面的鞍點,即不是最大值也不是最小值的平滑曲面,那麼一般結果表現為性能比較差;如果這個駐點是局部極小值,那麼表現為性能較好,但不是全域最優值。目前大多數訓練演算法在碰到無論是鞍點還是局部極值點的時候,因為此刻學習率已經變得非常小,所以會陷入非全域最優值不能自拔。——張俊林

那麼該怎麼避免這種情況呢?

對於這個問題,一個可行的方法是在訓練過程中使用“動態”的學習率,並讓它隨時間不斷下降。

如果發現訓練時模型的loss不再發生變化,我們可以視情況引入一些迴圈函數f,來改變每次反覆運算的學習率數值。由於每個週期的反覆運算次數都是固定的,這可以把學習率控制在合理範圍內迴圈調試。如果剛好是卡在鞍點上,學習率的週期性提高可以讓模型跳出當前局限,去“更遠的地方”看一看。

Leslie Smith等人在2015年提出的Triangular迴圈學習率正是基於這種思想。它的做法是在每次反覆運算後從頭開始調試學習率。

Triangular:學習率隨反覆運算次數發生的變化

Triangular2:學習率隨反覆運算次數發生的變化

此外,另一種流行的方法是由Loshchilov和Hutter提出的加入了熱重啟(Warm Restart)的隨機梯度下降。這種方法把余弦函數作為迴圈函數f,並在每一輪反覆運算開始時重設一個最大學習率。它的“熱(warm)”表現在重設學習率時,它取的不是初始值,而是模型上次收斂時的參數。

下圖是這一方法的視覺化圖像,它每輪反覆運算的學習率相同,但在實際操作中它可以有多種變化。

SGDR:學習率隨反覆運算次數發生的變化

依靠這些方法,我們能週期性跳出loss曲面鞍點,這也意味著能減少訓練時間。

左:固定的學習率;右:動態的學習率

相關研究還表明,這些週期性調整學習率的方法還可以在不對模型做出調整的情況下提高分類準確率,並減少反覆運算次數。

遷移學習中的學習率

這裡需要提到一個和deeplearning.ai齊名的深度學習熱門課程fast.ai,如果說吳恩達專注於傳播理論基礎,那有深厚kaggle背景的fast.ai則更關注如何讓你成為一名“老司機”。正是基於這個重視實踐的定位,fast.ai特別強調預訓練模型,假如你準備訓練一個圖像分類模型,那fast.ai的老師會強烈建議你用VGG或Resnet50等現成模型先在資料集上試試,再根據具體情況調整參數。

如果你想做一些fast.ai專案,以下是我歸納的基本步驟:

進行資料增強,precompute=True;

在loss保持下降時用lr_find()找出最佳學習率;

用precompute的值調整最後一層的參數,訓練最後一層1-2個epoch;

設置cycle_len = 1,用增強後的資料(precompute=False)訓練最後一層2–3個epoch;

把所有層設為可訓練;

將前一層的學習率設為後一層的1/10-1/3;

再次調用lr_find();

設置cycle_mult=2,訓練整個神經網路,直到它過擬合。

注:在fastai中,週期性提高學習率是通過設置learner.fit中的cyclelen和cyclemult參數來實現的。

可以發現,上述的步驟2、步驟5和步驟7都是關於學習率的。我們在上文中只介紹了步驟2的操作方法,即如何在訓練模型前確定最佳學習率。因此在接下去的內容中,我們將把注意力放在如何用SGDR縮短訓練時間、提高模型準確率上,即通過重新調整學習率避免梯度接近0。

其中最後一節會重點介紹差異性學習,談談訓練模型和預訓練模型相結合時它是怎麼調整學習率的。

什麼是差異性學習

差異性學習是指在訓練期間為神經網路的不同層設置不同學習率的方法,它和一般做法不同,因為通常整個神經網路使用的是同一學習率。

在寫這篇文章的時候,Jeremy 和Sebastian Ruder剛發了一篇論文Fine-tuned Language Models for Text Classification,深入探討了差異性學習這個問題。如果你對NLP有所瞭解,那差異性學習一個更常規的名稱是判別式微調(discriminative fine-tuning)。

為了更清楚地說明這個概念,我們可以看下方這張圖,它把預訓練模型分為紅、藍、綠三組,並賦予逐漸遞增的學習率。

包含不同學習率的CNN

這樣設置學習率的初衷是前幾個層會包含大量非常細微的重要資料細節,如線條、邊緣等,我們需要把它們原封不動的保留下來。而後面的層,如上圖中的綠色區域,包含眼睛、鼻子、嘴巴等資料的詳細特徵,這些內容可有可無。

和其他微調方法的對比

有人認為微調這種方法代價過高,它可能會使一些CNN超過100層,效率太低。因此很多人會通過一層層微調來確定參數。但這樣做也有缺點,首先你要保證調試順序是正確的,其次這種割裂式做法影響了平行計算,最後由於要多次經過資料集,最後模型很可能會過擬合。

對於這個擔憂,之前提到的這篇Fine-tuned Language Models for Text Classification已經提出了一種能在NLP任務中兼顧預測準確率和出錯率的方法,具體可以查看論文自行掌握。

同類文章
Next Article
喜欢就按个赞吧!!!
点击关闭提示