1. 程式人生 > >tf.Variable、tf.get_variable、tf.variable_scope以及tf.name_scope之間的關系

tf.Variable、tf.get_variable、tf.variable_scope以及tf.name_scope之間的關系

第二部分 向量 tps 選項 關系 修改 variables 通過 參考

tensorflow提供通過變量名稱來創建或者獲取一個變量的機制。通過這個機制,在不同的函數中可以直接通過變量的名字來使用變量,而不需要將變量通過參數的形式到處傳遞。

1. tf.Variable與tf.get_variable

tensorflow中通過變量名獲取變量的機制主要通過tf.get_variable和tf.variable_scope實現。當然,變量也可以通過tf.variable來創建。

當tf.get_variable用於變量創建時,和tf.variable的功能基本等價。

#以下兩個定義是等價的
v = tf.get_variable(v, shape=[1], initializer=tf.constant_initializer(1.0))
v 
= tf.Variable(tf.constant(1.0, shape=[1], name=v)

tf.get_variable和tf.variable的最大區別在於:

tf.variable的變量名是一個可選項,通過name=‘v‘的形式給出。但tf.get_variable必須指定變量名。

2. tf.get_variable與tf.variable_scope

先來解釋一下reuse問題:

當reuse為false或none時,同一個tf.variable_scope下面的變量名不能相同;

當reuse為true時,tf.variable_scope只能獲取已經創建過的向量。

例如:

#reuse=False時會報錯的情況:
with tf.variable_scope(foo):
    v = tf.get_variable(v,[1],initializer=tf.constant_initializer(1.0))
with tf.variable_scope(foo):
    v1 = tf.get_variable(v,[1])

在這種情況下會報錯:Variable foo/v already exists, disallowed.Did you mean to set reuse=True in Varscope?

其原因就是在命名空間foo中創建了相同的變量。如果要在foo下創建一個變量v1,其name=‘v’,只需要將reuse設置為Ture就ok了。

將上面第二部分代碼修改為:

with tf.variable_scope(foo, reuse=True):
    v1 = tf.get_variable(v,[1])
    print(v1.name)      #結果為foo/v

當reuse已經設置為True時,tf.variable_scope只能獲取已經創建過的變量。

這個時候,在命名空間bar中創建name=‘v’的變量v3,將會報錯:Variable bar/v dose not exists, diallowed. Did you mean to set reuse=None in VarScope?

with tf.variable_scope(bar, reuse=True):
    v3 = tf.get_variable(v,[1])

簡而言之,reuse=False時,tf.variable_scope創建變量;reuse=True時,tf.variable_scope獲取變量

3. tf.variable_scope與tf.name_scope

tf.name_scope函數也提供了命名空間管理的功能。這兩個函數在大部分情況下是等價的,唯一的區別是在使用tf.get_variable函數時。

tf.get_variable函數不受tf.name_scope的影響
我們從代碼看下這句話的具體意思。
首先是tf.variable_scope:

with tf.variable_scope(foo):
    a = tf.get_variable(bar,[1])
    print(a.name)#結果為foo/bar:0

再看tf.name_scope:

with tf.name_scope(a):
    a=tf.Variable([1])
    print(a.name)#結果為a/Variable:0

    b=tf.get_variable(b,[1])
    print(b.name)#結果為b:0

從這個結果中,我們能很清晰地看到,tf.get_variable創建的變量並不是a/b:0,而是b:0。這就表示了在tf.name_scope函數下,tf.get_variable不受其約束

(參考自https://blog.csdn.net/qq_22522663/article/details/78729029)

tf.Variable、tf.get_variable、tf.variable_scope以及tf.name_scope之間的關系