En TensorFlow, ¿hay alguna forma de inicializar las variables no inicializadas?


La forma estándar de inicializar variables en TensorFlow es

init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)

Después de ejecutar un poco de aprendizaje por un tiempo, creo un nuevo conjunto de variables, pero una vez que las inicializo, restablece todas mis variables existentes. Por el momento mi manera alrededor de esto es guardar toda la variable que necesito y luego volver a aplicarlos después del tf.initalize_all_variables llamada. Esto funciona, pero es un poco feo y torpe. No puedo encontrar nada como esto en los documentos...

¿alguien sabe de alguna buena manera de inicializar las variables no inicializadas?

Author: Hooked, 2016-02-03

7 answers

No hay una forma elegante* de enumerar las variables no inicializadas en un gráfico. Sin embargo, si tiene acceso a los nuevos objetos variables, llamémoslos v_6, v_7, y v_8 - puede inicializarlos selectivamente usando tf.initialize_variables():

init_new_vars_op = tf.initialize_variables([v_6, v_7, v_8])
sess.run(init_new_vars_op)

* Se podría utilizar un proceso de ensayo y error para identificar las variables no inicializadas, de la siguiente manera:

uninitialized_vars = []
for var in tf.all_variables():
    try:
        sess.run(var)
    except tf.errors.FailedPreconditionError:
        uninitialized_vars.append(var)

init_new_vars_op = tf.initialize_variables(uninitialized_vars)
# ...

...sin embargo, no toleraría tal comportamiento :-).

 29
Author: mrry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-31 04:05:04

ACTUALIZACIÓN: TensorFlow 0.9 tiene un nuevo método que" corrige " todo esto pero solo si está utilizando un VariableScope con reuse establecido en True. tf.report_uninitialized_variables que se puede utilizar en una línea con sess.run( tf.initialize_variables( list( tf.get_variable(name) for name in sess.run( tf.report_uninitialized_variables( tf.all_variables( ) ) ) ) ) )

O más inteligentemente a través de la capacidad de especificar las variables que se espera que se inicialicen:

def guarantee_initialized_variables(session, list_of_variables = None):
    if list_of_variables is None:
        list_of_variables = tf.all_variables()
    uninitialized_variables = list(tf.get_variable(name) for name in
                                   session.run(tf.report_uninitialized_variables(list_of_variables)))
    session.run(tf.initialize_variables(uninitialized_variables))
    return unintialized_variables

Esto es aún menos ideal que realmente saber qué variables son y no son inicializadas y cuidar de eso correctamente, pero en el caso de una mala dirección como las clases optim (ver más abajo) puede ser difícil de evitar.

También tenga en cuenta, tf.initialize_variables no puede evaluar tf.report_uninitialized_variables, por lo que ambos tienen que ejecutarse dentro del contexto de la sesión para trabajar.


Hay una manera poco elegante pero concisa de hacerlo. Antes de introducir sus nuevas variables ejecute temp = set(tf.all_variables()) y después ejecute sess.run(tf.initialize_variables(set(tf.all_variables()) - temp)). Estos juntos solo inicializarán cualquier variable creada después de la temperatura se asigna el valor.

He estado jugando con el aprendizaje de transferencia, así que quería una forma rápida de hacerlo también, pero esta es la mejor manera que pude encontrar. Especialmente cuando se usan cosas como AdamOptimizer, que no te da acceso fácil (o cualquiera, no estoy seguro) a las variables que usa. Así que lo siguiente realmente aparece en mi código. (Inicializo las variables de la nueva capa explícitamente, y la corro una vez para mostrar el error inicial antes de transferir el aprendizaje. Solo por una cordura comprobar.)

temp = set(tf.all_variables())
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
#I honestly don't know how else to initialize ADAM in TensorFlow.
sess.run(tf.initialize_variables(set(tf.all_variables()) - temp))

, Y resuelve todos mis problemas.

EDITAR: @La respuesta de Lifu_Huang indica la manera correcta de solucionar mi problema. Teóricamente, debe usar tf.tren.Optimizador.get_slot_names y tf.tren.Optimizador.get_slot :

