TensorFlow学习记录:variable_scope()和name_scope()函数的区别

1.variable_scope()

1.1 variable_scope() 对get_variable()的影响

首先,我们在相同的variable_scope内使用get_variable()函数创建一个name属性为a的变量a1

import tensorflow as tf
with tf.variable_scope("one"):
	a1=tf.get_variable("a",[1],initializer=tf.constant_initializer(1.0))
print(a1.name)
#输出:one/a:0

然后我们再在同一个variable_scope内内使用get_variable()函数创建一个name也属性为a的变量a2

import tensorflow as tf
with tf.variable_scope("one"):
	a2=tf.get_variable("a",[1])
print(a2.name)
#输出:Variable one/a already exists, disallowed. Did you mean to set reuse=True or reuse=tf.AUTO_REUSE in VarScope? Originally defined at:

我们可以看到编译器报错了,这两个代码说明了variable_scope函数影响了get_variable函数的使用,在创建变量a2的时候由于变量空间one中已经存在一个name属性为a的变量a1了,所以编译器会报错,并且我们看到报错提示了是否在本变量空间设置参数reuse=True。

reuse参数的默认值为False,上面那个代码报错的原因就是variable_scope()函数中的reuse参数的默认值为False,当variable_scope()函数的参数reuse=False时,上下文管理器内的所有get_variable()函数都只执行新建变量的操作而不执行获取变量的操作;当variable_scope()函数的参数reuse=True时,这个上下文管理器内的所有get_variable()函数都只执行获取变量的操作而不执行新建变量的操作。说明代码如下:

import tensorflow as tf
with tf.variable_scope("one"):
    a1=tf.get_variable("a",[1],initializer=tf.constant_initializer(1.0))
    
with tf.variable_scope("one",reuse=True):
    a2=tf.get_variable("a",[1],initializer=tf.constant_initializer(1.0))
    
    print(a1.name,a2.name)
#输出:one/a:0 one/a:0

在某个variable_scope中(不一定是上面所述的one,可以是任意的,例如two等),当variable_scope()函数使用reuse=True参数生成上下文管理器时,若果变量空间中并没有创建过属性为a的变量,使用get_variable()函数时编译器将会报错。说明代码如下:

import tensorflow as tf
with tf.variable_scope("two",reuse=True):
	a1=tf.get_variable("a",initializer=tf.constant_initializer(1.0))
	print(a1.name)
#输出:Variable two/a does not exist, or was not created with tf.get_variable(). Did you mean to set reuse=tf.AUTO_REUSE in VarScope?

此外,若果我们不知道当前变量空间的参数reuse是True还是False时,我们可以print(tf.get_variable_scope().reuse)来确定reuse的值。

with tf.variable_scope("two",reuse=True):
    print(tf.get_variable_scope().reuse)
#输出:True

1.2 variable_scope() 对Variable()的影响

通过上面的说明我们可以知道当variable_scope()函数的参数reuse=False时,上下文管理器内的所有get_variable()函数都只执行新建变量的操作而不执行获取变量的操作;当variable_scope()函数的参数reuse=True时,这个上下文管理器内的所有get_variable()函数都只执行获取变量的操作而不执行新建变量的操作。

而对于Variable()函数来说,因为这个函数的功能只是创建变量,不能像get_variable()函数既可以创建变量,又可以获取变量,所以说variable_scope() 函数中的参数reuse是True还是False对Variable()函数来说没影响,它的功能都只是创建变量。

import tensorflow as tf
with tf.variable_scope("one",reuse=True):
    a3=tf.Variable([1.0],name="a")

print(a3.name)

with tf.variable_scope("one",reuse=False):
    a4=tf.Variable([1.0],name="a")

print(a4.name)
#输出:one/a:0
#     one_1/a:0

2.name_scope()

2.1 name_scope()对get_variable()函数的影响

先看代码

with tf.name_scope("a"):
    a=tf.get_variable("b",[1])
    print(a.name)
#输出:b:0

再来看另个一个代码

with tf.name_scope("b"):
    c=tf.get_variable("b",[1])
    print(c.name)
#输出:Variable b already exists, disallowed. Did you mean to set reuse=True or reuse=tf.AUTO_REUSE in VarScope? Originally defined at:

可以看到,name_scope()没有对 tf.get_variable()创建的变量增加“范围”,如第一个代码所示,输出的变量名称面前没有变量空间名,但是,如果想创建一个属性name也为b的变量c,即使不在同一个name_scope里,编译器仍然会报错,这也恰好说明了name_scope()没有对 tf.get_variable()创建的变量增加“范围”

2.2 name_scope()对variable()函数的影响

看代码

with tf.name_scope("a"):
	a=tf.Variable([1],name='a')
print(a.name)
#输出:a/a:0

再创建一个变量a

with tf.name_scope("a"):
    a=tf.Variable([1],name='a')
print(a.name)
#输出:a_1/a:0

在另一个name_scope()创建变量a

with tf.name_scope("b"):
    a=tf.Variable([1],name='a')
print(a.name)
#输出:b/a:0

可以看到,name_scope()对 tf.Variable()创建的变量增加“范围”,第一个代码块中变量a的name属性为a/a:0,第二个代码块a的name属性为a_1/a:0,第三个代码块中变量a的name属性为b/a:0,说明了在name_scope()中,tf.Variable()可以创建同名字且属性name相同的变量,但每个变量都会被系统创建在不同的变量环境中。

参考书籍:《TensorFlow深度学习算法原理与编程实战》 蒋子阳 著

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值