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)]))

猜你喜欢

转载自www.cnblogs.com/huwj/p/10753370.html
今日推荐