為了在采用随機梯度下降算法訓練神經網絡時提高最終模型在測試資料上的表現,TensorFlow提供了一種在變量上使用指數滑動平均的方法。
實作一個變量的指數滑動平均需要首先通過tf.train.ExponentialMovingAverage()函數初始化一個滑動平均類,同時需要向函數提供一個衰減率(Decay)參數,這個衰減率将用于控制模型更新的速度。
滑動平均算法會對每一個變量維護一個影子變量,這個影子變量的初始值就是相應變量的初始值。如果變量發生變化,影子變量的值也會按照下面公式更新:
shadow_variable n + 1 _{n+1} n+1= decay * shadow_variable n _{n} n+(1-decay)*variable n + 1 _{n+1} n+1
式中,variable n + 1 _{n+1} n+1為更新後原變量的值,shadow_variable n + 1 _{n+1} n+1是variable n + 1 _{n+1} n+1的影子變量,其值等于該變量的初始值,shadow_variable n + 1 _{n+1} n+1就是更新後其影子變量的值,decay為衰減率。decay決定了滑動平均模型的更新速度,一般會設成非常接近1的數(如0.99或0.999),decay值越大模型越趨于穩定。
例如,将decay設定為0.99,變量variable的初始值為0,并一次疊代為5、15、20、25,則相應的影子變量會以如下表所示的方式更新:
變量疊代值 | 滑動平均值計算結果 |
---|---|
0.99×0+(1-0.99)×0=0 | |
5 | 0.99×0+(1-0.99)×5=0.05 |
15 | 0.99×0.05+(1-0.99)×15=0.2995 |
20 | 0.99×0.2995+(1-0.99)×20=0.4965 |
25 | 0.99×0.4965+(1-0.99)×25=0.7415 |
ExponentialMovingAverage()接受指定num_updates參數來限制decay的大小,如果在初始化時提供了num_updates參數,那麼每次使用的衰減率decay值将由下式決定:
m i n { d e c a y , 1 + n u m u p d a t e s 10 + n u m u p d a t e s } min\left \{ decay, \frac{1+numupdates}{10+numupdates}\right \} min{decay,10+numupdates1+numupdates}
将num_updates值設定得較小,會得到較快的影子變量更新速度。但如果想要使用預設的decay作為衰減率,那麼num_updates參數往往會比較大,比如1000或者10000,這樣才能使得計算之後的值大于decay。
在得到初始化的滑動平均類之後,可以通過這個類的函數apply()作用于目前模型中所有可訓練的變量上。這個函數的原型為apply(self,var_list),其中var_list參數是一個傳遞進來的參數清單。
average()真正執行了影子變量的計算。它是ExponentialMovingAverage類的一個函數,在使用時,對其傳入需要進行計算的變量即可。
一般情況下指數滑動平均使用的方法如下
training_step = tf.Variable(0,trainable=False)
variable_averages = tf.train.ExponentialMovingAverage(0.99,training_step)
variable_averages_op = variable_averages.apply(tf.trainable_variables())
variable_averages_list = [variable_averages.average(var) for var in tf.trainable_variables()]
為什麼要使用滑動平均?以下内容摘自這裡
滑動平均可以使模型在測試資料上更健壯(robust)。采用随機梯度下降算法訓練神經網絡使,使用滑動平均在很多應用中都可以在一定程度上提高最終模型在測試資料上的表現。
對神經網絡的權重weights使用滑動平均,得到的影子變量shadow_weights。在訓練過程中仍然使用原來不帶滑動平均的權重weights,不然無法得到weights下一步更新的值,又怎麼求下一步weights的影子變量shadow_weights呢?之後在測試過程中使用shadow_weights來代替weights作為神經網絡邊的權重,這樣在測試資料上效果更好。因為shadow_weights的更新更加平滑,對于随機梯度下降而言,更平滑的更新說明不會偏離最優點很遠。
參考書籍:《TensorFlow深度學習算法原理與程式設計實戰》 蔣子陽 著