在训练深度网络时,为了减少需要训练参数的个数(比如具有simase结构的LSTM模型)、或是多机多卡并行化训练大数据大模型(比如数据并行化)等情况时,往往需要共享变量。另外一方面是当一个深度学习模型变得非常复杂的时候,往往存在大量的变量和操作,如何避免这些变量名和操作名的唯一不重复,同时维护一个条理清晰的graph非常重要。

因此,tensorflow中用tf.Variable(),tf.get_variable(),tf.Variable_scope(),tf.name_scope()几个函数来实现:


一、tf.Variable(<variable_name>),tf.get_variable(<variable_name>)的作用与区别:

tf.Variable(<variable_name>)和tf.get_variable(<variable_name>)都是用于在一个name_scope下面获取或创建一个变量的两种方式,区别在于:

  1. tf.Variable(<variable_name>)会自动检测命名冲突并自行处理,但tf.get_variable(<variable_name>)则遇到重名的变量创建且变量名没有设置为共享变量时,则会报错。
  2. tf.Variable(<variable_name>)用于创建一个新变量,在同一个name_scope下面,可以创建相同名字的变量,底层实现会自动引入别名机制,两次调用产生了其实是两个不同的变量。

    tf.get_variable(<variable_name>)用于获取一个变量,并且不受name_scope的约束。当这个变量已经存在时,则自动获取;如果不存在,则自动创建一个变量。
二、tf.name_scope(<scope_name>)与tf.variable_scope(<scope_name>)的作用与区别:

tf.name_scope(<scope_name>):主要用于管理一个图里面的各种op,返回的是一个以scope_name命名的context manager。一个graph会维护一个name_space的

堆,每一个namespace下面可以定义各种op或者子namespace,实现一种层次化有条理的管理,避免各个op之间命名冲突。

tf.variable_scope(<scope_name>):一般与tf.name_scope()配合使用,用于管理一个graph中变量的名字,避免变量之间的命名冲突,tf.variable_scope(<scope_name>)允许在一个variable_scope下面共享变量。

代码示例:

在 tf.name_scope下时,tf.get_variable()创建的变量名不受 name_scope 的影响,而且在未指定共享变量时,如果重名会报错,tf.Variable()会自动检测有没有变量重名,如果有则会自行处理。

import tensorflow as tf

with tf.name_scope('name_scope_x'):
var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32)
var3 = tf.Variable(name='var2', initial_value=[2], dtype=tf.float32)
var4 = tf.Variable(name='var2', initial_value=[2], dtype=tf.float32) with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(var1.name, sess.run(var1))
print(var3.name, sess.run(var3))
print(var4.name, sess.run(var4))
# 输出结果:
# var1:0 [-0.30036557] 可以看到前面不含有指定的'name_scope_x'
# name_scope_x/var2:0 [ 2.]
# name_scope_x/var2_1:0 [ 2.] 可以看到变量名自行变成了'var2_1',避免了和'var2'冲突

如果使用tf.get_variable()创建变量,且没有设置共享变量,重名时会报错

import tensorflow as tf

with tf.name_scope('name_scope_1'):
var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32)
var2 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(var1.name, sess.run(var1))
print(var2.name, sess.run(var2)) # ValueError: Variable var1 already exists, disallowed. Did you mean
# to set reuse=True in VarScope? Originally defined at:
# var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32)

所以要共享变量,需要使用tf.variable_scope()

import tensorflow as tf

with tf.variable_scope('variable_scope_y') as scope:
var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32)
scope.reuse_variables() # 设置共享变量
var1_reuse = tf.get_variable(name='var1')
var2 = tf.Variable(initial_value=[2.], name='var2', dtype=tf.float32)
var2_reuse = tf.Variable(initial_value=[2.], name='var2', dtype=tf.float32) with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(var1.name, sess.run(var1))
print(var1_reuse.name, sess.run(var1_reuse))
print(var2.name, sess.run(var2))
print(var2_reuse.name, sess.run(var2_reuse))
# 输出结果:
# variable_scope_y/var1:0 [-1.59682846]
# variable_scope_y/var1:0 [-1.59682846] 可以看到变量var1_reuse重复使用了var1
# variable_scope_y/var2:0 [ 2.]
# variable_scope_y/var2_1:0 [ 2.]

