您好,登錄后才能下訂單哦!
使用TensorFlow怎么實現滑動平均?針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
1、滑動平均求解對象初始化
ema = tf.train.ExponentialMovingAverage(decay,num_updates)
參數decay
`shadow_variable = decay * shadow_variable + (1 - decay) * variable`
參數num_updates
`min(decay, (1 + num_updates) / (10 + num_updates))`
2、添加/更新變量
添加目標變量,為之維護影子變量
注意維護不是自動的,需要每輪訓練中運行此句,所以一般都會使用tf.control_dependencies使之和train_op綁定,以至于每次train_op都會更新影子變量
ema.apply([var0, var1])
3、獲取影子變量值
這一步不需要定義圖中,從影子變量集合中提取目標值
sess.run(ema.average([var0, var1]))
4、保存&載入影子變量
我們知道,在TensorFlow中,變量的滑動平均值都是由影子變量所維護的,如果你想要獲取變量的滑動平均值需要獲取的是影子變量而不是變量本身。
保存影子變量
建立tf.train.ExponentialMovingAverage對象后,Saver正常保存就會存入影子變量,命名規則是"v/ExponentialMovingAverage"對應變量”v“
import tensorflow as tf if __name__ == "__main__": v = tf.Variable(0.,name="v") #設置滑動平均模型的系數 ema = tf.train.ExponentialMovingAverage(0.99) #設置變量v使用滑動平均模型,tf.all_variables()設置所有變量 op = ema.apply([v]) #獲取變量v的名字 print(v.name) #v:0 #創建一個保存模型的對象 save = tf.train.Saver() sess = tf.Session() #初始化所有變量 init = tf.initialize_all_variables() sess.run(init) #給變量v重新賦值 sess.run(tf.assign(v,10)) #應用平均滑動設置 sess.run(op) #保存模型文件 save.save(sess,"./model.ckpt") #輸出變量v之前的值和使用滑動平均模型之后的值 print(sess.run([v,ema.average(v)])) #[10.0, 0.099999905]
載入影子變量并映射到變量
利用了Saver載入模型的變量名映射功能,實際上對所有的變量都可以如此操作『TensorFlow』模型載入方法匯總
v = tf.Variable(1.,name="v") #定義模型對象 saver = tf.train.Saver({"v/ExponentialMovingAverage":v}) sess = tf.Session() saver.restore(sess,"./model.ckpt") print(sess.run(v)) #0.0999999
這里特別需要注意的一個地方就是,在使用tf.train.Saver函數中,所傳遞的模型參數是{"v/ExponentialMovingAverage":v}而不是{"v":v},如果你使用的是后面的參數,那么你得到的結果將是10而不是0.09,那是因為后者獲取的是變量本身而不是影子變量。
使用這種方式來讀取模型文件的時候,還需要輸入一大串的變量名稱。
variables_to_restore函數的使用
v = tf.Variable(1.,name="v") #滑動模型的參數的大小并不會影響v的值 ema = tf.train.ExponentialMovingAverage(0.99) print(ema.variables_to_restore()) #{'v/ExponentialMovingAverage': <tf.Variable 'v:0' shape=() dtype=float32_ref>} sess = tf.Session() saver = tf.train.Saver(ema.variables_to_restore()) saver.restore(sess,"./model.ckpt") print(sess.run(v)) #0.0999999
variables_to_restore會識別網絡中的變量,并自動生成影子變量名。
通過使用variables_to_restore函數,可以使在加載模型的時候將影子變量直接映射到變量的本身,所以我們在獲取變量的滑動平均值的時候只需要獲取到變量的本身值而不需要去獲取影子變量。
5、官方文檔例子
官方文檔中將每次apply更新就會自動訓練一邊模型,實際上可以反過來兩者關系,《tf實戰google》P128中有示例
| Example usage when creating a training model: | | ```python | # Create variables. | var0 = tf.Variable(...) | var1 = tf.Variable(...) | # ... use the variables to build a training model... | ... | # Create an op that applies the optimizer. This is what we usually | # would use as a training op. | opt_op = opt.minimize(my_loss, [var0, var1]) | | # Create an ExponentialMovingAverage object | ema = tf.train.ExponentialMovingAverage(decay=0.9999) | | with tf.control_dependencies([opt_op]): | # Create the shadow variables, and add ops to maintain moving averages | # of var0 and var1. This also creates an op that will update the moving | # averages after each training step. This is what we will use in place | # of the usual training op. | training_op = ema.apply([var0, var1]) | | ...train the model by running training_op... | ```
6、batch_normal的例子
和上面不太一樣的是,batch_normal中不太容易綁定到train_op(位于函數體外面),則強行將兩個variable的輸出過程化為節點,綁定給參數更新步驟
def batch_norm(x,beta,gamma,phase_train,scope='bn',decay=0.9,eps=1e-5): with tf.variable_scope(scope): # beta = tf.get_variable(name='beta', shape=[n_out], initializer=tf.constant_initializer(0.0), trainable=True) # gamma = tf.get_variable(name='gamma', shape=[n_out], # initializer=tf.random_normal_initializer(1.0, stddev), trainable=True) batch_mean,batch_var = tf.nn.moments(x,[0,1,2],name='moments') ema = tf.train.ExponentialMovingAverage(decay=decay) def mean_var_with_update(): ema_apply_op = ema.apply([batch_mean,batch_var]) with tf.control_dependencies([ema_apply_op]): return tf.identity(batch_mean),tf.identity(batch_var) # identity之后會把Variable轉換為Tensor并入圖中, # 否則由于Variable是獨立于Session的,不會被圖控制control_dependencies限制 mean,var = tf.cond(phase_train, mean_var_with_update, lambda: (ema.average(batch_mean),ema.average(batch_var))) normed = tf.nn.batch_normalization(x, mean, var, beta, gamma, eps) return normed
關于使用TensorFlow怎么實現滑動平均問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。