文章目录

  • 一、VariableScope的reuse模式的设置
    • 1.1节
    • 1.2节
    • 1.3节
    • 1.4节
    • 1.5节
  • 二、reuse模式对tf.Variable() 的影响
  • 三、reuse模式对tf.get_variable()的影响
    • 3.1节
    • 3.2节
  • 附加1:tf.name_scope()与tf.variable_scope()的区别
  • 附加2:单机多GPU下的变量共享/复用

一、VariableScope的reuse模式的设置

1.1节

1、tf.get_variable_scope()可以获得当前的变量域,还可以通过其.name.reuse来查看其名称和当前是否为reuse模式。

2、变量域有name,变量也有name。默认变量作用域的name为空白字符串。

3、在变量域内命名的变量的name全称为:“变量域的name+变量定义时传入的name”(就像一个文件有名字作为标识符,但是在前面加上绝对路径就是它在整个文件系统中的全局标识符)。

这三点贯穿本文,如果不太清楚,可以直接看后面的多个例子,会不断地体现在代码中。

1.2节

with tf.variable_scope()可以打开一个变量域,有两个关键参数。name_or_scope参数可以是字符串或tf.VariableScope对象,reuse参数为布尔值,传入True表示设置该变量域为reuse模式。

还有一种方法可以将变量域设置为reuse模式,即使用VariableScope对象的reuse_variables()方法,例如tf.get_variable_scope().reuse_variables()可以将当前变量域设置为reuse模式。

with tf.variable_scope('vs1'):tf.get_variable_scope().reuse_variables()print('"'+tf.get_variable_scope().name+'"', tf.get_variable_scope().reuse)with tf.variable_scope('vs2',reuse=True):print('"'+tf.get_variable_scope().name+'"', tf.get_variable_scope().reuse)'''
"vs1" True
"vs2" True
'''

1.3节

对某变量域设置reuse模式,则reuse模式会被变量域的子域继承

