TensorFlow 滑动平均的示例代码


Posted in Python onJune 19, 2018

滑动平均会为目标变量维护一个影子变量,影子变量不影响原变量的更新维护,但是在测试或者实际预测过程中(非训练时),使用影子变量代替原变量。

1、滑动平均求解对象初始化

ema = tf.train.ExponentialMovingAverage(decay,num_updates)

参数decay

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

参数num_updates

`min(decay, (1 + num_updates) / (10 + num_updates))`

2、添加/更新变量

添加目标变量,为之维护影子变量

注意维护不是自动的,需要每轮训练中运行此句,所以一般都会使用tf.control_dependencies使之和train_op绑定,以至于每次train_op都会更新影子变量

ema.apply([var0, var1])

3、获取影子变量值

这一步不需要定义图中,从影子变量集合中提取目标值

sess.run(ema.average([var0, var1]))

4、保存&载入影子变量

我们知道,在TensorFlow中,变量的滑动平均值都是由影子变量所维护的,如果你想要获取变量的滑动平均值需要获取的是影子变量而不是变量本身。

保存影子变量

建立tf.train.ExponentialMovingAverage对象后,Saver正常保存就会存入影子变量,命名规则是"v/ExponentialMovingAverage"对应变量”v“

import tensorflow as tf 
if __name__ == "__main__": 

  v = tf.Variable(0.,name="v") 

  #设置滑动平均模型的系数 

  ema = tf.train.ExponentialMovingAverage(0.99) 

  #设置变量v使用滑动平均模型,tf.all_variables()设置所有变量 

  op = ema.apply([v]) 

  #获取变量v的名字 

  print(v.name) 

  #v:0 

  #创建一个保存模型的对象 

  save = tf.train.Saver() 

  sess = tf.Session() 

  #初始化所有变量 

  init = tf.initialize_all_variables() 

  sess.run(init) 

  #给变量v重新赋值 

  sess.run(tf.assign(v,10)) 

  #应用平均滑动设置 

  sess.run(op) 

  #保存模型文件 

  save.save(sess,"./model.ckpt") 

  #输出变量v之前的值和使用滑动平均模型之后的值 

  print(sess.run([v,ema.average(v)])) 

  #[10.0, 0.099999905]

载入影子变量并映射到变量

利用了Saver载入模型的变量名映射功能,实际上对所有的变量都可以如此操作『TensorFlow』模型载入方法汇总

v = tf.Variable(1.,name="v") 

#定义模型对象 

saver = tf.train.Saver({"v/ExponentialMovingAverage":v}) 

sess = tf.Session() 

saver.restore(sess,"./model.ckpt") 

print(sess.run(v)) 

#0.0999999

这里特别需要注意的一个地方就是,在使用tf.train.Saver函数中,所传递的模型参数是{"v/ExponentialMovingAverage":v}而不是{"v":v},如果你使用的是后面的参数,那么你得到的结果将是10而不是0.09,那是因为后者获取的是变量本身而不是影子变量。

使用这种方式来读取模型文件的时候,还需要输入一大串的变量名称。

variables_to_restore函数的使用

v = tf.Variable(1.,name="v") 

#滑动模型的参数的大小并不会影响v的值 

ema = tf.train.ExponentialMovingAverage(0.99) 

print(ema.variables_to_restore()) 

#{'v/ExponentialMovingAverage': <tf.Variable 'v:0' shape=() dtype=float32_ref>} 

sess = tf.Session() 

saver = tf.train.Saver(ema.variables_to_restore()) 

saver.restore(sess,"./model.ckpt") 

print(sess.run(v)) 

#0.0999999

variables_to_restore会识别网络中的变量,并自动生成影子变量名。

通过使用variables_to_restore函数,可以使在加载模型的时候将影子变量直接映射到变量的本身,所以我们在获取变量的滑动平均值的时候只需要获取到变量的本身值而不需要去获取影子变量。

5、官方文档例子

官方文档中将每次apply更新就会自动训练一边模型,实际上可以反过来两者关系,《tf实战google》P128中有示例

| Example usage when creating a training model:
 | 
 | ```python
 | # 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...
 | ```

6、batch_normal的例子

和上面不太一样的是,batch_normal中不太容易绑定到train_op(位于函数体外面),则强行将两个variable的输出过程化为节点,绑定给参数更新步骤

