在训练深度网络时,为了减少需要训练参数的个数(比如具有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()会自动检测有没有变量重名,如果有则会自行处理。

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

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

  1. import tensorflow as tf
  2. with tf.name_scope('name_scope_1'):
  3. var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32)
  4. var2 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32)
  5. with tf.Session() as sess:
  6. sess.run(tf.global_variables_initializer())
  7. print(var1.name, sess.run(var1))
  8. print(var2.name, sess.run(var2))
  9. # ValueError: Variable var1 already exists, disallowed. Did you mean
  10. # to set reuse=True in VarScope? Originally defined at:
  11. # var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32)

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

  1. import tensorflow as tf
  2. with tf.variable_scope('variable_scope_y') as scope:
  3. var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32)
  4. scope.reuse_variables() # 设置共享变量
  5. var1_reuse = tf.get_variable(name='var1')
  6. var2 = tf.Variable(initial_value=[2.], name='var2', dtype=tf.float32)
  7. var2_reuse = tf.Variable(initial_value=[2.], name='var2', dtype=tf.float32)
  8. with tf.Session() as sess:
  9. sess.run(tf.global_variables_initializer())
  10. print(var1.name, sess.run(var1))
  11. print(var1_reuse.name, sess.run(var1_reuse))
  12. print(var2.name, sess.run(var2))
  13. print(var2_reuse.name, sess.run(var2_reuse))
  14. # 输出结果:
  15. # variable_scope_y/var1:0 [-1.59682846]
  16. # variable_scope_y/var1:0 [-1.59682846] 可以看到变量var1_reuse重复使用了var1
  17. # variable_scope_y/var2:0 [ 2.]
  18. # 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. springboot之fastjson

    <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifac ...

  2. Go_Hello word

    与Go相关直接命令有哪些? go get    获取远程包 go run    直接运行程序 go bulid  测试编译 go fmt    格式化代码 go install       编译包文件 ...

  3. linkin大话面向对象--java关键字

    java中的关键字有以下几个,他们不能作任何其它的用途. 发现没,java中的关键字全是小写,java是严格区分大小写的. abstract  default  null  synchronized ...

  4. Storm容错和高可用

    Daemon Fault Tolerance Storm有一些不同的守护进程 Nimbus负责调度workers supervisors负责运行和杀死workers log views负责访问日志 U ...

  5. PMS 启动流程

    1.在SystemServer中启动PackageManagerService.main 2.newPackageManagerService()并添加到ServiceManager中 3.newin ...

  6. tomcat无法打开8080页面

    tomcat已启动 app已经正常执行 但不能打开8080管理页面 可能是在webapps目录下没有ROOT目录

  7. C之多线程(例子很不错)

    1.线程 线程池是一个树状结构. 多线程解决并发问题. 一个线程内部的执行顺序是线性的.而线程之间是乱序的. 若要创建一个多线程程序,它的参数必须是空指针类型. 变色龙程序: #define _CRT ...

  8. java基础(六) switch语句的深入解析

    引言   switch 语句是非常的基础的知识,掌握起来也不难掌握,语法比较简单.但大部分人基本是知其然,不知其所以然.譬如 早期JDK只允许switch的表达式的值 int及int类型以下的基本类型 ...

  9. Java设计模式之策略模式与状态模式

    版权声明:本文出自汪磊的博客,转载请务必注明出处. 一.策略模式定义 定义:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使他们之间可以相互替换,策略模式可以在不影响客户端的情况下发生变化. ...

  10. BZOJ 4408: [Fjoi 2016]神秘数 [主席树]

    传送门 题意: 一个可重复数字集合S的神秘数定义为最小的不能被S的子集的和表示的正整数.例如S={1,1,1,4,13},8无法表示为集合S的子集的和,故集合S的神秘数为8.现给定n个正整数a[1]. ...