【tensorflow 學習】 name_scope和variable_scope的區別
阿新 • • 發佈:2019-01-12
在tensorflow中,有兩個scope, 一個是name_scope一個是variable_scope,這兩個scope到底有什麼區別呢?
三個例子
先看第一個程式:
with tf.name_scope("hello") as name_scope: arr1 = tf.get_variable("arr1", shape=[2,10],dtype=tf.float32) arr2 = tf.Variable(1, name="arr2", dtype=tf.float32) print(name_scope) #hello/ print(arr1.name) #arr1:0 print(arr2.name) #hello/arr2:0 print("scope_name:%s " % tf.get_variable_scope().original_name_scope) #空 #輸出 hello/ arr1:0 hello/arr2:0 scope_name:
可以看出:
- tf.name_scope() 返回的是 一個string,”hello/”
- 在name_scope使用
get_variable()
中定義的 variable 的 name 並沒有字首 - 在name_scope使用
variable()
定義的variable的名字是有 “hello/”字首的 - tf.get_variable_scope().original_name_scope 是空
第二個程式:
import tensorflow as tf with tf.variable_scope("hello") as variable_scope: arr1 = tf.get_variable("arr1", shape=[2, 10], dtype=tf.float32) arr2 = tf.Variable(1, name="arr2", dtype=tf.float32) print(variable_scope)#<tensorflow.python.ops.variable_scope.VariableScope object at 0x7fbc09959210> print(variable_scope.name) #打印出變數空間名字 #hello print(arr1.name) #hello/arr1:0 print(arr2.name) #hello/arr2:0 print(tf.get_variable_scope().original_name_scope) #hello/ #tf.get_variable_scope() 獲取的就是variable_scope with tf.variable_scope("xixi") as v_scope2: print(tf.get_variable_scope().original_name_scope) #hello/xixi/ #輸出 <tensorflow.python.ops.variable_scope.VariableScope object at 0x0000020B2AAF9390> hello hello/arr1:0 hello/arr2:0 hello/ hello/xixi/
可以看出:
- tf.variable_scope() 返回的是一個
VariableScope
物件 - variable_scope使用
get_variable
定義的variable 的name加上了”hello/”字首 - tf.get_variable_scope().original_name_scope 是 巢狀後的scope name
第三個程式:
with tf.name_scope("name1"): with tf.variable_scope("var1"): w = tf.get_variable("w",shape=[2]) res = tf.add(w,[3]) print(w.name) print(res.name) # 輸出 var1/w:0 name1/var1/Add:0
可以看出:
variable_scope
和name_scope
都會給op
的name
加上字首- 這實際上是因為建立
variable_scope
時內部會建立一個同名的name_scope
對比三個個程式可以看出:
name_scope
返回的是 string, 而variable_scope
返回的是物件. 這也可以感覺到,variable_scope
能幹的事情比name_scope
要多.- name_scope對 get_variable()建立的變數 的名字不會有任何影響,而建立的
op
會被加上字首. - tf.get_variable_scope() 返回的只是 variable_scope,不管 name_scope. 所以以後我們在使用tf.get_variable_scope().reuse_variables() 時可以無視name_scope
其他:
with tf.name_scope("scope1") as scope1:
with tf.name_scope("scope2") as scope2:
print(scope2)
#輸出:
scope1/scope2/ 最後有斜槓
with tf.variable_scope("scope1") as scope1:
with tf.variable_scope("scope2") as scope2:
print(scope2)
print(scope2.name)
#輸出:
<tensorflow.python.ops.variable_scope.VariableScope object at 0x00000194F95C81D0>
scope1/scope2
tf.name_scope()可以用來幹什麼
對
tf.get_variable
不起作用,只對tf.Variable
起作用
典型的 TensorFlow 可以有數以千計的節點,如此多而難以一下全部看到,甚至無法使用標準圖表工具來展示。為簡單起見,我們為op/tensor
名劃定範圍,並且視覺化把該資訊用於在圖表中的節點上定義一個層級。預設情況下, 只有頂層節點會顯示。下面這個例子使用tf.name_scope在hidden命名域下定義了三個操作:
import tensorflow as tf
with tf.name_scope('hidden') as scope:
a = tf.constant(5, name='alpha')
W = tf.Variable(tf.random_uniform([1, 2], -1.0, 1.0), name='weights')
b = tf.Variable(tf.zeros([1]), name='biases')
print(a.name) #hidden/alpha
print(W.name) #hidden/weights
print(b.name) #hidden/biases
#輸出
hidden/alpha
hidden/weights
hidden/biases
name_scope 是給op_name加字首, variable_scope是給get_variable()建立的變數的名字加字首。
tf.variable_scope有時也會處理命名衝突
import tensorflow as tf
def test(name=None):
with tf.variable_scope(name, default_name="scope") as scope:
w = tf.get_variable("w", shape=[2, 10])
test()
test()
ws = tf.trainable_variables()
for w in ws:
print(w.name)
#scope/w:0
#scope_1/w:0
#可以看出,如果只是使用default_name這個屬性來建立variable_scope的時候,會處理命名衝突
其它
- tf.name_scope(None) 有清除name scope的作用
import tensorflow as tf
with tf.name_scope("hehe"):
w1 = tf.Variable(1.0)
with tf.name_scope(None):
w2 = tf.Variable(2.0)
print(w1.name)
print(w2.name)
#hehe/Variable:0
#Variable:0
tf.variable_scope()可以用來幹什麼
對
tf.get_variable
和tf.Variable
都起作用
variable_scope 用來管理 variable 詳見variable_scope
with tf.variable_scope("my_scope"):
v1 = tf.get_variable("var1", [1], dtype=tf.float32)
v2 = tf.Variable(1, name="var2", dtype=tf.float32)
a = tf.add(v1, v2)
print(v1.name) # my_scope/var1:0
print(v2.name) # my_scope/var2:0
print(a.name) # my_scope/Add:0
這種機制允許在不用的name_scope中使用tf.get_variable
來share變數,但是需要注意的是,一定要宣告reuse:
with tf.name_scope("foo"):
with tf.variable_scope("var_scope"):
v = tf.get_variable("var", [1])
with tf.name_scope("bar"):
with tf.variable_scope("var_scope", reuse=True):
v1 = tf.get_variable("var", [1])
assert v1 == v
print(v.name) # var_scope/var:0
print(v1.name) # var_scope/var:0
輸出:
var_scope/var:0
var_scope/var:0
總結
簡單來看
1. 使用tf.Variable()
的時候,tf.name_scope()
和tf.variable_scope()
都會給 Variable
和 op
的 name
屬性加上字首。
2. 使用tf.get_variable()
的時候,tf.name_scope()
就不會給 tf.get_variable()
創建出來的Variable
加字首。但是 tf.Variable()
創建出來的就會受到 name_scope
的影響.