天天看點

TensorFlow筆記:tf.get_variable,tf.Variable(),tf.variable_scope,tf.name_scopetf.get_variable,tf.Variable()tf.variable_scope,tf.name_scope總結:

tf.get_variable,tf.Variable()

tf.get_variable(“vname”)

在建立變量時,如果這個變量vname已經存在,直接使用這個變量,如果不存在,則重新建立;

tf.Variable()

在建立變量時,一律建立新的變量,如果這個變量已存在,則字尾會增加0、1、2等數字編号予以差別。

import tensorflow as tf

with tf.name_scope("a_name_scope"):
initializer = tf.constant_initializer(value=1)
var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32, initializer=initializer)
var2 = tf.Variable(name='var2', initial_value=[2], dtype=tf.float32)
var21 = tf.Variable(name='var2', initial_value=[2.1], dtype=tf.float32)
var22 = tf.Variable(name='var2', initial_value=[2.2], dtype=tf.float32)

with tf.Session() as sess:
sess.run(tf.initialize_all_variables())
print(var1.name) # var1:0
print(sess.run(var1)) # [ 1.]
print(var2.name) # a_name_scope/var2:0
print(sess.run(var2)) # [ 2.]
print(var21.name) # a_name_scope/var2_1:0
print(sess.run(var21)) # [ 2.0999999]
print(var22.name) # a_name_scope/var2_2:0
print(sess.run(var22)) # [ 2.20000005]
           

可以看出使用 tf.Variable() 定義變量的時候, 雖然var2, var21, var22的 name 一樣, 但是為了不重複變量名, Tensorflow 為它們做了附加的區分,因為輸出的變量名是不一樣的. 是以, 本質上tensorflow令 var2, var21, var22 成為不一樣的變量.

tf.variable_scope,tf.name_scope

tf.name_scope()、tf.variable_scope()

是兩個作用域函數,一般與兩個建立/調用變量的函數tf.variable() 和tf.get_variable()搭配使用。常用于:

1)變量共享;2)tensorboard畫流程圖進行可視化封裝變量。

通俗了解就是:tf.name_scope()、tf.variable_scope()會在模型中開辟各自的空間,而其中的變量均在這個空間内進行管理,但是之是以有兩個,主要還是有着各自的差別。

變量共享

name_scope 和 variable_scope主要用于變量共享。其中,變量共享主要涉及兩個函數:tf.variable() 和tf.get_variable();即就是必須要在tf.variable_scope的作用域下使用tf.get_variable()函數。這裡用tf.get_variable( ) 而不用tf.Variable( ),是因為前者擁有一個變量檢查機制,會檢測已經存在的變量是否設定為共享變量,如果已經存在的變量沒有設定為共享變量,TensorFlow 運作到第二個擁有相同名字的變量的時候,就會報錯。

注意,tf.variable() 和tf.get_variable()有不同的建立變量的方式:tf.Variable() 每次都會建立變量。如果希望重用(共享)一些變量,就需要用到了get_variable(),它會去搜尋變量名,有就直接用,沒有再建立。此外,為了對不同位置或者範圍的共享進行區分,就引入名字域。既然用到變量名了,就涉及到了名字域的概念。這就是為什麼會有scope 的概念。name_scope 作用域操作,variable_scope 可以通過設定reuse 标志以及初始化方式來影響域下的變量,因為想要達到變量共享的效果, 就要在 tf.variable_scope()的作用域下使用 tf.get_variable() 這種方式産生和提取變量. 不像 tf.Variable() 每次都會産生新的變量, tf.get_variable() 如果遇到了已經存在名字的變量時, 它會單純的提取這個同樣名字的變量,如果不存在名字的變量再建立.

name scope和variable scope差別

TF中有兩種作用域類型:

命名域 (name scope)

,通過tf.name_scope 或 tf.op_scope建立;

變量域 (variable scope),

通過tf.variable_scope 或 tf.variable_op_scope建立;

這兩種作用域,對于使用tf.Variable()方式建立的變量,具有相同的效果,都會在變量名稱前面加上域名稱。

with tf.name_scope("my_name_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) # var1:0
print(v2.name) # my_name_scope/var2:0
print(a.name) # my_name_scope/Add:0
           

小結:name_scope不會作為tf.get_variable變量的字首,但是會作為tf.Variable的字首。

with tf.variable_scope("my_variable_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_variable_scope/var1:0
print(v2.name) # my_variable_scope/var2:0
print(a.name) # my_variable_scope/Add:0

           

小結:在variable_scope的作用域下,tf.get_variable()和tf.Variable()都加了scope_name字首。是以,在tf.variable_scope的作用域下,通過get_variable()可以使用已經建立的變量,實作了變量的共享。

總結:

1、name_scope不會作為tf.get_variable變量的字首,但是會作為tf.Variable的字首。

2、在variable_scope的作用域下,tf.get_variable()和tf.Variable()都加了scope_name字首。是以,在tf.variable_scope的作用域下,通過get_variable()可以使用已經建立的變量,實作了變量的共享,即可以通過get_variable()在tf.variable_scope設定的作用域範圍内進行變量共享。

3、在重複使用的時候, 一定要在代碼中強調 scope.reuse_variables()過tf.get_variable()方式建立的變量,隻有variable scope名稱會加到變量名稱前面,而name scope不會作為字首。

繼續閱讀