web-dev-qa-db-fra.com

Quelle est la différence entre variable_scope et name_scope?

Quelle est la différence entre variable_scope et name_scope? Le tutoriel à portée variable parle de variable_scope ouvrant implicitement name_scope. J'ai aussi remarqué que créer une variable dans un name_scope étend automatiquement son nom avec le nom de la portée. Alors, quelle est la difference?

71
Andrzej Pronobis

J'ai eu du mal à comprendre la différence entre variable_scope et name_scope (ils avaient presque la même apparence) avant d'essayer de tout visualiser en créant un exemple simple:

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()

Ici, je crée une fonction qui crée des variables et des constantes et les groupe en étendues (en fonction du type que j'ai fourni). Dans cette fonction, j'imprime également les noms de toutes les variables. Après cela, j'exécute le graphique pour obtenir les valeurs des valeurs résultantes et enregistre les fichiers d'événements pour les étudier dans tensorboard. Si vous exécutez ceci, vous obtiendrez ce qui suit:

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 

Vous voyez le même schéma si vous ouvrez TB (comme vous voyez b est en dehors de scope_name Rectangulaire)): enter image description here


Ceci vous donne la réponse :

Maintenant, vous voyez que tf.variable_scope() ajoute un préfixe aux noms de toutes les variables (peu importe la façon dont vous les créez), ops, constantes. Par contre, tf.name_scope() ignore les variables créées avec tf.get_variable(), car il suppose que vous sachiez quelle variable et dans quelle étendue vous souhaitez utiliser.

Une bonne documentation sur variables de partage vous dit que

tf.variable_scope(): gère les espaces de noms des noms transmis à tf.get_variable().

La même documentation fournit plus de détails sur le fonctionnement de Variable Scope et sur son utilité.

48
Salvador Dali

Lorsque vous créez une variable avec tf.get_variable Au lieu de tf.Variable, Tensorflow commence à vérifier les noms des vars créés avec la même méthode pour voir s'ils se rencontrent. S'ils le font, une exception sera levée. Si vous avez créé une variable avec tf.get_variable Et tentez de modifier le préfixe de vos noms de variables à l'aide du gestionnaire de contexte tf.name_scope, Cela n'empêchera pas le flux de tenseurs de générer une exception. Seul le gestionnaire de contexte tf.variable_scope Modifiera effectivement le nom de votre var dans ce cas. Ou, si vous souhaitez réutiliser la variable, appelez scope.reuse_variables () avant de créer la var une deuxième fois.

En résumé, tf.name_scope Ajoute simplement un préfixe à tous les tenseurs créés dans cette étendue (à l'exception des vars créés avec tf.get_variable), Et tf.variable_scope Ajoute un préfixe aux variables créées avec tf.get_variable.

39
cesarsalgado

tf.variable_scope Est une évolution de tf.name_scope À gérer Variable réutilisation. Comme vous l'avez remarqué, il fait plus que tf.name_scope, Il n'y a donc aucune raison d'utiliser tf.name_scope: Ce n'est pas surprenant, n développeur de TF conseille d'utiliser simplement tf.variable_scope .

Si j'ai bien compris que tf.name_scope Traînait encore, il existait de subtiles incompatibilités dans le comportement de ces deux-là, ce qui invalide tf.variable_scope En remplacement immédiat de tf.name_scope.

2
P-Gn