tensorflow - example - tf get_variable tensor flow
Tensorflow variable alcance: reutilizar si existe variable (4)
Aunque el uso de la cláusula "probar ... excepto ..." funciona, creo que una forma más elegante y mantenible sería separar el proceso de inicialización de variables con el proceso de "reutilización".
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
Como a menudo solo necesitamos inicializar variables, pero reutilizarlo / compartirlo muchas veces, separando los dos procesos hace que el código sea más limpio. También de esta manera, no necesitaremos revisar la cláusula "probar" cada vez que se compruebe si la variable ya se ha creado o no.
Quiero un fragmento de código que crea una variable dentro de un ámbito si no existe, y accedo a la variable si ya existe. Necesito que sea el mismo código ya que se llamará varias veces.
Sin embargo, Tensorflow necesita que yo especifique si quiero crear o reutilizar la variable, como esto:
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])
¿Cómo puedo hacer que decida si crearlo o reutilizarlo automáticamente? Es decir, quiero que los dos bloques de código anteriores sean iguales y ejecuten el programa.
La nueva opción AUTO_REUSE hace el truco.
A partir de los documentos de la API tf.variable_scope : si reuse=tf.AUTO_REUSE
, creamos variables si no existen, y las devolvemos de otro modo.
Ejemplo básico de compartir una 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
Podemos escribir nuestra abstracción sobre tf.varaible_scope
que utiliza reuse=None
en la primera llamada y usa reuse=True
en las llamadas consiguientes:
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()
Uso:
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])
Se ValueError
un ValueError
en get_variable()
cuando se crea una nueva variable y no se declara una forma, o cuando se viola la reutilización durante la creación de la variable. Por lo tanto, puedes probar esto:
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
Tenga en cuenta que lo siguiente también funciona:
v1 = get_scope_variable(''foo'', ''v'', [1])
v2 = get_scope_variable(''foo'', ''v'', [1])
assert v1 == v2
ACTUALIZAR. La nueva API admite la reutilización automática ahora:
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