TensorFlow variable champ d'application: réutiliser si variable existe

je veux un morceau de code qui crée une variable dans un scope si elle n'existe pas, et accéder à la variable si elle existe déjà. J'ai besoin d'elle pour être le code puisqu'il sera appelé plusieurs fois.

Toutefois, Tensorflow besoin de moi pour spécifier si je veux créer ou de réutiliser la variable, comme ceci:

with tf.variable_scope("foo"): #create the first time
    v = tf.get_variable("v", [1])

with tf.variable_scope("foo", reuse=True): #reuse the second time
    v = tf.get_variable("v", [1])

Comment puis-je l'amener à comprendre s'il faut le créer ou le réutiliser automatiquement? I. e., Je veux les deux blocs de code à l' et avoir le programme exécuté.

25
demandé sur holdenlee 2016-07-23 21:52:32

4 réponses

ValueError est soulevée dans le get_variable() lors de la création d'une nouvelle variable et la forme n'est pas déclarée, ou lors de la violation de la réutilisation lors de la création de la variable. Par conséquent, vous pouvez essayer ceci:

def get_scope_variable(scope_name, var, shape=None):
    with tf.variable_scope(scope_name) as scope:
        try:
            v = tf.get_variable(var, shape)
        except ValueError:
            scope.reuse_variables()
            v = tf.get_variable(var)
    return v

v1 = get_scope_variable('foo', 'v', [1])
v2 = get_scope_variable('foo', 'v')
assert v1 == v2

notez que ce qui suit fonctionne aussi:

v1 = get_scope_variable('foo', 'v', [1])
v2 = get_scope_variable('foo', 'v', [1])
assert v1 == v2

mise à jour. la nouvelle API supporte la réutilisation automatique maintenant:

def get_scope_variable(scope, var, shape=None):
    with tf.variable_scope(scope, reuse=tf.AUTO_REUSE):
        v = tf.get_variable(var, shape)
    return v
24
répondu rvinas 2018-03-11 23:19:17

bien que utilisant " essayer...sauf..."clause fonctionne, je pense qu'une façon plus élégante et maintenable serait de séparer le processus d'initialisation variable avec le processus de "réutilisation".

def initialize_variable(scope_name, var_name, shape):
    with tf.variable_scope(scope_name) as scope:
        v = tf.get_variable(var_name, shape)
        scope.reuse_variable()

def get_scope_variable(scope_name, var_name):
    with tf.variable_scope(scope_name, reuse=True):
        v = tf.get_variable(var_name)
    return v

puisque souvent nous n'avons besoin d'initialiser que les variables, mais de les réutiliser/les partager plusieurs fois, la séparation des deux processus rend le code plus propre. De même, nous n'aurons pas besoin de passer par la clause "essayer" à chaque fois pour vérifier si la variable a déjà été créée ou non.

12
répondu Zhongyu Kuang 2016-10-17 18:45:21

nouvelle option AUTO_REUSE fait l'affaire.

tf.variable_scope API docs: si reuse=tf.AUTO_REUSE, nous créons des variables si elles n'existent pas, et les retournons autrement.

exemple de base de partage D'une variable AUTO_REUSE:

def foo():
  with tf.variable_scope("foo", reuse=tf.AUTO_REUSE):
    v = tf.get_variable("v", [1])
  return v

v1 = foo()  # Creates v.
v2 = foo()  # Gets the same, existing v.
assert v1 == v2
6
répondu Mikhail Mishin 2017-12-04 21:08:18

nous pouvons écrire notre abstraction sur tf.varaible_scopereuse=None sur le premier appel et utilise reuse=True sur le conséquente des appels:

def variable_scope(name_or_scope, *args, **kwargs):
  if isinstance(name_or_scope, str):
    scope_name = tf.get_variable_scope().name + '/' + name_or_scope
  elif isinstance(name_or_scope, tf.Variable):
    scope_name = name_or_scope.name

  if scope_name in variable_scope.scopes:
    kwargs['reuse'] = True
  else:
    variable_scope.scopes.add(scope_name)

  return tf.variable_scope(name_or_scope, *args, **kwargs)
variable_scope.scopes = set()

Utilisation:

with variable_scope("foo"): #create the first time
    v = tf.get_variable("v", [1])

with variable_scope("foo"): #reuse the second time
    v = tf.get_variable("v", [1])
1
répondu AlexP 2017-06-28 13:51:44