tensorflow提供的tf.train.ExponentialMovingAverage 类利用指数衰减维持变量的滑动平均。

当训练模型的时候,保持训练参数的滑动平均是非常有益的。评估时使用取平均后的参数有时会产生比使用最终训练好的参数值好很多的效果。方法apply()会添加被训练变量的影子副本和在影子副本中维持被训练变量的滑动平均的若干操作。该方法在创建训练模型时使用。那些保持维持滑动平均的操作(ops)一般会在每个训练步骤之后被执行。average()和average_name()方法分别提供了对影子变量和影子变量名字访问的途径。它们在建立评估模型或者从checkpoint文件恢复模型时能够用到,主要是帮助使用滑动平均代替最终训练结果进行评估。

滑动平均计算时使用指数衰减。当创建ExponentialMovingAverage对象时,衰减率应该被指定。影子变量和被训练参数的初始值相同。当执行更新滑动平均的操作时,每个影子变量会按照下面的公式进行更新:

shadow_variable -= (1 - decay) * (shadow_variable - variable)

上面的公式与下面的公式相同:

shadow_variable = decay * shadow_variable + (1 - decay) * variable

decay决定了模型更新的速度,越大越趋于稳定。decay的合理取值接近1.0,所以 decay的取值一般包含多个9,如0.999、0.9999等。

创建训练模型时的用法示例:

# Create variables.
var0 = tf.Variable(...)
var1 = tf.Variable(...)
# ... use the variables to build a training model...
...
# Create an op that applies the optimizer. This is what we usually
# would use as a training op.
opt_op = opt.minimize(my_loss, [var0, var1]) # Create an ExponentialMovingAverage object
ema = tf.train.ExponentialMovingAverage(decay=0.9999) with tf.control_dependencies([opt_op]):
# Create the shadow variables, and add ops to maintain moving averages
# of var0 and var1. This also creates an op that will update the moving
# averages after each training step. This is what we will use in place
# of the usual training op.
training_op = ema.apply([var0, var1]) ...train the model by running training_op...

有两种使用滑动平均进行评估的方法:

  • 建立一个使用影子变量(shadow variables)而非变量(variables)的模型。为此,需要使用返回给定变量的影子变量的average()方法
  • 创建一个正常的模型,但是使用影子变量名加载checkpoint文件进行评估。为此,需要使用average_name()方法

恢复影子变量值的示例:

# Create a Saver that loads variables from their saved shadow values.
shadow_var0_name = ema.average_name(var0)
shadow_var1_name = ema.average_name(var1)
saver = tf.train.Saver({shadow_var0_name: var0, shadow_var1_name: var1})
saver.restore(...checkpoint filename...)
# var0 and var1 now hold the moving average values

部分方法:

__init__(decay,
num_updates=None,
zero_debias=False,
name='ExponentialMovingAverage')
# 创建一个ExponentialMovingAverage对象
# 为了创建影子变量和添加维持滑动平均的操作,apply()方法必须被调用
        # 可选参数num_updates允许对衰减率进行动态微调。典型的方式是通过记录训练次数,在每次训练开始之前降低衰减率。这样做可以使模型在训练的初始阶段更新
        # 得更快
        # zero_debias: 如果为True,Tensor objects会被初始化为无偏滑动平均
        # 衰减率更新公式为:
actual_decay = min(decay, (1 + num_updates) / (10 + num_updates))
        可选参数name是被添加到apply()方法中的操作名称的前缀。
apply(var_list=None)
# 维持变量的滑动平均,即对shadow variables进行计算
# var_list必须是Variable或者Tensor objects构成的列表。该方法会为列表中的所有元素创建影子变量,且变量对象的影子变量初始值和变量相同。影子变量
           也会被添加到GraphKeys.MOVING_AVERAGE_VARIABLES集合中。对于Tensor objects,影子变量会被初始化为0,同时被设置为无偏。
# 影子变量被设置trainable=False,并且被添加到GraphKeys.MOVING_AVERAGE_VARIABLES集合中,它们会在调用tf.global_variables()时被返回。
# 该方法返回一个按照要求更新所有影子变量的操作。同时需要注意的是,apply()可以在不同的var_list下被多次调用。
average(var)
# 返回变量的影子变量值,即读取影子变量shadow variables

