1. 程式人生 > >用大白話講滑動平均模型(Tensorflow)

用大白話講滑動平均模型(Tensorflow)

無論是書上還是論壇講的滑動平均模型都太官方,看了好久才看懂,其實很簡單的事,大家說起來確很費事。
首先,先不要分析這個名字的含義,我就是被這幾個字給騙了,其實他的作用就一個:控制衰減率!!!
那怎麼控制呢?
TensorFlow中給出了影子變數(shadow varible)的概念,我當初看到這更懵了,tf還給個公式:

shadow_varible = decay×shadow_variable+(1-decay)×varible

這玩意也好意思叫公式???
逗比的我看了好久才看懂,哈哈,合併同列項一看

求:shadow_varible = decay×shadow_variable+(1-decay)×varible
解:  (1-decay)×shadow_variable=(1-decay)×varible
答: shadow_variable = varible

看到這時是不是已經懷疑人生了?當然不能這麼合併,因為等號左面的shadow_varible和等號右面的不是一個,可以理解為:
y1= decay×shadow_variable+(1-decay)×varible ①
而y1的值充當下一個shadow_variable
y2= decay×y1+(1-decay)×varible ②

這裡面的decay是衰減率,取0.99或者0.9999,就是為了接近1,
這麼做的目的就是讓②等式y2≈y1,為什麼讓y2≈y1?因為讓他衰減慢一點,為什麼讓他衰減慢一點,這裡可以先理解decay是個閾值,後面會改動decay,這裡設定decay是給一個使最後衰減最慢的一個閾值,其實真正的衰減速度可能會快於他,但是不能慢於他。

看公式①,請問varible是幹什麼的?
shadow_varible叫影子變數,那肯定會問是誰的影子,就是varible的影子。varible是個人,厲害了!
這下知道了,用大白話說:
新影子變數=舊影子變數×衰減率+(1-衰減率)×人
開始程式碼編寫:
首先設定decay(衰減率),因為這個貌似是常量,
本想來個高大上的指數級衰減小學習率

decayed_learning_rate=learning_rate * decay ^(global_step/decay_steps)

但發現tf已經有控制學習率的方法了。
decay=min{decay,1+num_updates/10+num_updates)}
不過num_updates只能使等號左面的decay控制在等號右面的decay初始化的數值之內,也就是為了使衰減前期可以更新快一點,也就是我剛才說的等號右面的decay真正的意義就是最慢的那個閾值(往上翻)。
程式碼編寫decay:

step=tf.Variable(0,trainable=False)#不讓其做訓練
ema = tf.train。ExponentialMovingAverage(0.99,step)

其次編寫(人)varible

v1=tf.Variable(0,dtype=tf.float32)

影子變數

maintain_averages_op = ema.apply([v1])

更新v1滑動平均值

with tfSession() as sess:
    sess.run(maintain_averages_op)

這裡可以輸出看一下,改動v1看看結果就知道了

    print sess.run([v1, ema.apply([v1])])