optim = tf.train.AdadeltaOptimizer(1e-4)
loss = cross_entropy(y,yhat)
train_step = optim.minimize(loss)
sess.run(tf.initialize_variables([optim.get_slot(loss, name)
                                  for name in optim.get_slot_names()])

Esto sin embargo me da AttributeError: 'NoneType' object has no attribute 'initializer'. Haré ediciones cuando averigüe qué hice mal, para que no cometas mis errores.

 30
Author: Poik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:18:26

TF no tiene una función que haga exactamente lo que quieres, pero puedes escribir fácilmente una:

import tensorflow as tf

def initialize_uninitialized(sess):
    global_vars          = tf.global_variables()
    is_not_initialized   = sess.run([tf.is_variable_initialized(var) for var in global_vars])
    not_initialized_vars = [v for (v, f) in zip(global_vars, is_not_initialized) if not f]

    print [str(i.name) for i in not_initialized_vars] # only for testing
    if len(not_initialized_vars):
        sess.run(tf.variables_initializer(not_initialized_vars))

Aquí me extraer todos los variables globales, recorrer todos ellos y así comprobar si ya inicializado. Después de esto obtengo una lista de variables no inicializadas que inicializo . También imprimo variables que voy a inicializar para fines de depuración.


Puede verificar fácilmente que funciona como esperado:

a = tf.Variable(3, name='my_var_a')
b = tf.Variable(4, name='my_var_b')

sess = tf.Session()
initialize_uninitialized(sess)
initialize_uninitialized(sess)

c = tf.Variable(5, name='my_var_a') # the same name, will be resolved to different name
d = tf.Variable(6, name='my_var_d')
initialize_uninitialized(sess)

print '\n\n', sess.run([a, b, c, d])

Esto imprimirá todas las variables unitializadas antes de inicializarlas y la última sesión.run se asegurará de persuadirlo de que todas las variables se inicializan.


También puede utilizar tf.report_uninitialized_variables() para escribir una función similar. Un bosquejo de ella es aquí.

 19
Author: Salvador Dali,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-31 05:21:34

Para el caso @Poik mencionado, cuando las variables son creadas por optimizadores para que no se pueda acceder directamente, una solución más limpia es usar tf.train.Optimizer.get_slot.

Algunas subclases del optimizador, como MomentumOptimizer y AdagradOptimizer asignan y administran variables adicionales asociadas con las variables a entrenar. Estos se llaman Ranuras. Puede usar tf.train.Optimizer.get_slot_names() para obtener todos los nombres de ranura que tiene un optimizador y luego usar tf.train.Optimizer.get_slot para obtener la variable asignada para estas ranuras.

 4
Author: Lifu Huang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-18 05:47:52

Se me ocurrió un método para TensorFlow r0. 11:

def get_uninitialized_variables(variables=None):
    """Get uninitialized variables as a list.

    Parameters
    ----------
    variables : collections.Iterable[tf.Variable]
        Return only uninitialized variables within this collection.
        If not specified, will return all uninitialized variables.

    Returns
    -------
    list[tf.Variable]
    """
    sess = tf.get_default_session()
    if variables is None:
        variables = tf.all_variables()
    else:
        variables = list(variables)
    init_flag = sess.run(
        tf.pack([tf.is_variable_initialized(v) for v in variables]))
    return [v for v, f in zip(variables, init_flag) if not f]
 4
Author: 平芜泫,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-18 12:17:02

Por cierto, si desea inicializar solo un tensor (por ejemplo, tf.Variable) que no se ha inicializado usando tf.global_variables_initializer(), entonces puede usar your_tensor.initializer en sess.run() como en el siguiente ejemplo:

In [196]: weights = tf.Variable(tf.zeros(shape=(3, 4)), name='weights')

In [197]: with tf.Session() as sess:
     ...:     sess.run(weights.initializer)
     ...:     print(weights.eval())
     ...:     

# the result
[[ 0.  0.  0.  0.]
 [ 0.  0.  0.  0.]
 [ 0.  0.  0.  0.]]
 1
Author: kmario23,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-13 18:50:50

Creo que la forma más fácil es crear todos los operadores de entrenamiento primero e inicializar las variables después.

Por ejemplo, resolví el problema del preentrenamiento en capas con Adam Optimizer de la siguiente manera:

 # create an optimizer
 pretrain_optimizer =  tf.train.AdamOptimizer(learning_rate=learning_rate)

 # Make an array of the trainers for all the layers
 trainers=[pretrain_optimizer.minimize(loss_reconstruction(ae.run_less_layers(ae._input_, i+1), ae.run_less_layers(ae._input_, i+1, is_target=True)), global_step=tf.contrib.framework.get_or_create_global_step(), name='Layer_wise_optimizer_'+str(i)) for i in xrange(len(ae_shape) - 2)]

 # Initialize all the variables
 sess.run(tf.global_variables_initializer())
 0
Author: Taras Kucherenko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-10 13:10:26