2016-05-08 41 views
58

據我所知,Variable是製作變量的默認操作,而get_variable主要用於權重共享。TensorFlow中變量和get_variable之間的區別

一方面,有人建議在需要變量時使用get_variable而不是原始的Variable操作。另一方面,我在TensorFlow的官方文檔和演示中只看到get_variable的任何使用。

因此,我想知道一些關於如何正確使用這兩種機制的規則。有沒有「標準」原則?

+4

get_variable是新的方式,變老的方式(這可能永遠支持)爲盧卡斯說(PS :他在TF中寫了大量的變量名稱範圍) –

回答

56

我建議始終使用tf.get_variable(...) - 如果您需要在任何時間共享變量,它將使重構代碼變得更容易。在多GPU設置中(請參閱多GPU CIFAR示例)。它沒有缺點。

tf.Variable是較低級的;在某個點tf.get_variable()不存在,所以一些代碼仍然使用低級方式。

+3

非常感謝您的回答。但是我仍然有一個關於如何用'tf.get_variable'替換'tf.Variable'的問題。那就是當我想用一個numpy數組初始化一個變量時,我無法找到一個乾淨而有效的方式來處理它,就像我使用'tf.Variable'一樣。你如何解決它?謝謝。 –

38

tf.Variable是一個類,有幾種創建tf.Variable的方法,包括tf.Variable .__ init__和tf.get_variable。

tf.Variable .__ init__:用初始值創建一個新變量。

W = tf.Variable(<initial-value>, name=<optional-name>) 

tf.get_variable:獲取具有這些參數的現有變量或創建一個新變量。你也可以使用初始化器。

W = tf.get_variable(name, shape=None, dtype=tf.float32, initializer=None, 
     regularizer=None, trainable=True, collections=None) 

這是非常有用的使用初始化如xavier_initializer:在https://www.tensorflow.org/versions/r0.8/api_docs/python/state_ops.html#Variable

W = tf.get_variable("W", shape=[784, 256], 
     initializer=tf.contrib.layers.xavier_initializer()) 

更多信息。

+0

是的,通過'Variable'實際上我的意思是使用它的'__init__'。由於'get_variable'非常方便,我想知道爲什麼我看到的大多數TensorFlow代碼都使用'Variable'而不是'get_variable'。在它們之間進行選擇時是否有任何約定或因素要考慮。謝謝! –

+0

如果你想有一個特定的值,使用變量很簡單:x = tf.Variable(3)。 –

+0

@SungKim通常當我們使用'tf.Variable()'時,我們可以將它初始化爲一個截斷正態分佈的隨機值。這裏是我的例子'w1 = tf.Variable(tf.truncated_normal([5,50],stddev = 0.01),name ='w1')'。這相當於什麼?我如何告訴它我想要一個截斷的正常?我應該做'w1 = tf.get_variable(name ='w1',shape = [5,50],initializer = tf.truncated_normal,regularizer = tf.nn.l2_loss)'? –

18

我能找到一個和另一個之間的兩個主要區別:

  1. 首先是tf.Variable將始終創建一個新的變量,是否tf.get_variable從圖中得到這些參數的存在的變量,如果它不存在,它創建一個新的。

  2. tf.Variable要求指定初始值。

它澄清,功能tf.get_variable前綴的名稱與當前變量範圍進行復用的檢查是很重要的。例如:

with tf.variable_scope("one"): 
    a = tf.get_variable("v", [1]) #a.name == "one/v:0" 
with tf.variable_scope("one"): 
    b = tf.get_variable("v", [1]) #ValueError: Variable one/v already exists 
with tf.variable_scope("one", reuse = True): 
    c = tf.get_variable("v", [1]) #c.name == "one/v:0" 

with tf.variable_scope("two"): 
    d = tf.get_variable("v", [1]) #d.name == "two/v:0" 
    e = tf.Variable(1, name = "v", expected_shape = [1]) #e.name == "two/v_1:0" 

assert(a is c) #Assertion is true, they refer to the same object. 
assert(a is d) #AssertionError: they are different objects 
assert(d is e) #AssertionError: they are different objects 

最後一個斷言錯誤很有趣:在同一個作用域下的兩個同名變量應該是同一個變量。但是,如果你測試的變量d名稱和e你會發現,Tensorflow改變變量e的名字:

d.name #d.name == "two/v:0" 
e.name #e.name == "two/v_1:0" 
+0

很好的例子!關於'd.name'和'e.name',我剛剛遇到了一個關於張量圖命名操作的[TensorFlow doc](https://www.tensorflow.org/programmers_guide/graphs#naming_operations),它解釋了它:'如果默認圖形已經包含名爲「answer」的操作,則TensorFlow會將「_1」,「_2」等添加到名稱中,以使其唯一。 – Atlas7

相關問題