記錄內容來自《Tensorflow實戰Google一書》及MOOC人工智能實踐 http://www.icourse163.org/learn/PKU-1002536002?tid=1002700003
--梯度下降算法主要用於優化單個參數的取值, 反向傳播算法給出了一個高效的方式在所有參數上使用梯度下降算法。
從而神經網絡模型在訓練數據的孫師函數盡可能小。
--反向傳播算法是訓練神經網絡的核心算法, 它可以跟據定義好的損失函數優化神經網絡中參數的取值, 從而使神經網絡模型在訓練數據集上的損失函數達到一個較小值。
假設損失函數如下:

x軸表示參數取值, y軸表示損失函數的值。, 假設當前的參數和損失函數值的位置為圖中小黑點的位置, 那么梯度下降算法將會將參數向x軸左側移動, 從而使小圓點朝箭頭的方向
移動。參數的梯度可以通過求騙到的方式計算。

通過以下是實例來解釋梯度下降算法作用於損失函數的應用。

根據例子我們可以看出梯度下降算法可以順利的使參數值朝着真實的值靠近。但是它並不能保證被優化的函數達到全局最優解。如下圖實例所示:

為解決這一問題引進了隨機梯度下降算法(stochastic gradient descent):這個算法優化的不是在全部訓練數據上的損失函數, 而是在每一輪迭代中,隨機優化
某一條訓練數據上的損失函數。
神經網絡的進一步優化
學習率的設置:
學習率表示了每次參數更新的幅度大小。學習率過大, 會導致待優化的參數在最小值附近波動, 不收斂;學習率過小, 會導致待優化的參數收斂緩慢。
在訓練過程中, 參數的更新向着損失函數梯度下降的方向。

一個實例:來自大學MOOCTensorflow筆記
通過梯度下降算法優化損失函數 loss= (w+1)^2, w初始值設置為20, 學習率設置為0.2, 定義反向傳播算法最后得到w的值為-1, loss為0, 符合函數曲線。
如果學習率設置為1 則會出現不收斂的情況

1 #coding:utf-8 2 #設損失函數 loss=(w+1)^2, 令w初值是常數5。反向傳播就是求最優w,即求最小loss對應的w值 3 import tensorflow as tf 4 #定義待優化參數w初值賦5 5 w = tf.Variable(tf.constant(20, dtype=tf.float32)) 6 #定義損失函數loss 7 loss = tf.square(w+1) 8 #定義反向傳播方法 9 train_step = tf.train.GradientDescentOptimizer(0.2).minimize(loss) 10 #生成會話,訓練40輪 11 with tf.Session() as sess: 12 init_op=tf.global_variables_initializer() 13 sess.run(init_op) 14 for i in range(40): 15 sess.run(train_step) 16 w_val = sess.run(w) 17 loss_val = sess.run(loss) 18 print "After %s steps: w is %f, loss is %f." % (i, w_val,loss_val)
學習率為0.2運行結果如下, 較正常的結果:

學習率為1則會出現震盪不收斂的結果w的值在20和-22之間跳動,這就是不收斂:

為了解決設定學習率的問題, Tensorflow提供了一種更加靈活的學習率設置方法--指數衰減法
指數衰減學習率: 學習率隨着訓練輪數變化而動態更新,通過這個函數,可以先使用較大的學習率來快速得到一個比較優的解,然后隨着迭代的接續逐步減小學習率,
是的模型在訓練后期更加穩定。
學習率計算公式如下:

用 Tensorflow 的函數表示為:
global_step = tf.Variable(0, trainable=False)
learning_rate = tf.train.exponential_decay(
LEARNING_RATE_BASE,
global_step,
LEARNING_RATE_STEP, LEARNING_RATE_DECAY,
staircase=True/False) 其中, LEARNING_RATE_BASE 為學習率初始值, LEARNING_RATE_DECAY 為學習率衰減率,global_step 記 錄了當前訓練輪數,為不可訓練型參數。學習率 learning_rate 更新頻率為輸入數據集總樣本數除以每 次喂入樣本數。若 staircase 設置為 True 時,表示 global_step/learning rate step 取整數,學習 率階梯型衰減;若 staircase 設置為 false 時,學習率會是一條平滑下降的曲線。

一般來說初始學習率、衰減系數和衰減速度都是根據經驗設置的。而且損失函數下降的速度和迭代結束之后總損失的大小沒有必然的聯系。
也就是說不能通過前幾輪損失函數下降的速度來比較不同神經網絡的效果。
1 #coding:utf-8 2 #設損失函數 loss=(w+1)^2, 令w初值是常數10。反向傳播就是求最優w,即求最小loss對應的w值 3 #使用指數衰減的學習率,在迭代初期得到較高的下降速度,可以在較小的訓練輪數下取得更有收斂度。 4 import tensorflow as tf 5 6 LEARNING_RATE_BASE = 0.1 #最初學習率 7 LEARNING_RATE_DECAY = 0.99 #學習率衰減率 8 LEARNING_RATE_STEP = 1 #喂入多少輪BATCH_SIZE后,更新一次學習率,一般設為:總樣本數/BATCH_SIZE 9 10 #運行了幾輪BATCH_SIZE的計數器,初值給0, 設為不被訓練 11 global_step = tf.Variable(0, trainable=False) 12 #定義指數下降學習率 13 learning_rate = tf.train.exponential_decay(LEARNING_RATE_BASE, global_step, LEARNING_RATE_STEP, LEARNING_RATE_DECAY, staircase=True) 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 #生成會話,訓練40輪 21 with tf.Session() as sess: 22 init_op=tf.global_variables_initializer() 23 sess.run(init_op) 24 for i in range(40): 25 sess.run(train_step) 26 learning_rate_val = sess.run(learning_rate) 27 global_step_val = sess.run(global_step) 28 w_val = sess.run(w) 29 loss_val = sess.run(loss) 30 print "After %s steps: global_step is %f, w is %f, learning rate is %f, loss is %f" % (i, global_step_val, w_val, learning_rate_val, loss_val)
由結果看出學習率在不斷的減小