tf.variable和tf.get_Variable以及tf.name_scope和tf.variable_scope的区别的更多相关文章

  1. 理解 tf.Variable、tf.get_variable以及范围命名方法tf.variable_scope、tf.name_scope

    tensorflow提供了通过变量名称来创建或者获取一个变量的机制.通过这个机制,在不同的函数中可以直接通过变量的名字来使用变量,而不需要将变量通过参数的形式到处传递. 1. tf.Variable( ...

  2. tf.Variable

    tf.Variable __init__( initial_value=None, trainable=True, collections=None, validate_shape=True, cac ...

  3. TF.VARIABLE、TF.GET_VARIABLE、TF.VARIABLE_SCOPE以及TF.NAME_SCOPE关系

    1. tf.Variable与tf.get_variable tensorflow提供了通过变量名称来创建或者获取一个变量的机制.通过这个机制,在不同的函数中可以直接通过变量的名字来使用变量,而不需要 ...

  4. 彻底弄懂tf.Variable、tf.get_variable、tf.variable_scope以及tf.name_scope异同

    https://blog.csdn.net/qq_22522663/article/details/78729029 1. tf.Variable与tf.get_variabletensorflow提 ...

  5. tensorflow共享变量 the difference between tf.Variable() and get_variable()

    一般这样用tf.get_variable(): v = tf.get_variable(name, shape, dtype, initializer) 下面内容来源于 http://blog.csd ...

  6. tf.Variable() 与tf.get_variable()的区别

    每次调用 tf.Variable() 都会产生一个新的变量,变量名称是一个可选参数,运行命名相同,如果命名冲突会根据命名先后对名字进行处理, tf.get_variable()的变量名称是必填参数,t ...

  7. TensorFlow函数(二)tf.get_variable() 和 tf.Variable()

    tf.Variable(<initial - value>,name=<optional - name>) 此函数用于定义图变量.生成一个初始值为initial - value ...

  8. tf.Variable()、tf.get_variable()和tf.placeholder()

    1.tf.Variable() tf.Variable(initializer,name) 功能:tf.Variable()创建变量时,name属性值允许重复,检查到相同名字的变量时,由自动别名机制创 ...

  9. tf.name_scope()和tf.variable_scope() (转)

    网络层中变量存在两个问题: 随着层数的增多,导致变量名的增多: 在调用函数的时候,会重复生成变量,但他们存储的都是一样的变量.   tf.variable不能解决这个问题. 变量作用域使用tf.var ...

随机推荐

  1. java面向对象的三大特性——封装

    封装 封装从字面上来理解就是包装的意思,专业点就是信息隐藏,是指利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体,数据被保护在抽象数据类型的内部,尽可能地隐藏内部的细节 ...

  2. GPU 实现 RGB -- YUV 转换 (OpenGL)

    GPU 实现 RGB -- YUV 转换 前言 RGB --> YUV 转换的公式是现成的,直接在 CPU 端转换的话,只需要遍历每个像素,得到新的 YUV 值,根据其内存分布规律,合理安排分布 ...

  3. JDK自带的日志Logging

    OK,现在我们来研究下JDK自带的日志Logger. 从jdk1.4起,JDK开始自带一套日志系统.JDK Logger最大的优点就是不需要任何类库的支持,只要有Java的运行环境就可以使用. 相对于 ...

  4. TDD入门demo

    OK,前面的博客整理了一系列的junit相关内容,这里举一个例子TDD实际的编码例子,不管实际编码中是否使用TDD,个人觉得这种思想必须要有. 我们不一定在写业务代码之前一定要说是把测试类都写出来,至 ...

  5. U盘安装CentOS 7问题解决

    1 使用U盘安装最新版Centos时报错(CentOS-7-x86_64-DVD-1503-01): 错误提示:"Warning:could not boot;Warning: /dev/r ...

  6. maven系列--maven目录

    我们在玩maven,首先就是利用maven来管理我们的项目.其实maven并不难,它无非是一种目录结构.所以在本系列开始之前,我们要细致的了解下maven的目录,其实也就是maven的约定. 约定优于 ...

  7. css3 box-shadow让我们实现图层阴影效果

    box-shadow box-shadow: h-shadow v-shadow blur spread color inset;box-shadow:2px 2px 3px rgba(50,50,5 ...

  8. 理解Object.defineProperty的作用

    对象是由多个名/值对组成的无序的集合.对象中每个属性对应任意类型的值.定义对象可以使用构造函数或字面量的形式: var obj = new Object; //obj = {} obj.name = ...

  9. 刚买个炼狱蝰蛇1800dpi的下完驱动提示没有发现鼠标

    2017-02-19补充:可以下载下面的程序 ,也可以访问 http://cn.razerzone.com/synapse/  下载雷云 也可解决问题 ------------------------ ...

  10. word文字覆盖问题

    我们在编写word文档时,偶尔会遇到这个问题: 在一个段落中的某个位置修改文字时,直接就把后面的字体给覆盖了,导致后面的句子也不完整了. 解决经过: 之前遇到这种情况,非常恼火,直接新建一个word文 ...