Tensorflow 如何使用tf.train.MonitoredTrainingSession仅恢复某些变量
如何让tf.train.MonitoredTrainingSession仅恢复变量的一个子集,并对其余变量执行初始化? 从cifar10教程开始。。 。。我创建了要还原和初始化的变量列表,并使用传递给MonitoredTrainingSession的支架指定了它们:Tensorflow 如何使用tf.train.MonitoredTrainingSession仅恢复某些变量,tensorflow,Tensorflow,如何让tf.train.MonitoredTrainingSession仅恢复变量的一个子集,并对其余变量执行初始化? 从cifar10教程开始。。 。。我创建了要还原和初始化的变量列表,并使用传递给MonitoredTrainingSession的支架指定了它们: restoration_saver = Saver(var_list=restore_vars) restoration_scaffold = Scaffold(init_op=variables_initializer(
restoration_saver = Saver(var_list=restore_vars)
restoration_scaffold = Scaffold(init_op=variables_initializer(init_vars),
ready_op=constant([]),
saver=restoration_saver)
但这会产生以下错误:
RuntimeError:初始化操作未使模型为本地初始化做好准备。Init op:group_deps,Init fn:None,error:Variables not initialized:conv2a/T,conv2b/T,[…]
。。其中,错误消息中列出的未初始化变量是我的“init_vars”列表中的变量
SessionManager.prepare_session()引发异常。该方法的源代码似乎表明,如果会话是从检查点恢复的,则init_op不会运行。因此,看起来您可以使用还原变量或初始化变量,但不能同时使用两者。好吧,正如我所怀疑的,我通过基于现有tf.training.SessionManager实现一个新的RefinementSessionManager类实现了我想要的。这两个类几乎相同,只是我修改了prepare_session方法来调用init_op,而不管模型是否从检查点加载 这允许我从检查点加载变量列表,并初始化init_op中的其余变量 我的准备会话方法如下:
def prepare_session(self, master, init_op=None, saver=None,
checkpoint_dir=None, wait_for_checkpoint=False,
max_wait_secs=7200, config=None, init_feed_dict=None,
init_fn=None):
sess, is_loaded_from_checkpoint = self._restore_checkpoint(
master,
saver,
checkpoint_dir=checkpoint_dir,
wait_for_checkpoint=wait_for_checkpoint,
max_wait_secs=max_wait_secs,
config=config)
# [removed] if not is_loaded_from_checkpoint:
# we still want to run any supplied initialization on models that
# were loaded from checkpoint.
if not is_loaded_from_checkpoint and init_op is None and not init_fn and self._local_init_op is None:
raise RuntimeError("Model is not initialized and no init_op or "
"init_fn or local_init_op was given")
if init_op is not None:
sess.run(init_op, feed_dict=init_feed_dict)
if init_fn:
init_fn(sess)
# [...]
希望这对其他人有所帮助。您可以使用
local\u init\u op
参数解决此问题,该参数在从检查点加载后运行。来自@avital的提示有效,为了更完整:使用local\u init\u op
和aready\u for\u local\u init\u op
将脚手架对象传递到MonitoredTrainingSession
。像这样:
model_ready_for_local_init_op = tf.report_uninitialized_variables(
var_list=var_list)
model_init_tmp_vars = tf.variables_initializer(var_list)
scaffold = tf.train.Scaffold(saver=model_saver,
local_init_op = model_init_tmp_vars,
ready_for_local_init_op = model_ready_for_local_init_op)
with tf.train.MonitoredTrainingSession(...,
scaffold=scaffold,
...) as mon_sess:
...
脚手架包含以下内容:
- 初始操作
- 准备好了吗
- 本地初始化操作
- 准备好进行本地初始化操作了吗
init_op
仅当我们不从检查点还原时才会被调用
如果未从检查点加载:
如果init_op为None,而不是init_fn和self。_local_init_op为None:
raise RUNTIMERROR(“模型未初始化且没有初始化或”
“已给出初始值fn或本地初始值”)
如果init_op不是None:
sess.run(init_op,feed_dict=init_feed_dict)
如果初始化fn:
初始值(sess)
所以实际上,init_op
在这里帮不上忙。如果您可以编写一个新的会话管理器
,您可以使用@user550701。我们也可以使用local\u init\u op
,但在分布式情况下可能有点棘手
Scaffold
将为我们生成默认的init_op
和local_init_op
:
- 初始化操作:将初始化
tf.global\u变量
- local_init_op:将初始化
tf.local_变量
我们应该初始化变量,同时不要破坏默认机制
一名工人的情况
您可以这样创建local\u init\u op
:
target_collection = [] # Put your target tensors here
collection = tf.local_variables() + target_collection
local_init_op = tf.variables_initializer(collection)
ready_for_local_init_op = tf.report_uninitialized_variables(collection)
分布情况
我们应该注意重复初始化我们的target\u集合
,因为local\u init\u op
将在多个worker上被多次调用。如果变量是局部变量,则没有区别。如果它们是全局变量,我们应该确保只初始化一次。为了解决重复问题,我们可以操作集合
变量。在chief worker上,它包括局部变量和我们的target\u集合
。而对于非首席员工,我们只将局部变量放入其中
if is_chief:
collection = tf.local_variables() + target_collection
else:
collection = tf.local_variables()
总而言之,这有点棘手,但我们不必侵入tensorflow。我也遇到了同样的问题,我的解决方案是
checkpoint_restore_dir_for_monitered_session = None
scaffold = None
if params.restore:
checkpoint_restore_dir_for_monitered_session = checkpoint_save_dir
restore_exclude_name_list = params.restore_exclude_name_list
if len(restore_exclude_name_list) != 0:
variables_to_restore, variables_dont_restore = get_restore_var_list(restore_exclude_name_list)
saver_for_restore = tf.train.Saver(var_list=variables_to_restore, name='saver_for_restore')
ready_for_local_init_op = tf.report_uninitialized_variables(variables_to_restore.values())
local_init_op = tf.group([
tf.initializers.local_variables(),
tf.initializers.variables(variables_dont_restore)
])
scaffold = tf.train.Scaffold(saver=saver_for_restore,
ready_for_local_init_op=ready_for_local_init_op,
local_init_op=local_init_op)
with tf.train.MonitoredTrainingSession(
checkpoint_dir=checkpoint_restore_dir_for_monitered_session,
save_checkpoint_secs=None, # don't save ckpt
hooks=train_hooks,
config=config,
scaffold=scaffold,
summary_dir=params.log_dir) as sess:
pass
在此代码片段中,get\u restore\u var\u list
getvariables\u to\u restore
和variables\u not\u restore
saver\u for_restore
仅将variables\u中的变量还原为_restore
,然后由ready\u for_local\u init\u op
检查并传递。
然后运行local\u init\u op
,初始化local\u variables()
和variables\u not\u restore
(可能是tf.variance\u scaling\u initializer
。我不明白。如果您将模型变量指定为local_init_op,您不是要初始化两次吗?这不应该是其他未保存在模型中的变量吗?首先,我认为两次初始化变量不是一个大问题,其次,您要选择var_列表中的变量。这个问题是关于恢复一些变量并初始化模型中可能存在的其他变量。但是也许我没有正确回答你的问题?如果我还原一个变量然后初始化它会发生什么?那么,恢复的状态不会被覆盖吗?因为var\u list
只包含我正在保存的变量,对吗?我的理解是,model\u ready\u for_local\u init\u op
让我知道var\u list
中的所有变量何时被初始化(从模型还原),即返回一个空列表,然后我可以继续初始化未存储的其他变量(即model\u init\u tmp\u vars
)?来自Scaffold的文档:ready_for_local_init_op:Optional op,用于验证全局变量已初始化,并且可以运行local_init_op。初始化全局变量时,必须返回空的1D字符串张量,或者是一个非空的一维字符串张量,列出了未初始化的全局变量的名称。
那么,对于ready\u和local\u init\u op
使用相同的变量列表有什么意义呢?就像对未来旅行者的警告一样,如果