【问题标题】:How to initialise only optimizer variables in Tensorflow?如何在 Tensorflow 中仅初始化优化器变量?
【发布时间】:2017-05-22 20:33:22
【问题描述】:

我想在 Tensorflow 中使用 MomentumOptimizer。然而,由于这个优化器使用了一些内部变量,试图在不初始化这个变量的情况下使用它会产生错误:

FailedPreconditionError(参见上面的回溯):尝试使用 未初始化值Variable_2/Momentum

这可以通过初始化所有变量来轻松解决,例如使用

tf.global_variables_initializer().run()

但是,我不想初始化 所有 变量 - 只有优化器的变量。有没有办法做到这一点?

【问题讨论】:

    标签: python tensorflow


    【解决方案1】:

    还有一种更直接的方法:

    optimizer = tf.train.AdamOptimizer()
    session.run(tf.variables_initializer(optimizer.variables()))
    

    【讨论】:

    • 哇,看起来不错!好久没用Tensorflow了,好像是个新的API函数?
    • Optimizer 中的.variables() 方法是在 tensorflow 1.4 和 1.8 之间的某个时刻添加的。
    【解决方案2】:

    要解决 None 问题,只需执行以下操作:

      self.opt_vars = [opt.get_slot(var, name) for name in opt.get_slot_names() 
                       for var in self.vars_to_train
                       if opt.get_slot(var, name) is not None]
    

    【讨论】:

      【解决方案3】:

      根据 LucasB 关于AdamOptimizer 的回答,此函数采用AdamOptimizer 实例adam_opt,该实例已创建Variables(这两个之一称为:adam_opt.minimize(loss, var_list=var_list)adam_opt.apply_gradients(zip(grads, var_list))。该函数创建一个Op 调用时会为传递的变量重新初始化优化器的变量,以及全局计数状态。

      def adam_variables_initializer(adam_opt, var_list):
          adam_vars = [adam_opt.get_slot(var, name)
                       for name in adam_opt.get_slot_names()
                       for var in var_list if var is not None]
          adam_vars.extend(list(adam_opt._get_beta_accumulators()))
          return tf.variables_initializer(adam_vars)
      

      例如:

      opt = tf.train.AdamOptimizer(learning_rate=1e-4)
      fit_op = opt.minimize(loss, var_list=var_list)
      reset_opt_vars = adam_variables_initializer(opt, var_list)
      

      【讨论】:

      • 在我的情况下,adam_vars 列表可能包含 None 类型的变量,不确定是否有一种优雅的方法来解决它...目前我只是将它们全部过滤
      • @TamakiSakura 嗯,哪个?我用列表理解中的过滤器更新了答案
      • [adam_opt.get_slot(var, name) for name in adam_opt.get_slot_names() for var in var_list] 部分,我确定我的 var_list 不包含 None。我目前做的很丑:adam_vars = filter(lambda x: x is not None, adam_vars) 之前调用tf.variables_initalizer
      【解决方案4】:

      当前的两个答案都可以通过使用“Momentum”字符串过滤变量名来工作。但这在两个方面都很脆弱:

      1. 它可以静默(重新)初始化一些您实际上不想重置的其他变量!例如,可能只是因为名称冲突,或者因为您有一个更复杂的图表并分别优化不同的部分。
      2. 它只适用于一个特定的优化器,您如何知道要为其他优化器寻找的名称?
      3. 奖励:对 tensorflow 的更新可能会默默地破坏您的代码。

      幸运的是,tensorflow 的抽象Optimizer 类有一个机制,这些额外的优化器变量称为"slots",您可以使用get_slot_names() 方法获取优化器的所有插槽名称:

      opt = tf.train.MomentumOptimizer(...)
      print(opt.get_slot_names())
      # prints ['momentum']
      

      您可以使用get_slot(var, slot_name) 方法获取与特定(可训练)变量v 的槽对应的变量:

      opt.get_slot(some_var, 'momentum')
      

      将所有这些放在一起,您可以创建一个初始化优化器状态的操作,如下所示:

      var_list = # list of vars to optimize, e.g. 
                 # tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES)
      opt = tf.train.MomentumOptimizer(0.1, 0.95)
      step_op = opt.minimize(loss, var_list=var_list)
      reset_opt_op = tf.variables_initializer([opt.get_slot(var, name) for name in opt.get_slot_names() for var in var_list])
      

      这实际上只会重置正确的变量,并在优化器中保持稳健。

      除了一个unfortunate caveatAdamOptimizer。那个人还保留了一个计数器来记录它被调用的频率。这意味着无论如何你都应该认真思考你在这里所做的事情,但为了完整起见,你可以将其额外状态设为opt._get_beta_accumulators()。返回的列表应添加到上述reset_opt_op 行中的列表中。

      【讨论】:

        【解决方案5】:

        tf.variables_initializer 似乎是初始化一组特定变量的首选方式:

        var_list = [var for var in tf.global_variables() if 'Momentum' in var.name]
        var_list_init = tf.variables_initializer(var_list)
        ...
        sess = tf.Session()
        sess.run(var_list_init)
        

        【讨论】:

        • 应该是:var_list = [var for var in tf.global_variables() if 'Momentum' in var.name]
        【解决方案6】:

        您可以按名称过滤变量并仅初始化它们。浏览器

        momentum_initializers = [var.initializer for var in tf.global_variables() if 'Momentum' in var.name]
        sess.run(momentum_initializers)
        

        【讨论】:

        • 有效。为自己的变量添加前缀(你想要保留的)和那些(没有前缀 || 在其名称中有斜杠)是那些应该被初始化的。
        猜你喜欢
        • 2017-06-16
        • 2019-01-23
        • 2016-12-21
        • 2017-11-30
        • 1970-01-01
        • 1970-01-01
        • 2017-07-03
        • 2019-05-17
        • 2016-02-16
        相关资源
        最近更新 更多