tensorflow提供了通过变量名称来创建或者获取一个变量的机制。通过这个机制,在不同的函数中可以直接通过变量的名字来使用变量,而不需要将变量通过参数的形式到处传递。
这种机制即通过tf.variable_scope 及 tf.get_variable实现。
import tensorflow as tf
with tf.variable_scope("my_scope_name", reuse=None):
v = tf.get_variable("varibale_name", shape, initializer)
在此上下文管理器中定义的变量,其属性name:
v.name == "my_scope_name/varibale_name"
(1)reuse参数默认为None,此时get_variable()会创建一个新变量;
(2)reuse参数设置为True时,get_variable()会获取一个已经定义的变量。获取方式即:设置get_variable的第一个参数为目标变量的name属性,同时也要注意获取时,get_variable所在的my_scope_name。
举例说明:
例(1)
with tf.variable_scope("layer1"):
w1 = tf.get_variable("weigth1", [3, 3], initializer=tf.constant_initializer(0))
print(w1.name) #输出:layer1/weigth1:0
with tf.variable_scope("layer1", reuse=True):
w2 = tf.get_variable("weigth1")
print(w2.name) #输出:layer1/weigth1:0
对于下面的w2,是获取变量,所以w2.name还是w1的name。注意,下面的with中,设置的scope_name 是 “layer1”,所以获取w1时,不用输入w1.name的全部路径。
例(2):
with tf.variable_scope("layer1"):
w1 = tf.get_variable("weigth1", [3, 3], initializer=tf.constant_initializer(0))
print(w1.name)
with tf.variable_scope("", reuse=True):
w2 = tf.get_variable("layer1/weigth1")
print(w2.name)
如果将下面with的scope_name改为空,则获取w1变量时,要写出w1.name的全部路径。总之,with中的路径,都会加上其scope_name前缀。
例(3):
所以,下面这种情况会报错:
with tf.variable_scope("layer1"):
w1 = tf.get_variable("weigth1", [3, 3], initializer=tf.constant_initializer(0))
print(w1.name)
with tf.variable_scope("layer2", reuse=True):
w2 = tf.get_variable("layer1/weigth1")
print(w2.name)
ValueError: Variable layer2/layer1/weigth1 does not exist
可以看到,你在试图获取变量layer2/layer1/weigth1,获取路径添加了layer2前缀。
例(4)
最后一种情况:在不同的scope_name下定义的变量,其name属性不同;但是我们都用同一个python变量名做其引用(python新建变量的时类似于新建了一个指向某块内存的引用)。
with tf.variable_scope("layer1"):
w = tf.get_variable("weigth", [3, 3], initializer=tf.constant_initializer(0))
print(w.name)
with tf.variable_scope("layer2"):
w = tf.get_variable("weigth", [1])
print(w.name)
print(w.name)
输出:
layer1/weigth:0
layer2/weigth:0
layer2/weigth:0
可见,在layer2里创建的w变量,覆盖了原来的w。所以退出with环境后,w.name变成了覆盖后的结果。
本文介绍了TensorFlow中利用tf.variable_scope和tf.get_variable进行变量管理的方法。通过变量名称创建和获取变量,可以避免在不同函数间传递变量。当reuse参数为None时,会创建新变量;为True时,会获取已定义的变量。变量的name属性受到当前scope_name的影响,错误的路径会导致获取失败。示例展示了不同scope下变量的创建和覆盖行为,强调了正确使用scope_name的重要性。

5万+

被折叠的 条评论
为什么被折叠?



