2016-05-08 15 views
58

O ile mi wiadomo, domyślną operacją do utworzenia zmiennej jest Variable, a get_variable służy głównie do dzielenia ciężaru.Różnica między zmienną a zmienną get w TensorFlow

Z jednej strony niektórzy ludzie sugerują użycie get_variable zamiast pierwotnej operacji Variable, kiedy tylko potrzebujesz zmiennej. Z drugiej strony, widzę jedynie użycie get_variable w oficjalnych dokumentach i demach TensorFlow.

Tak więc chcę poznać kilka zasad kciuków, jak prawidłowo korzystać z tych dwóch mechanizmów. Czy istnieją jakieś "standardowe" zasady?

+4

get_variable jest nowy sposób, zmienna jest stary sposób (który może być obsługiwany na zawsze), jak mówi Łukasz (PS : napisał dużo zmiennej o nazwie scoping w TF) –

Odpowiedz

56

Zalecam, aby zawsze używać tf.get_variable(...) - dzięki temu łatwiej będzie poprawić kod, jeśli w dowolnym momencie chcesz udostępnić zmienne, np. w ustawieniu multi-gpu (patrz przykład CIFAR multi-gpu). Nie ma w tym nic złego.

Czysty tf.Variable jest niższy poziom; w pewnym momencie nie istnieje tf.get_variable(), więc niektóre kody nadal używają niskiego poziomu.

+3

Dziękuję bardzo za odpowiedź. Ale wciąż mam jedno pytanie o to, jak zastąpić 'tf.Variable' z' tf.get_variable' wszędzie. To jest, gdy chcę zainicjować zmienną z tablicą numpy, nie mogę znaleźć czystej i efektywnej metody robienia tego tak jak w przypadku 'tf.Variable'. Jak go rozwiązać? Dzięki. –

38

tf.Variable jest klasą i istnieje kilka sposobów na utworzenie tf.Variable including tf.Variable .__ init__ i tf.get_variable.

tf.Zmienna .__ init__: Tworzy nową zmienną z wartość_w początkowej.

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

tf.get_variable: Pobiera istniejącą zmienną o tych parametrach lub tworzy nową. Możesz także użyć inicjalizatora.

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

Jest to bardzo przydatne w użyciu inicjatorów takich jak xavier_initializer:

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

Więcej informacji na https://www.tensorflow.org/versions/r0.8/api_docs/python/state_ops.html#Variable.

+0

Tak, przez 'Variable' faktycznie mam na myśli używanie jego' __init__'. Ponieważ 'get_variable' jest tak wygodne, zastanawiam się, dlaczego większość kodu TensorFlow, który widziałem, używa' Variable' zamiast 'get_variable'. Czy przy wyborze między nimi istnieją jakieś konwencje lub czynniki, które należy wziąć pod uwagę. Dziękuję Ci! –

+0

Jeśli chcesz mieć określoną wartość, użycie opcji Variable jest proste: x = tf.Variable (3). –

+0

@SungKim normalnie, gdy używamy 'tf.Variable()' możemy zainicjować go jako wartość losową z obciętej dystrybucji normalnej. Oto mój przykład 'w1 = tf.Variable (tf.truncated_normal ([5, 50], stddev = 0.01), name = 'w1')'. Jaki byłby odpowiednik tego? jak mam powiedzieć, że chcę ucięty normalny? Czy powinienem po prostu zrobić 'w1 = tf.get_variable (name = 'w1', shape = [5,50], initializer = tf.truncated_normal, constantizer = tf.nn.l2_loss)? –

18

znajdę dwie główne różnice między jednym a drugim:

  1. pierwsze, tf.Variable zawsze utworzyć nową zmienną, czy tf.get_variable dostaje z wykresu istniejącą zmienną z tych parametrów, a jeśli nie istnieje, tworzy nowy.

  2. tf.Variable wymaga podania wartości początkowej.

Ważne jest, aby wyjaśnić, że funkcja tf.get_variable prefiksy nazwie pod bieżącym zakresie zmiennej o przeprowadzenie kontroli wykorzystania. Na przykład:

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 

Ostatni błąd asercji jest interesujący: dwie zmienne o tej samej nazwie w tym samym zakresie mają być tą samą zmienną.Ale jeśli przetestować nazwy zmiennych d i e zdasz sobie sprawę, że Tensorflow zmienił nazwę zmiennej e:

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

Świetny przykład! Odnośnie 'd.name' i' e.name', właśnie natknąłem się na [ten dokument TensorFlow dotyczący operacji na tensorowym nazewnictwie wykresów] (https://www.tensorflow.org/programmers_guide/graphs#naming_operations), który wyjaśnia to : 'Jeśli domyślny wykres zawierał już operację o nazwie" odpowiedź ", to TensorFlow dołączałby" _1 "," _2 "itd. Do nazwy, aby było to unikalne." – Atlas7

Powiązane problemy