tensorflow 滑动平均模型

    滑动平均模型可以是模型在测试数据集上具有更强的鲁棒性。在采用随机梯度下降法训练神经网络时,可以在一定程度上提高模型在测试数据上的表现。

下面主要就TensorFlow提供的相关函数进行说明,理解。

tf.train.ExponentialMovingAverage()函数来实现滑动平均模型。在初始化函数时需要提供一个衰减率(decay)用于控制模型变量的更新速度。ExponentialMovingAverage会为训练时的每个可训练变量提供一个影子变量(shadow_variable)。该值的初始值等于相应变量的初始值,每次变量更新时,影子变量的值会更新为:

                                                                影子变量=衰减率*影子变量+(1-衰减率)*变量

        其中,衰减率决定了变量的更新速度,衰减率越大,变量更新速度越慢,模型越稳定。实际应用中常将其设置为非常接近1的数(0.999或0.9999)。为了使模型在训练前期更新的更快。ExponentialMovingAverage()函数还提供了num_udates参数来设置decay的大小。即,

                                                                         


首先通过一个简单代码来解释该函数

import tensorflow as tf
#定义变量v1用于滑动平均验证,并将其初始化为0.注意的是计算滑动平均时变量类型必须是实数型。tf.float32正好是实数型
v1 = tf.Variable(0, dtype=tf.float32)#初始化v1变量
#step用来模拟神经网络的迭代步数,迭代步数通常在tf.train.GradientDescentOptimizer(lr).minimize(loss_train,global_step=global_step_train)函数执行时自动完成加1操作
step = tf.Variable(0, trainable=False) #初始化step为0
#初始化衰减率为0.99 
ema = tf.train.ExponentialMovingAverage(0.99,step) #定义平滑类,设置参数以及step

#定义一个更新变量滑动平均的操作。这里需要给定一个列表,每次执行该操作时这个列表中的变量都会进行跟新
maintain_averages_op = ema.apply([v1]) #定义更新变量平均操作,

with tf.Session() as sess:
    # 初始化
    init_op = tf.global_variables_initializer()
    sess.run(init_op)
    #通过ema.average(v1)获得滑动平均后的值。
    print ("变量v1的初始值为: %f ,对应滑动平均初始值为:%f" % (sess.run(v1),sess.run(ema.average(v1))))
    # 更新变量v1的取值
    sess.run(tf.assign(v1, 5))
    sess.run(maintain_averages_op)
    #衰减率为min(0.99,(1+step)/(10+step))=min(0.99,0.1)=0.1,所以v1的滑动平均会被更新为0.1*0+(1-0.1)*5=4.5
    print ("变量v1的第一次更新值为: %f ,对应滑动平均值为:%f" % (sess.run(v1),sess.run(ema.average(v1))))
    # 更新step和v1的取值
    
    sess.run(tf.assign(step, 10000))
    sess.run(tf.assign(v1, 10))
    sess.run(maintain_averages_op)
     #衰减率为min(0.99,(1+step)/(10+step))=min(0.99,10001/10010)=0.99 ,所以v1的滑动平均会被更新为0.99*4.5+(1-0.99)*10=4.555
    print ("变量v1的第二次更新值为: %f ,对应滑动平均值为:%f" % (sess.run(v1),sess.run(ema.average(v1))))

运行结果如下

                                         


上诉为该函数对单一变量的简单应用。在实际利用TensorFlow训练网络时要复杂一些。具体参考一下代码

  MOVING_AVERAGE_DECAY = 0.9999     # The decay to use for the moving average.
  global_step_train=tf.Variable(0,trainable=False) #记录神经网络训练轮数,为不可训练的变量
  #滑动平均模型
  variable_averages=tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY,global_step_train)
  variables_averages_op = variable_averages.apply(tf.trainable_variables())
  
  logits=Alexnet_inference.inference(x,keep_prob)
  loss_train=loss(logits,y_)
  
 
  #tf.control_dependencies指定某些操作执行的依赖关系  ,即先计算滑动平均然后再利用梯度下降法
  with tf.control_dependencies([variables_averages_op]):
      train_step=tf.train.GradientDescentOptimizer().minimize(loss_train,global_step=global_step_train)

猜你喜欢

转载自blog.csdn.net/xiaolifeidaoer/article/details/88395764