def batch_norm(x,beta,gamma,phase_train,scope='bn',decay=0.9,eps=1e-5):

  with tf.variable_scope(scope):

    # beta = tf.get_variable(name='beta', shape=[n_out], initializer=tf.constant_initializer(0.0), trainable=True)

    # gamma = tf.get_variable(name='gamma', shape=[n_out],

    #             initializer=tf.random_normal_initializer(1.0, stddev), trainable=True)

    batch_mean,batch_var = tf.nn.moments(x,[0,1,2],name='moments')

    ema = tf.train.ExponentialMovingAverage(decay=decay)

 

    def mean_var_with_update():

      ema_apply_op = ema.apply([batch_mean,batch_var])

      with tf.control_dependencies([ema_apply_op]):

        return tf.identity(batch_mean),tf.identity(batch_var)

        # identity之后会把Variable转换为Tensor并入图中,

        # 否则由于Variable是独立于Session的,不会被图控制control_dependencies限制

 

    mean,var = tf.cond(phase_train,

              mean_var_with_update,

              lambda: (ema.average(batch_mean),ema.average(batch_var)))

   normed = tf.nn.batch_normalization(x, mean, var, beta, gamma, eps)

  return normed

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
从零学python系列之教你如何根据图片生成字符画
May 23 Python
跟老齐学Python之网站的结构
Oct 24 Python
Python调用SQLPlus来操作和解析Oracle数据库的方法
Apr 09 Python
详解Python中 __get__和__getattr__和__getattribute__的区别
Jun 16 Python
Python端口扫描简单程序
Nov 10 Python
python使用mitmproxy抓取浏览器请求的方法
Jul 02 Python
用Python从0开始实现一个中文拼音输入法的思路详解
Jul 20 Python
详解python中*号的用法
Oct 21 Python
python根据文本生成词云图代码实例
Nov 15 Python
Python hashlib加密模块常用方法解析
Dec 18 Python
TensorFlow实现指数衰减学习率的方法
Feb 05 Python
利用pipenv和pyenv管理多个相互独立的Python虚拟开发环境
Nov 01 Python
python3个性签名设计实现代码
Jun 19 #Python
TensorFlow 模型载入方法汇总(小结)
Jun 19 #Python
python3爬虫之设计签名小程序
Jun 19 #Python
Python GUI Tkinter简单实现个性签名设计
Jun 19 #Python
TensorFlow数据输入的方法示例
Jun 19 #Python
深入分析python中整型不会溢出问题
Jun 18 #Python
Python登录注册验证功能实现
Jun 18 #Python
You might like
高分R级DC动画剧《哈莉·奎茵》第二季正式预告首发
2020/04/09 欧美动漫
一步一步学习PHP(8) php 数组
2010/03/05 PHP
php 生成唯一id的几种解决方法
2013/03/08 PHP
解析php mysql 事务处理回滚操作(附实例)
2013/08/05 PHP
Yii净化器CHtmlPurifier用法示例(过滤不良代码)
2016/07/15 PHP
php实现替换手机号中间数字为*号及隐藏IP最后几位的方法
2016/11/16 PHP
浅谈ThinkPHP5.0版本和ThinkPHP3.2版本的区别
2017/06/17 PHP
浅谈laravel5.5 belongsToMany自身的正确用法
2019/10/17 PHP
tp5框架基于Ajax实现列表无刷新排序功能示例
2020/02/10 PHP
Array对象方法参考
2006/10/03 Javascript
jQuery实现表格展开与折叠的方法
2015/05/04 Javascript
readonly和disabled属性的区别
2015/07/26 Javascript
JS实现带有抽屉效果的产品类网站多级导航菜单代码
2015/09/15 Javascript
JS实现超简洁网页title标题跑动闪烁提示效果代码
2015/10/23 Javascript
node.js require() 源码解读
2015/12/13 Javascript
JavaScript操作HTML DOM节点的基础教程
2016/03/11 Javascript
jQuery layui常用方法介绍
2016/07/25 Javascript
jquery实现点击页面回到顶部
2016/11/23 Javascript
js 数字、字符串、布尔值的转换方法(必看)
2017/04/07 Javascript
Angularjs 实现动态添加控件功能
2017/05/25 Javascript
详解React-Native解决键盘遮挡问题(Keyboard遮挡问题)
2017/07/13 Javascript
浅谈JS获取元素的N种方法及其动静态讨论
2017/08/25 Javascript
JavaScript对象的浅拷贝与深拷贝实例分析
2018/07/25 Javascript
JQuery样式与属性设置方法分析
2019/12/07 jQuery
基于jQuery实现挂号平台首页源码
2020/01/06 jQuery
javascript设计模式 ? 桥接模式原理与应用实例分析
2020/04/13 Javascript
VUE项目axios请求头更改Content-Type操作
2020/07/24 Javascript
Python中模拟enum枚举类型的5种方法分享
2014/11/22 Python
Python两个内置函数 locals 和globals(学习笔记)
2016/08/28 Python
python中的随机函数random的用法示例
2018/01/27 Python
CSS3中border-radius属性设定圆角的使用技巧
2016/05/10 HTML / CSS
建筑装饰学院室内设计专业个人自我评价
2013/12/07 职场文书
读书活动总结
2014/04/28 职场文书
初中学习计划书范文
2014/09/15 职场文书
2015年度考核个人工作总结
2015/10/24 职场文书
vue项目支付功能代码详解
2022/02/18 Vue.js