tensorflow學習率指數衰減ExponentialDecay的引數介紹與使用方法

疯狂学习GIS發表於2024-07-17

  本文介紹在tensorflow庫中,用於動態調整神經網路的學習率的一種方法——指數衰減ExponentialDecay()策略的引數含義及其具體用法。

  在進行神經網路訓練時,我們經常需要用到動態變化的學習率,其中指數衰減ExponentialDecay()策略是我們常用的一種策略。在tensorflow庫中,其完整的用法是tf.keras.optimizers.schedules.ExponentialDecay(),其中的具體引數如下所示。

tf.keras.optimizers.schedules.ExponentialDecay(
    initial_learning_rate, decay_steps, decay_rate, staircase=False, name=None
)

  首先,我們需要知道,在用了ExponentialDecay()策略後,程式將動態調整神經網路訓練過程中的學習率,且這一調整是與我們當前訓練的step有關的。具體關於step的解釋,大家可以參考文章神經網路常見引數解釋:epoch、batch、batch size、step、iteration,本文就不再贅述。

  如以下程式碼所示,使用ExponentialDecay()策略後,程式將依據如下的規律,基於當前訓練的step,以及我們自行設定的幾個引數,從而計算得到當前的學習率。其中,函式的返回值就是當前的學習率。

def decayed_learning_rate(step):
  return initial_learning_rate * decay_rate ^ (step / decay_steps)

  其中,initial_learning_rate * decay_rate ^ (step / decay_steps)就是當前學習率的計算公式。這裡的initial_learning_ratedecay_rate以及decay_steps,就是我們前面提到的ExponentialDecay()函式的前3個引數。其中,initial_learning_rate是我們的初始學習率,decay_rate是學習率下降的速率,而decay_steps則是學習率下降的位置(具體含義我們稍後介紹)。此外,ExponentialDecay()策略還有兩個引數,staircase表示我們在計算(step / decay_steps)時,是對結果向下取整還是取小數,預設為False,即取小數結果(具體含義我們稍後介紹);最後一個name引數,只是對當前這一學習率下降的策略加以命名,一般用不上這個引數,我們就不再介紹了。

  由此,我們可以初步知道,ExponentialDecay()函式的前4個引數都是用來計算當前的學習率的;且結合我們前面的公式initial_learning_rate * decay_rate ^ (step / decay_steps),我們可以知道,隨著當前的step不斷增加,decay_rate ^ (step / decay_steps)是降低的。

  接下來,我們直接帶入具體的資料,來看一下這幾個引數的具體作用。

  如下圖所示,我們這裡有一個訓練資料集,其中共有193608個樣本。

image

  同時,我設定了神經網路的batch size2048,那麼基於前述提及的文章神經網路常見引數解釋:epoch、batch、batch size、step、iteration,可知在1epoch中,我們對這193608個樣本加以訓練,共需要的batch數目為193608 / 2048,也就是94.54,向上取整為95,相當於需要95step。此外,我設定initial_learning_ratedecay_rate以及decay_steps分別為0.10.95以及95,且設定staircaseTrue。如下圖所示。

  此時,我們就可以對每一個引數的具體含義與作用加以介紹了。首先,我們開始訓練神經網路模型,即step開始從0逐步增加;但是由於我的staircaseTrue,因此只要指數(step / decay_steps)是小於1的,那麼都視作0(因為當前引數設定是對結果向下取整);而由於除了0以外任何數的0次方都是1,因此此時的公式initial_learning_rate * decay_rate ^ (step / decay_steps)始終等於initial_learning_rate,也就是一直保持0.1;只有當step到達我們設定的decay_steps之後,指數(step / decay_steps)才可以成為1,使得decay_rate終於產生了效果。而在這裡,由於我故意設定decay_steps95,因此按道理只要經過1epoch之後,學習率就會下降——因為前面我們計算過了,在1epoch中需要95step。那麼此時,學習率就變為了0.1 * 0.95

  接下來,我們執行上述程式碼,訓練6epoch,來驗證一下學習率的變化是否如同我們的設想。

  下圖為TensorBoard中,學習率隨著epoch的變化。這裡需要注意,我這裡截圖的時候開了曲線圖的平滑選項,因此應該以淺色的線為準。

  上面的圖因為不太全,所以或許看不出什麼;我們直接將學習率變化情況匯出,如下圖所示。

  其中,圖中的step實際上表示的是epoch,大家這裡理解即可。可以看到,在epoch0時(也就是進行第一個epoch時),學習率一直為0.1;而進行到第二個epoch時——此時我們訓練過程的step就應該是從95開始,但還不到190,因此(step / decay_steps)始終為1,學習率就是0.1 * 0.95 = 0.095了(因為資料格式問題,精度稍有差距);隨後,進行到第三個epoch時——此時我們訓練過程的step就應該是從190開始,但還不到285,因此(step / decay_steps)始終為2,學習率就已經是0.1 * 0.95 * 0.95 = 0.09025了。

  由此可知,假如我將decay_steps擴大10倍,使得其為950,那麼在前10epoch時,學習率都不會發生改變,而從第11epoch開始,學習率才會開始衰減。

  這裡我的引數staircase設定為True,因此會出現上述結果;相反的,如果設定為False,那麼計算(step / decay_steps)時,是對結果取小數,換句話說只要step發生變化,那麼當前對應的學習率也會發生變化,只不過變化的幅度會稍小一些。

  由此看到,上述學習率的變化,是符合我們的預期的。當然,上圖中最後兩個epoch對應的學習率沒有發生變化,這個具體原因我暫時也沒搞清楚;不過學習率下降作為一種策略,我們透過上述程式碼,還是達到了動態調整學習率的需求的。

  至此,大功告成。

相關文章