¿Cuál es la diferencia entre el alcance del nombre y el alcance variable en tensorflow?

Resuelto Xiuyi Yang asked hace 8 años • 8 respuestas

¿Cuáles son las diferencias entre estas funciones?

tf.variable_op_scope(values, name, default_name, initializer=None)

Devuelve un administrador de contexto para definir una operación que crea variables. Este administrador de contexto valida que los valores dados provienen del mismo gráfico, garantiza que ese gráfico sea el predeterminado y envía un alcance de nombre y un alcance de variable.


tf.op_scope(values, name, default_name=None)

Devuelve un administrador de contexto para usar al definir una operación de Python. Este administrador de contexto valida que los valores dados provienen del mismo gráfico, garantiza que ese gráfico sea el predeterminado y envía un alcance de nombre.


tf.name_scope(name)

Envoltorio para Graph.name_scope()usar el gráfico predeterminado. Ver Graph.name_scope()para más detalles.


tf.variable_scope(name_or_scope, reuse=None, initializer=None)

Devuelve un contexto para el alcance de la variable. El alcance de la variable permite crear nuevas variables y compartir las ya creadas, al tiempo que proporciona controles para no crear ni compartir por accidente. Para obtener más información, consulte el artículo sobre alcance variable. Aquí presentamos solo algunos ejemplos básicos.

Xiuyi Yang avatar Mar 10 '16 21:03 Xiuyi Yang
Aceptado

Comencemos con una breve introducción al uso compartido de variables. Es un mecanismo TensorFlowque permite compartir variables a las que se accede en diferentes partes del código sin pasar referencias a la variable.

El método tf.get_variablese puede utilizar con el nombre de la variable como argumento para crear una nueva variable con dicho nombre o recuperar la que se creó antes. Esto es diferente de usar el tf.Variableconstructor que creará una nueva variable cada vez que se llame (y potencialmente agregará un sufijo al nombre de la variable si ya existe una variable con ese nombre).

Es a efectos del mecanismo de intercambio de variables que se introdujo un tipo separado de alcance (alcance variable).

Como resultado, terminamos teniendo dos tipos diferentes de ámbitos:

  • alcance del nombre , creado usandotf.name_scope
  • alcance variable , creado usandotf.variable_scope

Ambos alcances tienen el mismo efecto en todas las operaciones, así como en las variables creadas con tf.Variable, es decir, el alcance se agregará como prefijo a la operación o al nombre de la variable.

Sin embargo tf.get_variable, . Podemos ver eso en el siguiente ejemplo:

with tf.name_scope("my_scope"):
    v1 = tf.get_variable("var1", [1], dtype=tf.float32)
    v2 = tf.Variable(1, name="var2", dtype=tf.float32)
    a = tf.add(v1, v2)

print(v1.name)  # var1:0
print(v2.name)  # my_scope/var2:0
print(a.name)   # my_scope/Add:0

La única forma de colocar una variable a la que se accede usando tf.get_variableen un alcance es usar un alcance de variable, como en el siguiente ejemplo:

with tf.variable_scope("my_scope"):
    v1 = tf.get_variable("var1", [1], dtype=tf.float32)
    v2 = tf.Variable(1, name="var2", dtype=tf.float32)
    a = tf.add(v1, v2)

print(v1.name)  # my_scope/var1:0
print(v2.name)  # my_scope/var2:0
print(a.name)   # my_scope/Add:0

Esto nos permite compartir fácilmente variables entre diferentes partes del programa, incluso dentro de diferentes ámbitos de nombres:

with tf.name_scope("foo"):
    with tf.variable_scope("var_scope"):
        v = tf.get_variable("var", [1])
with tf.name_scope("bar"):
    with tf.variable_scope("var_scope", reuse=True):
        v1 = tf.get_variable("var", [1])
assert v1 == v
print(v.name)   # var_scope/var:0
print(v1.name)  # var_scope/var:0

ACTUALIZAR

A partir de la versión r0.11, están obsoletosop_scope y variable_op_scopereemplazados por y .name_scopevariable_scope

Andrzej Pronobis avatar May 30 '2016 23:05 Andrzej Pronobis

Tanto variable_op_scope como op_scope ahora están en desuso y no deberían usarse en absoluto.

Con respecto a los otros dos, también tuve problemas para entender la diferencia entre variable_scope y name_scope (se veían casi iguales) antes de intentar visualizar todo creando un ejemplo 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()

Aquí creo una función que crea algunas variables y constantes y las agrupa en ámbitos (según el tipo que proporcioné). En esta función, también imprimo los nombres de todas las variables. Después de eso, ejecuto el gráfico para obtener los valores de los valores resultantes y guardo los archivos de eventos para investigarlos en TensorBoard. Si ejecuta esto, obtendrá lo siguiente:

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 

Verás un patrón similar si abres TensorBoard (como ves, bestá fuera del scope_namerectángulo):


Esto te da la respuesta :

Ahora ves que tf.variable_scope()agrega un prefijo a los nombres de todas las variables (sin importar cómo las crees), operaciones, constantes. Por otro lado, tf.name_scope()ignora las variables creadas tf.get_variable()porque supone que sabes qué variable y en qué ámbito deseas usar.

Una buena documentación sobre Compartir variables te dice que

tf.variable_scope(): Administra espacios de nombres para los nombres pasados ​​a tf.get_variable().

La misma documentación proporciona más detalles sobre cómo funciona el alcance variable y cuándo es útil.

Salvador Dali avatar Apr 24 '2017 06:04 Salvador Dali