TensorFlow的variable_scope和name_scope詳細介紹
阿新 • • 發佈:2018-11-09
TensorFlow中有兩個作用域(scope),分別是name_scope和variable_scope。variable_scope主要是給variable_name(變數名)增加字首,還可以給op_name(運算名稱)增加字首,而name_scope是,op_name(運算名稱)增加字首。接下來回詳細介紹兩者的區別和聯絡。
一、variable_scope的使用
tf.get_variable函式通過所給的名稱建立或者獲取一個變數
1、variable_scope的使用
with tf.variable_scope("foo") as scope: v = tf.get_variable("v",[1]) print(v.name) #foo/v:0
tf.variable_scope有一個引數reuse預設None,當reuse為None或False時,表示在該作用域下tf.get_variable函式只能建立變數,如果建立兩個相同名字的變數就會報錯:ValueError: Variable foo/v already exists
with tf.variable_scope("foo") as scope:
v = tf.get_variable("v",[1])
v1 = tf.get_variable("v",[1])
print(v.name)
將reuse引數設定為True時,作用域可以共享變數,兩個變數相等
with tf.variable_scope("foo",reuse=True):
v1 = tf.get_variable("v",[1])
v2 = tf.get_variable("v",[1])
print(v1.name,v2.name,v1 == v2)
#foo/v:0 foo/v:0 True
2、獲取變數的作用域
with tf.variable_scope("foo") as foo_scope: v = tf.get_variable("v",[1]) with tf.variable_scope(foo_scope): w = tf.get_variable("w",[1]) print(v.name,w.name) #foo/v:0 foo/w:0
如果在開啟一個變數的作用域之前預先定義一個作用域,則會跳過當前變數的作用域,使用預先定義的作用域
with tf.variable_scope("bar"):
with tf.variable_scope("baz") as other_scope:
print(other_scope.name)
#bar/baz
#使用預先定義的作用域
with tf.variable_scope(foo_scope) as foo_scope2:
print(foo_scope2.name)
#foo
3、變數作用域的初始化
在定義變數的作用域的時候,可以給該作用域下的變數預設定義一個初始化器,在這個作用域下的子作用域或變數都可以繼承或者重寫父作用域的初始化值。
sess = tf.Session()
#為該作用域下的變數定義一個初始化器,預設變數值為0.4
with tf.variable_scope("foo",initializer=tf.constant_initializer(0.4)):
#使用預設值
v = tf.get_variable("v",[1])
#重寫作用域的初始化值
w = tf.get_variable("w",[1],initializer=tf.constant_initializer(0.5))
#子作用域,預設使用父作用域的初始化器
with tf.variable_scope("bar"):
v1 = tf.get_variable("v1",[1])
#子作用域,重寫父作用域的初始化值
with tf.variable_scope("baz",initializer=tf.constant_initializer(0.6)):
v2 = tf.get_variable("v2",[1])
init = tf.global_variables_initializer()
sess.run(init)
print(sess.run(v),sess.run(w),sess.run(v1),sess.run(v2))
#[0.4] [0.5] [0.4] [0.6]
sess.close()
4、在variable_scope下的op_name
with tf.variable_scope("foo"):
x = 1.0 + tf.get_variable("v",[1])
print(x.op.name)
#foo/add
在variable_scope下也會為op_name增加一個字首
二、name_scope的使用
name_scope下的作用域會影響op_name,但不會影響get_variable建立的變數,會影響通過Variable()建立的變數
with tf.variable_scope("foo"):
with tf.name_scope("bar"):
v = tf.get_variable("v",[1])
w = tf.Variable(tf.zeros([1]),name="w")
z = 1.0 + v
print(v.name,w.name,z.op.name)
#foo/v:0 foo/bar/w:0 foo/bar/add