TensorFlow中有什么方法可以初始化未初始化的变量吗?
python
tensorflow
5
0

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

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

经过一段时间的学习后,我创建了一组新的变量,但是一旦初始化它们,它将重置所有现有变量。目前,解决此问题的方法是保存我需要的所有变量,然后在tf.initalize_all_variables调用之后重新应用它们。这有效,但是有点笨拙。我在文档中找不到类似的内容...

有谁知道初始化未初始化变量的好方法吗?

参考资料:
Stack Overflow
收藏
评论
共 5 个回答
高赞 时间 活跃

更新: TensorFlow 0.9有一个新方法可以“修复”所有问题, 但前提是您使用的VariableScopereuse设置为Truetf.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( ) ) ) ) ) )一起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类(见下文)这样的错误optim的情况下,可能很难避免。

还请注意,tf.initialize_variables无法评估tf.report_uninitialized_variables,因此它们两者都必须在会话上下文中运行才能起作用。


有一个优雅但简洁的方法可以做到这一点。在引入新变量之前,请运行temp = set(tf.all_variables()) ,然后运行sess.run(tf.initialize_variables(set(tf.all_variables()) - temp)) 。这些一起只能初始化分配了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的答案陈述了解决我的问题的正确方法。从理论上讲,您应该使用tf.train.Optimizer.get_slot_namestf.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' 。当我弄清楚我做错了什么时,我将进行编辑,这样您就不会犯我的错误。

收藏
评论

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

在这里,我提取所有全局变量 ,对所有全局变量进行迭代,然后检查它们是否已初始化 。之后,我会得到一个未初始化的变量列表,这些变量会进行初始化 。我还将打印用于调试目的而初始化的变量。


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

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()编写类似的函数。它的草图在这里

收藏
评论

没有优雅的方法可以枚举图中的未初始化变量。但是,如果您可以访问新的变量对象(我们将它们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)
# ...

...但是,我不会容忍这种行为:-)。

收藏
评论

我想出了一个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]
收藏
评论

对于提到的@Poik情况,当优化器创建变量以使其不能直接访问时,更干净的解决方案是使用tf.train.Optimizer.get_slot

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

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号