2015-12-11 14 views
52

Jaka jest różnica między variable_scope i name_scope? variable scope tutorial mówi o variable_scope niejawnie otwierając name_scope. Zauważyłem również, że utworzenie zmiennej w pliku name_scope automatycznie rozszerza jej nazwę także o nazwę zakresu. Jaka jest różnica?Różnica między zmiennym_sklepem a nazwanym_skresem w TensorFlow

+0

FYI [Jaka jest różnica zakresu nazwy i zakresu zmiennego w tensorflow?] (Http://stackoverflow.com/q/35919020/395857) –

+0

Widziałem :-) Dzięki za udostępnienie. Czy powinniśmy oznaczyć to pytanie jako duplikat drugiego pytania? –

+0

Możliwy duplikat [Jaka jest różnica zakresu nazwy i zakresu zmiennego w tensorflow?] (Https://stackoverflow.com/questions/35919020/whats-the-difference-of-name-scope-and-a-variable- scope-in-tensorflow) –

Odpowiedz

34

Po utworzeniu zmiennej z tf.get_variable zamiast tf.Variable, Tensorflow rozpocznie sprawdzanie nazw vars utworzonych tą samą metodą, aby sprawdzić, czy się zderzają. Jeśli tak, zostanie zgłoszony wyjątek. Jeśli utworzono var z tf.get_variable i próbujesz zmienić prefiks nazw zmiennych za pomocą menedżera kontekstów tf.name_scope, nie zapobiegnie to Tensorflow zgłaszania wyjątków. Tylko menedżer kontekstu tf.variable_scope skutecznie zmieni nazwę twojego var w tym przypadku. Lub jeśli chcesz ponownie użyć zmiennej, powinieneś wywołać scope.reuse_variables() przed utworzeniem var po raz drugi.

Podsumowując, tf.name_scope wystarczy dodać prefiks do wszystkich tensora utworzonego w tym zakresie (z wyjątkiem Vars utworzonych z tf.get_variable), a tf.variable_scope dodać przedrostek do zmiennych utworzonych z tf.get_variable.

+4

Czy mógłbyś powiedzieć nieco więcej o tym, dlaczego potrzebne są dwa mechanizmy scopingowe? –

+2

Nie wiem. Może powinieneś utworzyć problem na github z prośbą o lepsze udokumentowanie różnicy między tymi dwoma mechanizmami. – cesarsalgado

+4

Mogę spekulować. Myślę, że powodem istnienia dwóch sposobów na utworzenie zmiennej (tf.Variable i tf.get_variable) jest to, że zwykle nie chcesz udostępniać zmiennej. Jeśli chcesz się tym dzielić, musisz utworzyć plik var z tf.get_variable i użyć tf.variable_scope do zmiany zakresu, aby wyraźnie zaznaczyć, że obsługujesz zmienne vars. Jeśli byłoby możliwe użycie tf.name_scope w tym przypadku, może to zmniejszyłoby czytelność kodu. – cesarsalgado

28

miałem problemy ze zrozumieniem różnicy między variable_scope i name_scope (wyglądały prawie tak samo) przed Starałem się wyobrazić wszystko, tworząc prosty przykład:

import tensorflow as tf 
def scoping(fn, scope1, scope2, vals): 
    with fn(scope1): 
     a = tf.Variable(vals[0], name='a') 
     b = tf.get_variable('b', initializer=vals[1]) 
     c = tf.constant(vals[2], name='c') 
     with fn(scope2): 
      d = tf.add(a * b, c, name='res') 

     print '\n '.join([scope1, a.name, b.name, c.name, d.name]), '\n' 
    return d 

d1 = scoping(tf.variable_scope, 'scope_vars', 'res', [1, 2, 3]) 
d2 = scoping(tf.name_scope,  'scope_name', 'res', [1, 2, 3]) 

with tf.Session() as sess: 
    writer = tf.summary.FileWriter('logs', sess.graph) 
    sess.run(tf.global_variables_initializer()) 
    print sess.run([d1, d2]) 
    writer.close() 

Tutaj utworzyć funkcję, która tworzy kilka zmiennych i stałe i grupuje je w zakresach (w zależności od typu I). W tej funkcji drukuję również nazwy wszystkich zmiennych. Następnie wykonuję wykres, aby uzyskać wartości wynikowych wartości i zapisać pliki zdarzeń, aby zbadać je w tensorboard. Po uruchomieniu tego, otrzymasz następujące:

scope_vars 
    scope_vars/a:0 
    scope_vars/b:0 
    scope_vars/c:0 
    scope_vars/res/res:0 

scope_name 
    scope_name/a:0 
    b:0 
    scope_name/c:0 
    scope_name/res/res:0 

Zobaczysz podobny wzór, jeśli otwarte TB (jak widać b jest poza scope_name prostokątne): enter image description here


To daje odpowiedź:

Teraz widzisz, że tf.variable_scope() dodaje prefiks do nazw wszystkich zmiennych (bez względu na to, jak Ty stwórz je), ops, stałe. Z drugiej strony tf.name_scope() ignoruje zmienne utworzone za pomocą tf.get_variable(), ponieważ zakłada, że ​​wiesz, która zmienna i w jakim zakresie chciałeś użyć.

Dobra dokumentacja Sharing variables mówi, że

tf.variable_scope(): Zarządza nazw nazw przekazywanych tf.get_variable().

Ta sama dokumentacja zawiera więcej informacji o tym, jak działa zakres zmienny i kiedy jest przydatny.

+0

Proponuję uprościć ten bardzo użyteczny przykład, pomijając argument "vals". –

+0

Chciałbym również zasugerować zmianę nazwy "d" z "res". Zakładam, że nie ma to związku z "res", który przekazałeś jako zakres2. –