Подтвердить что ты не робот

В TensorFlow есть ли способ просто инициализировать неинициализированные переменные?

Стандартный способ инициализации переменных в TensorFlow -

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

После некоторого обучения некоторое время я создаю новый набор переменных, но как только я их инициализирую, он сбрасывает все мои существующие переменные. В настоящий момент мой путь к этому заключается в том, чтобы сохранить всю переменную, которая мне нужна, а затем повторно применить ее после вызова tf.initalize_all_variables. Это работает, но немного уродливо и неуклюже. Я не могу найти ничего подобного в документах...

Кто-нибудь знает какой-либо хороший способ просто инициализировать неинициализированные переменные?

4b9b3361

Ответ 1

Нет никакого изящного * способа перечисления неинициализированных переменных в графе. Однако, если у вас есть доступ к новым объектам переменной mdash, позвоните им v_6, v_7 и v_8 — вы можете выборочно инициализировать их с помощью tf.initialize_variables():

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

* Процесс проб и ошибок может быть использован для идентификации неинициализированных переменных следующим образом:

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)
# ...

... однако я бы не потворствовал такому поведению: -).

Ответ 2

ОБНОВЛЕНИЕ: TensorFlow 0.9 имеет новый метод, который "исправляет" все это , но только если вы используете VariableScope с reuse установлен на True. tf.report_uninitialized_variables, который можно использовать в одной строке с sess.run( tf.initialize_variables( list( tf.get_variable(name) for name in sess.run( tf.report_uninitialized_variables( tf.all_variables( ) ) ) ) ) )

или более разумно через возможность указать переменные, которые вы ожидаете инициализировать:

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

Это все же менее идеально, чем фактически знать, какие переменные являются и не инициализированы и заботятся об этом должным образом, но в случае неправильного направления, такого как классы optim (см. ниже), это может быть трудно избежать.

Также обратите внимание: tf.initialize_variables не может оценить tf.report_uninitialized_variables, поэтому оба они должны выполняться в контексте сеанса для работы.


Существует неэлегантный, но краткий способ сделать это. Прежде чем вводить новые переменные, запустите temp = set(tf.all_variables()), а затем запустите sess.run(tf.initialize_variables(set(tf.all_variables()) - temp)). Они вместе только инициализируют любые переменные, созданные после присвоения значения темпа.

Я играю с трансляцией, поэтому мне тоже нужен быстрый способ сделать это, но это лучший способ найти. Особенно, когда вы используете такие вещи, как AdamOptimizer, который не дает вам легкого (или любого, я не уверен) доступа к переменным, которые он использует. Итак, в моем коде появилось следующее. (Я инициализирую новые переменные уровня явным образом и запускаю его один раз, чтобы показать начальную ошибку перед переносом обучения. Просто для проверки работоспособности.)

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))

И он решает все мои проблемы.

РЕДАКТИРОВАТЬ: @Lifu_Huang answer указывает правильный способ исправить мою проблему. Теоретически вы должны использовать tf.train.Optimizer.get_slot_names и tf.train.Optimizer.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()])

Это, однако, дает мне AttributeError: 'NoneType' object has no attribute 'initializer'. Я сделаю изменения, когда выясню, что я сделал не так, поэтому вы не совершаете ошибок.

Ответ 3

TF не имеет функции, которая делает именно то, что вы хотите, но вы можете легко написать ее:

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))

Здесь я извлекаю все глобальные переменные, повторяю их все и проверяю, являются ли они уже инициализированы. После этого я получаю список неинициализированных переменных, которые я initialize. Я также печатаю переменные, которые я собираюсь инициализировать для целей отладки.


Вы можете легко убедиться, что он работает так, как ожидалось:

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])

Это приведет к печати всех униализированных переменных перед их инициализацией, а последний sess.run убедит вас в том, что все переменные инициализированы.


Вы также можете использовать tf.report_uninitialized_variables() для записи аналогичной функции. Эскиз этого здесь.

Ответ 4

Для случая, упомянутого в @Poik, когда переменные создаются оптимизаторами, так что к ним нельзя получить доступ напрямую, более чистым решением является использование tf.train.Optimizer.get_slot.

Некоторые подклассы оптимизатора, такие как MomentumOptimizer и AdagradOptimizer выделяют и управляют дополнительными переменными, связанными с переменными для обучения. Они называются слотами. Вы можете использовать tf.train.Optimizer.get_slot_names(), чтобы получить все имена слотов, которые есть у оптимизатора, и затем использовать tf.train.Optimizer.get_slot для получения переменной, выделенной для этих слотов.

Ответ 5

Я придумал метод для 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]

Ответ 6

Я думаю, что самый простой способ - сначала создать все тренировочные операторы и инициализировать переменные.

Например, я решил проблему многоуровневой предварительной обработки с помощью Adam Optimizer следующим образом:

 # 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())

Ответ 7

Btw, если вы хотите инициализировать только один тензор (например, tf.Variable), который не был инициализирован с помощью tf.global_variables_initializer(), вы можете использовать your_tensor.initializer в sess.run(), как в следующем примере:

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.]]