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?
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)):
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é.
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
.
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
.