最近看北京大學曹建老師的TensorFlow搭建神經網絡,在指數衰減學習率中,了解到指數衰減學習率的強大。由此寫一些自己在學習中的感悟和啟發。
大家都知道在設定學習率時,如果偏大會發生動盪不收斂,如果偏小則收斂速度慢。那么有沒有一個好的方法可以讓可以讓學習率變化,並隨着訓練輪數由大到小進行變化。
答案是有的:指數衰減學習率可以做到。
先給出它的公式(枯燥的):learning_rate = learning_rate_base * learning_rate_decyglobal_step/learning_rate_step
TensorFlow源碼中同樣給出個計算公式
(注 1):learning_rate_base 表示學習率的初始值,learning_rate_decy 表示學習率衰減率,
global_step表示運行了幾輪的BATCH_SIZE計數器,learning_rate_step表示多少輪BATCH_SIZE后更新一次學習率,一般設為:總樣本數/BATCH_SIZE
通俗來講:假設learning_rate_step為 1,那么就是1輪更新一次。由於global_step是每輪都自加一的,所以第一輪后學習率為:learning_rate_base * learning_rate_decy1
第二輪后學習率為:learning_rate_base * learning_rate_decy 2,第n輪后學習率為:learning_rate_base * learning_rate_decy n
方便起見我們設 LEARNING_RATE_BASE = 0.1 ,LEARNING_RATE_DECY = 0.99, LEARNING_RATE_STEP = 1
第一輪后 學習率更新為 learning_rate = 0.1 * 0.991 = 0.099 ,第二輪后 學習率更新為 earning_rate = 0.1 * 0.992 = 0.098 ,第n輪后 學習率更新為 learning_rate = 0.1 * 0.99n
(注 2):如果想看指數衰減原理性的,推薦吳恩達老師的機器學習。
代碼奉上如下:
1 import tensorflow as tf 2 3 LEARNING_RATE_BASE = 0.1 # 最初學習率 4 LEARNING_RATE_DECY = 0.99 # 學習率衰減率 5 LEARNING_RATE_STEP = 1 # 喂入多少輪BATCH_SIZE后更新一次學習率,一般設為:總樣本數/BATCH_SIZE 6 7 # 運行了幾輪的BATCH_SIZE計數器,初值給零,設置為不被訓練 8 global_step = tf.Variable(0, trainable=False) 9 10 # 定義指數下降學習率 11 learning_rate = tf.train.exponential_decay(LEARNING_RATE_BASE, global_step, 12 LEARNING_RATE_STEP, LEARNING_RATE_DECY, staircase=True) 13 14 # 定義待優化參數,初值給10 15 w = tf.Variable(tf.constant(10, dtype=tf.float32)) 16 # 定義損失函數 loss 17 loss = tf.square(w+1) 18 # 定義反向傳播方法 19 train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=global_step) 20 21 # 生成會話,訓練40輪 22 with tf.Session() as sess: 23 init_op = tf.global_variables_initializer() 24 sess.run(init_op) 25 for i in range(40): 26 sess.run(train_step) 27 learning_rate_val = sess.run(learning_rate) 28 global_step_var = sess.run(global_step) 29 w_var = sess.run(w) 30 loss_var = sess.run(loss) 31 print('after %d steps: global_step is %f, w is %f, learn_rate is %f, loss is %f' % (i+1, global_step_var, w_var, 32 learning_rate_val, loss_var))
# 定義指數下降學習率
learning_rate = tf.train.exponential_decay(LEARNING_RATE_BASE, global_step,LEARNING_RATE_STEP, LEARNING_RATE_DECY, staircase=True)
LEARNING_RATE_DECY取值為(0, 1)這個區間
當staircase為True時,global_step/LEARNING_RATE_STEP取整數,學習率階梯性衰減。staircase為False時,學習率會是一條平滑下降的曲線。
下面附上代碼運行結果更直觀顯示:運行的輪數以及對應的學習率
結果顯示loss值下降的過程非常好。且w很快的收斂到1.
下面給出固定學習率的運行結果。
learning_rate = 0.001
結果表明w隨着輪數緩慢的下降(此時w應該是趨於1的)
當learning_rate = 1時
結果表明w隨着輪數增加在10和-12之間跳變(此時w應該是趨於1的)