TensorFlow學習筆記之tf.train.ExponentialMovingAverage(decay=decay, num_updates=num_updates)類的理解


 神經網絡訓練一個模型的過程中,對於每一次參數的更新可以增加一個trick,即對參數進行滑動平均更新,即moving average,會對模型的訓練有益。參照源碼的一句說法:When training a model, it is often beneficial to maintain moving averages of the trained parameters. Evaluations that use averaged parameters sometimes produce significantly better results than the final trained values.

 

滑動平均更新參數依據公式:shadow_variable(cur) = decay * shadow_variable(pre) + (1 - decay) * variable

其中,decay控制更新速率,一般取值0.9以上,值越大,更新越慢,值越穩定;variable是當前變量的值;shadow_variable(pre)為上一次更新參數值;shadow_variable(cur)當前更新參數值。

 

下面說一下對這個類的理解:

類的主要參數有decay和num_updates,decay為衰減率,控制更新速率,num_updates為參數更新次數,或者說訓練次數,decay的值可以根據下面公式改變:

min(decay, (1 + num_updates) / (10 + num_updates)))

每次構造一個對象ema = tf.train.ExponentialMovingAverage(decay=decay, num_updates=num_updates)之后,需要調用函數ema.apply((self, var_list=None),參數var_list是一個列表或張量

此函數的功能就是執行滑動平均更新參數,返回一個操作,該操作就是實現上面公式shadow_variable(cur) = decay * shadow_variable(pre) + (1 - decay) * variable的操作。

官方源碼的解釋:The `apply()` method adds shadow copies of trained variables and add ops that maintain a moving average of the trained variables in their shadow copies. It is used when building the training model. The ops that maintain moving averages are typically run after each training step.

參數:`var_list` must be a list of `Variable` or `Tensor` objects.

返回值:Returns an op that updates all shadow variables from the current value of their associated variables.

 

舉例:

 

 1 #!/usr/bin/env python
 2 # -*- coding: utf-8 -*-
 3 import tensorflow as tf
 4 
 5 """
 6 滑動平均方法的運用,通常用於訓練模型參數時,對參數的更新操作,利用
 7 shadow_variable = decay * shadow_variable + (1 - decay) * variable
 8 構造類tf.train.ExponentialMovingAverage()的對象ema
 9 調用ema.apply() 返回用於對參數更新滑動平均的操作的列表,常用來傳給control_dependencies(control_inputs)函數
10 
11 """
12 
13 # 定義一個32位浮點數的變量,初始值位0.0
14 v1 = tf.Variable(dtype=tf.float32, initial_value=0.)
15 # 衰減率decay,初始值位0.99
16 decay = 0.99
17 # 定義num_updates,同樣,初始值位0
18 num_updates = tf.Variable(0, trainable=False)
19 # 定義滑動平均模型的類,將衰減率decay和num_updates傳入。
20 ema = tf.train.ExponentialMovingAverage(decay=decay, num_updates=num_updates)
21 # 定義更新變量列表
22 update_var_list = [v1]
23 # 使用滑動平均模型
24 ema_apply = ema.apply(update_var_list) # return an operation that updates the moving averages
25 
26 # Tensorflow會話
27 with tf.Session() as sess:
28     # 初始化全局變量
29     sess.run(tf.global_variables_initializer())
30     # 輸出初始值
31     print(sess.run([v1, ema.average(v1)]))
32     # [0.0, 0.0](此時 num_updates = 0 ⇒ decay = .1, ),
33     # shadow_variable = variable = 0.
34     # 將v1賦值為5
35     sess.run(tf.assign(v1, 5))
36     # 調用函數,使用滑動平均模型
37     sess.run(ema_apply)
38     # 再次輸出
39     print(sess.run([v1, ema.average(v1)]))
40     # 此時,num_updates = 0 ⇒ decay =0.1,  v1 = 5;
41     # shadow_variable = 0.1 * 0 + 0.9 * 5 = 4.5 ⇒ variable
42     # 將num_updates賦值為10000
43     sess.run(tf.assign(num_updates, 10000))
44     # 將v1賦值為10
45     sess.run(tf.assign(v1, 10))
46     # 調用函數,使用滑動平均模型
47     sess.run(ema_apply)
48     # 輸出
49     print(sess.run([v1, ema.average(v1)]))
50     # decay = 0.99,shadow_variable = 0.99 * 4.5 + .01*10 ⇒ 4.555
51     # 再次使用滑動平均模型
52     sess.run(ema_apply)
53     # 輸出
54     print(sess.run([v1, ema.average(v1)]))
55     # decay = 0.99,shadow_variable = .99*4.555 + .01*10 = 4.609
56     for i in range(1000):
57         sess.run(ema_apply)
58         print(sess.run([v1, ema.average(v1)]))

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM