滑动平均模型是可以使模型在测试数据上更加鲁棒的一个方法。
在TensorFlow中提供了tf.train.ExponentialMovingAverage
来实现滑动平均模型,其参数衰减率
d
e
c
a
y
decay
decay用于控制模型更新的速度。ExponentialMovingAverage
对每个变量维护一个影子变量(shadow variable),该影子变量的初始值就是相应变量的初始值,每次运行变量更新时,影子变量的值会更新为:
s
h
a
d
o
w
_
v
a
r
i
a
b
l
e
=
d
e
c
a
y
∗
s
h
a
d
o
w
_
v
a
r
i
a
b
l
e
+
(
1
−
d
e
c
a
y
)
∗
v
a
r
i
a
b
l
e
shadow\_variable = decay * shadow\_variable + (1 - decay) * variable
shadow_variable=decay∗shadow_variable+(1−decay)∗variable
其中
s
h
a
d
o
w
_
v
a
r
i
a
b
l
e
shadow\_variable
shadow_variable为影子变量,
v
a
r
i
a
b
l
e
variable
variable为待更新变量,
d
e
c
a
y
decay
decay为衰减率。
d
e
c
a
y
decay
decay决定了模型更新的速度,
d
e
c
a
y
decay
decay越大模型越趋于稳定。在实际应用中,
d
e
c
a
y
decay
decay一般会设成非常接近于1的数(比如0.999或0.9999),为了使得模型在训练前期可以更新得更快,ExponentialMovingAverage
提供了num_updates
参数来动态设置
d
e
c
a
y
decay
decay的大小。如果在ExponentialMovingAverage
初始化时提供了
n
u
m
_
u
p
d
a
t
e
s
num\_updates
num_updates参数,那么每次使用的衰减率将是:
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(decay,\frac{1+num\_updates}{10+num\_updates})
min(decay,10+num_updates1+num_updates)
import tensorflow as tf
v1 = tf.Variable(0.0)
decay = 0.99
step = tf.Variable(0,dtype=tf.float32,trainable=False)
ema = tf.train.ExponentialMovingAverage(decay,step, name='ExponentialMovingAverage')
maintain_op = ema.apply([v1])
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(v1.eval(), ema.average(v1).eval())
sess.run(tf.assign(v1,5))
sess.run(maintain_op)
print(v1.eval(), ema.average(v1).eval())
sess.run(tf.assign(step,10000))
sess.run(tf.assign(v1,10))
sess.run(maintain_op)
print(v1.eval(), ema.average(v1).eval())
sess.run(maintain_op)
print(v1.eval(), ema.average(v1).eval())
'''
0.0 0.0
5.0 4.5
10.0 4.555
10.0 4.60945
'''
Reference
- 郑泽宇等.TensorFLow实战Google深度学习框架(第2版),电子工业出版社,2018.
相关文章
以mnist展示滑动平均、正则化、变量管理
tf.train.ExponentialMovingAverage()的错误与正确实践