# 注意,默认变量域的名称为空白字符串
tf.get_variable_scope().reuse_variables() # 将默认变量域设置为reuse模式
print('"'+tf.get_variable_scope().name+'"', tf.get_variable_scope().reuse) # 为了显示空白字符串,在名称两边加上双引号with tf.variable_scope('vs'): # vs是默认变量域的子域,故虽然没有明确设置vs的模式,但其也更改成了reuse模式print('"'+tf.get_variable_scope().name+'"', tf.get_variable_scope().reuse)'''输出为:
"" True
"vs" True'''

1.4节

每次在with块中设置变量域的模式,退出with块就会失效(恢复回原来的模式)。

with tf.variable_scope('vs1'):tf.get_variable_scope().reuse_variables()print('"'+tf.get_variable_scope().name+'"', tf.get_variable_scope().reuse)with tf.variable_scope('vs1'):print('"'+tf.get_variable_scope().name+'"', tf.get_variable_scope().reuse)'''输出为:
"vs1" True
"vs1" False'''

1.5节

可以使用一个变量域(tf.VariableScope对象)的引用来打开它,这样可以不用准确的记住其name的字符串。下面的例子来自tensorflow官网。

with tf.variable_scope("model") as scope:output1 = my_image_filter(input1)
with tf.variable_scope(scope, reuse=True):output2 = my_image_filter(input2)

tf.VariableScope对象作为with tf.variable_scope( name_or_scope ):的参数时,该with语句块的模式是该scope对应的模式。(下面的代码同时也展现了前面所说的“继承”和“失效”的现象。)

with tf.variable_scope('vs1'):tf.get_variable_scope().reuse_variables()print('"'+tf.get_variable_scope().name+'"', tf.get_variable_scope().reuse)with tf.variable_scope('vs2') as scope: # vs2(全称是vs1/vs2)将会继承vs1的reuse模式print('"'+tf.get_variable_scope().name+'"', tf.get_variable_scope().reuse)# 重新用with打开vs1和vs2,他们的reuse模式不受之前with块中的设置的影响
with tf.variable_scope('vs1'): print('"'+tf.get_variable_scope().name+'"', tf.get_variable_scope().reuse)with tf.variable_scope('vs2'):print('"'+tf.get_variable_scope().name+'"', tf.get_variable_scope().reuse)# tf.variable_scope也可以传入tf.VariableScope类型的变量,此处的scope是第4行with语句中定义的
with tf.variable_scope(scope): print('"'+tf.get_variable_scope().name+'"', tf.get_variable_scope().reuse)
# 第二个with中, vs1/vs2的reuse模式为False,即前面所说的退出with块之后reuse模式的设置“失效”
# 但是第三个with中,vs1/vs2的reuse却为True,这是因为当`name_or_scope`参数是tf.VariableScope对象时,
# 其打开的变量域的reuse模式由这个参数scope决定。
# 此处的`scope`在第4行定义,“继承”vs1的reuse,且之后没有改变,所以第三个with打开的就是reuse=True'''输出为:
"vs1" True
"vs1/vs2" True
"vs1" False
"vs1/vs2" False
"vs1/vs2" True'''

二、reuse模式对tf.Variable() 的影响

tf.Variable() 只有新建变量的功能,一个变量域是否为reuse模式不影响tf.Variable()的作用。如果该变量域中已经有同名的变量,则新建的变量会被重命名,加上数字后缀以区分。

print('"'+tf.get_variable_scope().name+'"', tf.get_variable_scope().reuse)
v1=tf.Variable(tf.constant(1),name='v')
v2=tf.Variable(tf.constant(1),name='v')tf.get_variable_scope().reuse_variables()
print('"'+tf.get_variable_scope().name+'"', tf.get_variable_scope().reuse)v3=tf.Variable(tf.constant(1),name='v') # 在reuse模式下使用tf.Variable(),仍然会新建,故v3名称为v_2print(v1.name)
print(v2.name)
print(v3.name)'''输出为:
"" False
"" True
v:0
v_1:0
v_2:0'''

三、reuse模式对tf.get_variable()的影响

reuse模式会对tf.get_variable()的实际效果有决定作用。

3.1节

在non-reuse模式下,tf.get_variable()作用为新建变量(设为v)。若变量域内已经有同名变量(设为w),则分两种情况:

  1. w是之前通过tf.Variable()创建的,则v将被重命名,即加上数字后缀。
  2. w是之前通过tf.get_variable()创建的,则不允许新建同名变量v
with tf.variable_scope('vs'):# 打印当前scope的名称和是否为reuse模式print('"'+tf.get_variable_scope().name+'"', tf.get_variable_scope().reuse) v1=tf.Variable(tf.constant(1),name='v')print(v1.name) # 前缀为scope的名称加一个反斜线,即“vs/”,故全称为“vs/v:0”,“冒号0”的解释见后文。v2=tf.get_variable('v',shape=()) print(v2.name) # 已经有名为v的变量,故v2的name会在v后面加上数字后缀(从1开始)v3=tf.get_variable('v',shape=()) # 已经有名为v且由tf.get_variable创建的变量,故v3的创建抛出异常print(v3.name)

输出为:(题外话,“:0” 指的是该变量是创建它的operation的第一个输出,见 这个链接)

"vs" False
vs/v:0
vs/v_1:0
--------------------------------------------------------------------------ValueError                               Traceback (most recent call last)<ipython-input-2-e0b97b39994d> in <module>()5     v2=tf.get_variable('v',shape=())6     print(v2.name)
----> 7     v3=tf.get_variable('v',shape=())8     print(v3.name)9<省略部分输出>
ValueError: Variable vs/v already exists, disallowed. Did you mean to set reuse=True or reuse=tf.AUTO_REUSE in VarScope?

3.2节

在reuse模式下,tf.get_variable()作用为重用(reuse)变量。注意只能重用之前在本变量域创建的、且使用tf.get_variable()创建的变量,即不能在本变量域中重用其他变量域中创建的变量,也不能重用那些使用tf.Variable()创建的变量。

1.重用变量

with tf.variable_scope('vs'):print('"'+tf.get_variable_scope().name+'"', tf.get_variable_scope().reuse)v=tf.get_variable('v',shape=())print(v.name)with tf.variable_scope('vs',reuse=True):print('"'+tf.get_variable_scope().name+'"', tf.get_variable_scope().reuse)reused_v=tf.get_variable('v',shape=()) # reused_v就是之前的v,他们是共享内存的变量print(reused_v.name)'''输出为:
"vs" False
vs/v:0
"vs" True
vs/v:0'''

2.不能重用其他变量域中命名的变量(相当于你在A文件夹新建了v.txt,但是不能到B文件夹里面找v.txt)。

# 在vs变量域新建v,尝试到vs1中重用变量
with tf.variable_scope('vs'):print('"'+tf.get_variable_scope().name+'"', tf.get_variable_scope().reuse)v=tf.get_variable('v',shape=())# v=tf.Variable(tf.constant(1),name='v')print(v.name)with tf.variable_scope('vs1',reuse=True):print('"'+tf.get_variable_scope().name+'"', tf.get_variable_scope().reuse)# 下一行会报错,因为vs1这个变量域并没有用get_variable()创建过名为v的变量reused_v=tf.get_variable('v',shape=()) print(reused_v.name)'''
报错:
ValueError: Variable vs1/v does not exist, or was not created with tf.get_variable(). Did you mean to set reuse=tf.AUTO_REUSE in VarScope?
'''

3.只能重用那些使用tf.get_variable()创建的变量,而不能重用那些使用tf.Variable()创建的变量。

with tf.variable_scope('vs'):print('"'+tf.get_variable_scope().name+'"', tf.get_variable_scope().reuse)v=tf.Variable(tf.constant(1),name='v')print(v.name)with tf.variable_scope('vs',reuse=True):print('"'+tf.get_variable_scope().name+'"', tf.get_variable_scope().reuse)reused_v=tf.get_variable('v',shape=())print(reused_v.name)

输出为:

"vs" False
vs/v:0
"vs" True
--------------------------------------------------------------------------ValueError                               Traceback (most recent call last)<ipython-input-2-63ddfa598083> in <module>()6 with tf.variable_scope('vs',reuse=True):7     print('"'+tf.get_variable_scope().name+'"', tf.get_variable_scope().reuse)
----> 8     reused_v=tf.get_variable('v',shape=())9     print(reused_v.name)10<省略部分输出>ValueError: Variable vs/v does not exist, or was not created with tf.get_variable(). Did you mean to set reuse=tf.AUTO_REUSE in VarScope?

附加1:tf.name_scope()与tf.variable_scope()的区别

tf.name_scope()tf.variable_scope()的功能很像,这里也顺便探讨一下他们的区别,以助于加深对两个方法的理解。

本小节参考自 这篇知乎文章

with tf.name_scope('ns'):print('"'+tf.get_variable_scope().name+'"', tf.get_variable_scope().reuse)v1=tf.get_variable('v',shape=())v2=tf.Variable(tf.constant(1),name='v')print(v1.name)print(v2.name)with tf.variable_scope('vs'):print('"'+tf.get_variable_scope().name+'"', tf.get_variable_scope().reuse)v3=tf.get_variable('v',shape=())v4=tf.Variable(tf.constant(1),name='v')print(v3.name)print(v4.name)with tf.variable_scope('vs'):with tf.name_scope('ns'):v5=tf.Variable(tf.constant(1),name='v')print(v5.name)v6=tf.get_variable('v',shape=()) # 这里将会抛出异常print(v6.name)

输出如下,解释见对应的注释:

"" False   # 1.with打开NameScope并不影响所在的VariableScope
v:0        # 2.NameScope对于以tf.get_variable()新建的变量的命名不会有影响
ns/v:0     # 3.对于以tf.Variable()方式新建的变量的命名,会加上NameScope的名字作为前缀
"vs" False # 4.印证了第1点
vs/v:0     # 5.印证了第2点
ns/vs/v:0  # 6.对于被多层NameScope和VariableScope包围的、以tf.Variable()新建的变量,其命名以嵌套顺序来确定前缀
vs/ns/v:0  # 7.印证了第6点
# 下面的异常是由v6=tf.get_variable('v',shape=())导致的
# 因为tf.get_variable()获得的变量的命名不受NameScope影响,所以这里其实对应了3.1节第2点的情况
# 即在相同的VariableScope中使用tf.get_variable()定义了重名的变量
Traceback (most recent call last):File "scope.py", line 79, in <module>v6=tf.get_variable('v',shape=())File "C:\Users\pyxies\Anaconda3\lib\site-packages\tensorflow\python\ops\variable_scope.py", line 1203, in get_variableconstraint=constraint)File "C:\Users\pyxies\Anaconda3\lib\site-packages\tensorflow\python\ops\variable_scope.py", line 1092, in get_variableconstraint=constraint)File "C:\Users\pyxies\Anaconda3\lib\site-packages\tensorflow\python\ops\variable_scope.py", line 425, in get_variableconstraint=constraint)File "C:\Users\pyxies\Anaconda3\lib\site-packages\tensorflow\python\ops\variable_scope.py", line 394, in _true_getteruse_resource=use_resource, constraint=constraint)File "C:\Users\pyxies\Anaconda3\lib\site-packages\tensorflow\python\ops\variable_scope.py", line 742, in _get_single_variablename, "".join(traceback.format_list(tb))))
ValueError: Variable vs/v already exists, disallowed. Did you mean to set reuse=True or reuse=tf.AUTO_REUSE in VarScope?

附加2:单机多GPU下的变量共享/复用

见 https://blog.csdn.net/xpy870663266/article/details/99330338

tensorflow变量共享——VariableScope的reuse模式、tf.get_variable()、tf.Variable() 探索相关推荐

  1. tensorflow 变量及命名空间 tf.Variable() vs tf.get_variable() tf.name_scope() vs tf.variable_scope()

    tf.Variable() vs tf.get_variable() tf.name_scope() vs tf.variable_scope() 1. 基础功能 1.1 tf.Variable() ...

  2. TensorFlow 变量共享,命名空间

    原文出处: http://blog.csdn.NET/Jerr__y/article/details/70809528 前言: 本例子主要介绍 name_scope 和 variable_scope ...

  3. tf.Variable,tf.get_variable,tf.variable_scope,tf.name_scope区别分析

    1.tf.Variable与tf.get_variable ①在创建变量的时候,两者是等价的 ②tf.Variable的变量名是一个可选项,而tf.get_variable必须要有变量名 import ...

  4. 【TensorFlow】TensorFlow函数精讲之tf.get_variable()和tf.get_variable_scope()

    目录 1.tf.get_variable() 2.tf.variable_scope() 3.tf.variable_scope() 函数嵌套 1.tf.get_variable() tf.get_v ...

  5. TensorFlow基础篇(二)——tf.get_variable()和tf.get_variable_scope()

    1.tf.get_variable() tf.get_variable()用来创建变量时,和tf.Variable()函数的功能基本等价. v = tf.get_variable("v&qu ...

  6. tf.Variable() 和 tf.get_variable(),tf.name_scope() 和 tf.variable_scope()

    在gpu并行训练网络时,往往需要共享已创建的变量,tensorflow中为了使这些变量名和操作名唯一并且不重复,用了几个函数来应对这种情况.于是就有了tf.Variable(), tf.get_var ...

  7. tf.variable和tf.get_Variable以及tf.name_scope和tf.variable_scope的区别

    在训练深度网络时,为了减少需要训练参数的个数(比如具有simase结构的LSTM模型).或是多机多卡并行化训练大数据大模型(比如数据并行化)等情况时,往往需要共享变量.另外一方面是当一个深度学习模型变 ...

  8. tf.Variable、tf.get_variable、tf.variable_scope、tf.name_scope、random、initializer

    转自:tensorflow学习笔记(二十三):variable与get_variable TF.VARIABLE.TF.GET_VARIABLE.TF.VARIABLE_SCOPE以及TF.NAME_ ...

  9. Tensorflow 变量的共享

    https://github.com/chenghuige/tensorflow-exp/blob/master/examples/sparse-tensor-classification/ tens ...

最新文章

  1. narray删除列 python_Python数据分析入门教程(四):数值操作
  2. Service生命周期
  3. POJ 1745 Divisibility DP
  4. python3 一 多线程死锁问题及解决方案
  5. MySQL学习笔记:MySQL管理
  6. Java虚拟机学习总结(1)——JVM内存模型
  7. HTTP 500 - 内部服务器错误的解决
  8. 3013C语言_输入输出
  9. linux查看所有目录
  10. 看jQuery源码的技巧
  11. 彩虹自助下单平台对接爱代挂插件程序
  12. 奥拉星插件flash下载手机版下载安装_flash插件
  13. 康佳电视手机遥控器android版,康佳电视遥控器
  14. TeamViewer远程控制软件的许可证有什么用处
  15. Arduino 通过双路L298N电机驱动模块控制麦克纳姆轮运动
  16. zencart的html文件,zencart模板 哪儿有zencart免费模版?
  17. 数据库学习7 — 嵌套查询
  18. native聊天界面 react_ReactNative 聊天 App 实战|RN 仿微信界面群聊|朋友圈
  19. java定时执行bat_windows定时器配置执行java jar文件的方法详解
  20. pdf.js 修改预览页面title

热门文章

  1. 通用文件模型及VFS-VFS结构
  2. matlab解方程x 2-x-2=0,matlab用三种方法求解二阶微分方程x''+0.2x'=0.4x=0.2u(t),u(t)是单位阶跃函数,初始状态为0...
  3. Microsoft CryptoAPI加密技术
  4. iframe相关case之allowTransparency属性
  5. lcc源代码详解之介绍
  6. CF1095D Circular Dance
  7. 集合————示例详解
  8. 第6节 寻找主力踪迹——大宗交易数据解读
  9. 日常生活英语单词大全(转)
  10. 我所体验的HP金牌售后服务