在TensorFlow中有没有办法初始化未初始化的变量?

时间:2016-02-02 21:55:19

标签: python tensorflow

在TensorFlow中初始化变量的标准方法是

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

在运行一段时间的学习之后,我创建了一组新的变量,但是一旦我初始化它们就会重置我现有的所有变量。目前我的方法是保存我需要的所有变量,然后在tf.initalize_all_variables调用之后重新应用它们。这有效,但有点丑陋和笨重。我在文档中找不到这样的东西......

有没有人知道有什么好方法可以初始化未初始化的变量?

7 个答案:

答案 0 :(得分:35)

没有优雅的方法来枚举图中未初始化的变量。但是,如果您有权访问新变量对象 - 让我们称之为v_6v_7v_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)
# ...

...但是,我不会宽恕这种行为: - )。

答案 1 :(得分:31)

更新:TensorFlow 0.9有一种新方法可以修复"所有这些,但前提是您使用reuseTrue设置为sess.run( tf.initialize_variables( list( tf.get_variable(name) for name in sess.run( tf.report_uninitialized_variables( tf.all_variables( ) ) ) ) ) ) VariableScope可以在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

这仍然不如实际知道哪些变量是初始化和未初始化并且正确处理这些变量,但在像temp = set(tf.all_variables())类(见下文)这样误导的情况下,可能很难避免。

另请注意,tf.initialize_variables无法评估tf.report_uninitialized_variables,因此必须在会话的上下文中运行它们才能正常工作。

有一种不雅但简洁的方法。在介绍新变量之前,请运行sess.run(tf.initialize_variables(set(tf.all_variables()) - temp)),然后运行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)) 。这些一起只会初始化分配临时值后创建的任何变量。

我一直在玩转学习,所以我想要一个快速的方法来做,但这是我能找到的最好方法。特别是当使用像AdamOptimizer这样的东西时,它并不能让你轻松(或任何,我不确定)访问它所使用的变量。所以以下实际显示在我的代码中。 (我明确地初始化了新图层的变量,并在转移学习之前运行一次以显示初始错误。只是为了进行健全性检查。)

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

它解决了我所有的问题。

编辑: tf.report_uninitialized_variables说明解决问题的正确方法。从理论上讲,您应该使用@Lifu_Huang's answertf.train.Optimizer.get_slot_names

AttributeError: 'NoneType' object has no attribute 'initializer'

然而,这给了我{{1}}。当我弄清楚我做错了什么时,我会做编辑,所以你不会犯错误。

答案 2 :(得分:25)

TF does not have a function that does exactly what you want,但您可以轻松编写一个:

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

在这里,我提取所有global variables,迭代所有are already initialized并检查它们是否initialize。在此之后,我得到了一个未初始化的变量列表,我tf.report_uninitialized_variables()。我还打印了我要初始化的变量以用于调试目的。

您可以轻松验证其是否按预期工作:

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将确保说服所有变量都被初始化。

您也可以使用here编写类似的功能。它的草图是this article

答案 3 :(得分:4)

对于@Poik提到的情况,当变量由优化器创建以便无法直接访问时,更简洁的解决方案是使用tf.train.Optimizer.get_slot

某些优化器子类(例如MomentumOptimizerAdagradOptimizer分配和管理与要训练的变量关联的其他变量。这些被称为插槽。您可以使用tf.train.Optimizer.get_slot_names()获取优化程序具有的所有插槽名称,然后使用tf.train.Optimizer.get_slot获取为这些插槽分配的变量。

答案 4 :(得分:4)

我想出了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]

答案 5 :(得分:1)

顺便说一句,如果您只想初始化尚未使用tf.Variable初始化的单个张量(例如tf.global_variables_initializer()),那么您可以在{{1}中使用your_tensor.initializer如下例所示:

sess.run()

答案 6 :(得分:0)

我认为最简单的方法是首先创建所有训练操作符并在之后初始化变量。

例如,我通过以下方式解决了使用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())