Python 如何在Tensorflow中仅初始化优化器变量?
我想在Tensorflow中使用Python 如何在Tensorflow中仅初始化优化器变量?,python,tensorflow,Python,Tensorflow,我想在Tensorflow中使用MomentumOptimizer。但是,由于此优化器使用某些内部变量,因此在不初始化此变量的情况下尝试使用它会产生错误: FailedPremissionError(回溯请参见上文):尝试使用 未初始化值变量2/动量 这可以通过初始化所有变量轻松解决,例如 tf.global_variables_initializer().run() 但是,我不想初始化所有变量,只初始化优化器的变量。有什么方法可以做到这一点吗?您可以按名称筛选变量,并且只初始化这些变量。即
MomentumOptimizer
。但是,由于此优化器使用某些内部变量,因此在不初始化此变量的情况下尝试使用它会产生错误:
FailedPremissionError
(回溯请参见上文):尝试使用
未初始化值变量2/动量
这可以通过初始化所有变量轻松解决,例如
tf.global_variables_initializer().run()
但是,我不想初始化所有变量,只初始化优化器的变量。有什么方法可以做到这一点吗?您可以按名称筛选变量,并且只初始化这些变量。即
momentum_initializers = [var.initializer for var in tf.global_variables() if 'Momentum' in var.name]
sess.run(momentum_initializers)
似乎是初始化一组特定变量的首选方法:
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)
当前的两个答案都是通过使用“动量”字符串过滤变量名来实现的。但这在两方面都非常脆弱:
它可以无声地(重新)初始化一些您实际上不想重置的其他变量!或者仅仅是因为名称冲突,或者是因为您有一个更复杂的图形并分别优化了不同的部分,例如
它只适用于一个特定的优化器,您如何知道其他优化器的名称
额外好处:对tensorflow的更新可能会悄悄地破坏您的代码
幸运的是,tensorflow的abstractOptimizer
类有一种机制,可以调用这些额外的优化器变量,您可以使用以下方法获得优化器的所有插槽名称:
您可以使用以下方法获得与特定(可训练)变量v
插槽对应的变量:
将所有这些放在一起,您可以创建一个op来初始化优化器的状态,如下所示:
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])
这实际上只会重置正确的变量,并且在整个优化器中都是健壮的
除了一个:AdamOptimizer
。这一个还保留了一个计数器,记录它被调用的频率。这意味着您应该认真考虑您在这里所做的事情,但为了完整性起见,您可以将其额外状态设置为opt.\u get\u beta\u累加器()
。返回的列表应添加到上述reset_opt_op
行中的列表中。基于LucasB关于AdamOptimizer
的回答,此函数采用创建了变量的AdamOptimizer
实例adam_opt
(其中一个称为:adam_opt(loss,var_list=var_list)
或adam_opt.apply_梯度(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)
e、 g:
要解决无问题,只需执行以下操作:
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]
有一种更直接的方法:
optimizer = tf.train.AdamOptimizer()
session.run(tf.variables_initializer(optimizer.variables()))
它应该是:var_list=[tf.global_variables()中的var for var,如果var.name中的'Momentum'是这样的话]在我的例子中,adam_vars list可能包含None类型的变量,不确定是否有一种优雅的方法来解决它……目前我只是过滤它们all@TamakiSakurahm哪些?我用列表中的过滤器更新了答案[adam_opt.get_slot(var,name)作为adam_opt中的name。get_slot_names()作为var_列表中的var]
part,我确信我的var_列表不包含任何内容。我目前做的事情非常难看:adam_vars=filter(lambda x:x不是None,adam_vars)
在调用tf.variables\u initializer
之前,这看起来很不错!我已经有一段时间没有使用Tensorflow了,但它看起来像是一个新的API函数?优化器中的variables()
方法是在Tensorflow 1.4和1.8.Works之间的某个时刻添加的。为自己的变量(你想保留的)和那些变量添加前缀(没有前缀| |名称中有斜杠)是应初始化的。
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)
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]
optimizer = tf.train.AdamOptimizer()
session.run(tf.variables_initializer(optimizer.variables()))