average_name(var)
# 返回变量的影子变量名,即读取影子变量名
# 在模型训练期间计算变量的滑动平均和在评估时从计算得到的滑动平均恢复变量是ExponentialMovingAverage的典型应用。
# 为了恢复变量,必须知道影子变量名。然后影子变量名和对应的变量被传给Saver()对象来从计算得到滑动平均值恢复变量。
# Saver=tf.train.Saver({ema.average_name(var):var})
# 不管apply()方法有没有被调用,average_name()都可以被调用
variables_to_restore(moving_avg_variables=None)
# 返回要恢复的变量的名称映射
# moving_avg_variables : 需要使用滑动平均名进行恢复的变量构成的list;如果为None,会默认为variables.moving_average_variables() + va
                                   riables.trainable_variables()
# 如果变量有滑动平均,那么使用滑动平均变量名作为恢复时使用的名称;否则,使用变量名。
# 例如:
# variables_to_restore = ema.variables_to_restore()
# saver = tf.train.Saver(variables_to_restore)
# 以下是返回的一个映射的示例:
# conv/batchnorm/gamma/ExponentialMovingAverage: conv/batchnorm/gamma,
# conv_4/conv2d_params/ExponentialMovingAverage: conv_4/conv2d_params,
# global_step: global_step

示例:参考链接

import os
import tensorflow as tf os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' # 创建待训练参数
variable1 = tf.Variable(initial_value=0, trainable=True, dtype=tf.float32)
# 训练次数,不可训练
step_var = tf.Variable(initial_value=0, trainable=False)
# 创建滑动平均对象
ema = tf.train.ExponentialMovingAverage(decay=0.999, num_updates=step_var)
# 计算变量variable1的滑动平均操作
maintain_average_op = ema.apply([variable1]) # 初始化操作
init_op = tf.global_variables_initializer() with tf.Session() as sess:
sess.run(init_op)
# 初始值输出
# 更新影子变量
sess.run(maintain_average_op)
# 输出变量和变量的影子变量
print(sess.run([variable1, ema.average(variable1)])) # 更新变量
sess.run(tf.assign(variable1, 5))
# 更新影子变量
# decay = min(decay, (1+step_var) / (10+step_var))
# shadow_variable = decay * shadow_variable + (1 - decay) * variable
sess.run(maintain_average_op)
# 输出变量和变量的影子变量
print(sess.run([variable1, ema.average(variable1)])) # 更新step_var
sess.run(tf.assign(step_var, 10000))
# 更新变量
sess.run(tf.assign(variable1, 10))
# 更新影子变量
sess.run(maintain_average_op)
# 输出变量和变量的影子变量
print(sess.run([variable1, ema.average(variable1)])) # 更新影子变量 # 更新影子变量
sess.run(maintain_average_op)
# 输出变量和变量的影子变量
print(sess.run([variable1, ema.average(variable1)]))

输出如下:

[0.0, 0.0]
[5.0, 4.5]
[10.0, 4.5054998]
[10.0, 4.5109944]

