神经网络优化之滑动平均(tensorflow)

滑动平均

滑动平均相当于一个影子值(像是给参数加了影子,参数变化,影子随之追随),记录了每个参数一段时间内过往值的平均,增加了模型的泛化性。滑动平均不仅表现了当前值,还表现了过去一段时间内的平均值。

滑动平均的计算

影子 = 衰减率x影子+(1-衰减率)x参数
(影子初值=参数初值;
衰减率=min{MOVING_AVERAGE_DECY,(1+轮数)/(10+轮数)})

tensorflow 代码详解

import tensorflow as tf
#1.定义变量及滑动平均类
#定义一个32位浮点变量,初始值位0.0,这个代码就是不断更新w1参数,优化w1,滑动平均做了一个w1的影子
w1 = tf.Variable(0,dtype=tf.float32)
#定义num_updates(NN的迭代轮数),初始值为0,不可被优化,这个参数不训练
global_step = tf.Variable(0,trainable=False)
#实例化滑动平均类,设衰减率为0.99,当前轮数global_step
MOVING_AVERAGE_DECAY = 0.99
ema = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY,global_step)
#ema.apply后面的括号是更新列表,每次运行sess.run(ema_op)时,对更新列表求滑动平均值
#在实际应用中会使tf.trainable_variables()自动将所有训练的参数汇总为列表
#ema_op = ema.apply([w1])
ema_op = ema.apply(tf.trainable_variables())

#2.查看不同迭代中变量取值的变化
#初始化变量,计算图节点要运用的会话实现
with tf.Session() as sess:
    #初始化变量
    init_op = tf.global_variables_initializer()
    # 计算图节点运算
    sess.run(init_op)
    #用ema.average(w1)获取w1滑动平均值
    #打印出当前参数w1和w1的滑动平均
    print(sess.run([w1,ema.average(w1)]))
    #参数w1赋值为1
    #tf.assign(A, new_number): 这个函数的功能主要是把A的值变为new_number
    sess.run(tf.assign(w1,1))
    sess.run(ema_op)
    print(sess.run([w1,ema.average(w1)]))

    #更新step和w1的值,模拟出100轮迭代后,参数w1变为10
    sess.run(tf.assign(global_step,100))
    sess.run(tf.assign(w1,10))
    sess.run(ema_op)
    print(sess.run([w1,ema.average(w1)]))

    #复制粘贴几次执行滑动平均节点的操作
    sess.run(ema_op)
    print(sess.run([w1, ema.average(w1)]))

    sess.run(ema_op)
    print(sess.run([w1, ema.average(w1)]))

    sess.run(ema_op)
    print(sess.run([w1, ema.average(w1)]))

    sess.run(ema_op)
    print(sess.run([w1, ema.average(w1)]))

    sess.run(ema_op)
    print(sess.run([w1, ema.average(w1)]))

运行后结果

这里写图片描述
可以发现,最初的w1和滑动平均都是0,w1设为1后,滑动平均为0.9,当迭代轮数更新为100轮,w1设为10,滑动平均为1.64,之后每执行一次,参数w1的滑动平均都在向参数w1逼近。

猜你喜欢

转载自blog.csdn.net/qq_37566138/article/details/81238739