tensorflow入门笔记(二) 滑动平均模型的更多相关文章

  1. tensorflow笔记之滑动平均模型

    tensorflow使用tf.train.ExponentialMovingAverage实现滑动平均模型,在使用随机梯度下降方法训练神经网络时候,使用这个模型可以增强模型的鲁棒性(robust),可 ...

  2. Tensorflow滑动平均模型tf.train.ExponentialMovingAverage解析

    觉得有用的话,欢迎一起讨论相互学习~Follow Me 移动平均法相关知识 移动平均法又称滑动平均法.滑动平均模型法(Moving average,MA) 什么是移动平均法 移动平均法是用一组最近的实 ...

  3. tensorflow随机梯度下降算法使用滑动平均模型

    在采用随机梯度下降算法训练神经网络时,使用滑动平均模型可以提高最终模型在测试集数据上的表现.在Tensflow中提供了tf.train.ExponentialMovingAverage来实现滑动平均模 ...

  4. Tensorflow中的滑动平均模型

    原文链接 在Tensorflow的教程里面,使用梯度下降算法训练神经网络时,都会提到一个使模型更加健壮的策略,即滑动平均模型. 基本思想 在使用梯度下降算法训练模型时,每次更新权重时,为每个权重维护一 ...

  5. tensorflow学习笔记二:入门基础 好教程 可用

    http://www.cnblogs.com/denny402/p/5852083.html tensorflow学习笔记二:入门基础   TensorFlow用张量这种数据结构来表示所有的数据.用一 ...

  6. 1 TensorFlow入门笔记之基础架构

    ------------------------------------ 写在开头:此文参照莫烦python教程(墙裂推荐!!!) ---------------------------------- ...

  7. 78、tensorflow滑动平均模型,用来更新迭代的衰减系数

    ''' Created on 2017年4月21日 @author: weizhen ''' #4.滑动平均模型 import tensorflow as tf #定义一个变量用于计算滑动平均,这个变 ...

  8. tensorflow入门笔记(三) tf.GraphKeys

    tf.GraphKeys类存放了图集用到的标准名称. 该标准库使用各种已知的名称收集和检索图中相关的值.例如,tf.Optimizer子类在没有明确指定待优化变量的情况下默认优化被收集到tf.Grap ...

  9. 吴裕雄 PYTHON 神经网络——TENSORFLOW 滑动平均模型

    import tensorflow as tf v1 = tf.Variable(0, dtype=tf.float32) step = tf.Variable(0, trainable=False) ...

随机推荐

  1. 用HTML5+JS开发跨平台的桌面应用

    通过Node.js和WebKit技术的融合,开发者可以用HTML5技术编写UI,同时又能利用Node.js平台上众多library访问本地OS的能力,最终达到用Web技术就可以编写桌面应用的目的. 选 ...

  2. kafka性能测试1.0.0

    kafka提供工具kafka-producer-perf-test.sh用以压测, 参数 说明 messages 生产者发送总的消息数量 message-size 每条消息大小 batch-size ...

  3. python : 将txt文件中的数据读为numpy数组或列表

    很多时候,我们将数据存在txt或者csv格式的文件里,最后再用python读取出来,存到数组或者列表里,再做相应计算.本文首先介绍写入txt的方法,再根据不同的需求(存为数组还是list),介绍从tx ...

  4. Mysql系列八:Mycat和Sharding-jdbc的区别、Mycat分片join、Mycat分页中的坑、Mycat注解、Catlet使用

    一.Mycat和Sharding-jdbc的区别 1)mycat是一个中间件的第三方应用,sharding-jdbc是一个jar包 2)使用mycat时不需要改代码,而使用sharding-jdbc时 ...

  5. portfolio

    1.工作量计算逻辑: 原始待办事项: 预估2个冲刺,如下图所示: Sprint1的故事点计划工作量5,空闲工作量28.如下图 Sprint2为预估冲刺,指的是预估待办事项在后续冲刺的预估计划,后续冲刺 ...

  6. RedisLive监控工具 windows部署笔记

    1. Python2.7环境安装  Path环境变量中添加  2.下载安装 VC Compiler for Python  地址: http://www.microsoft.com/en-us/dow ...

  7. [JS] ECMAScript 6 - Prototype : compare with c#

    开胃菜 prototype 对象 JavaScript 语言的继承则是通过“原型对象”(prototype). function Cat(name, color) { // <----构造函数 ...

  8. [Laravel] 16 - DB: Eloquent

    前言 一.大纲 写后端API,与数据库打交道无疑是很重要的角色. PHP数据库操作:从MySQL原生API到PDO PHP数据库操作:使用ORM Ref: [PHP] 07 - Json, XML a ...

  9. 看看大网站都用什么操作系统和Web服务器

    以下内容为网络上转载总结,不是很准确 Google 用哪些软件做 Web Server? 除了有两个节点操作系统看出来是 Linux 外,其他的都是未知的. Web 服务器用的都是 GWS ? 我估计 ...

  10. C++定义字符数组

    问:C++中定义字符型数组时'\0'是不是也占一位?是不是定义char a[5],只能有4个字符?那计算字符长度时又否忽略'\0'? 答: C++中定义字符型数组时'\0'是不是也占一位?是不是定义c ...