如何在 tf-slim 中使用 evaluation_loop 和 train_loop
How to use evaluation_loop with train_loop in tf-slim
我正在尝试实现几个不同的模型并在 CIFAR-10 上训练它们,我想使用 TF-slim 来执行此操作。看起来 TF-slim 有两个在训练期间很有用的主要循环:train_loop 和 evaluation_loop。
我的问题是:使用这些循环的规范方法是什么?
作为后续行动:是否可以使用 train_loop 提前停止?
目前我有一个模型,我的训练文件train.py看起来像这样
import ...
train_log_dir = ...
with tf.device("/cpu:0"):
images, labels, dataset = set_up_input_pipeline_with_fancy_prefetching(
subset='train', ... )
logits, end_points = set_up_model( images ) // Possibly using many GPUs
total_loss = set_up_loss( logits, labels, dataset )
optimizer, global_step = set_up_optimizer( dataset )
train_tensor = slim.learning.create_train_op(
total_loss,
optimizer,
global_step=global_step,
clip_gradient_norm=FLAGS.clip_gradient_norm,
summarize_gradients=True)
slim.learning.train(train_tensor,
logdir=train_log_dir,
local_init_op=tf.initialize_local_variables(),
save_summaries_secs=FLAGS.save_summaries_secs,
save_interval_secs=FLAGS.save_interval_secs)
到目前为止,这很棒 - 我的模型都很好地训练和收敛。我可以从 train_log_dir
中的事件中看到这一点,其中所有指标都朝着正确的方向发展。朝着正确的方向前进让我很开心。
但我想检查验证集上的指标是否也在改进。我不知道有什么方法可以很好地处理训练循环,因此我创建了另一个名为 eval.py
的文件,其中包含我的评估循环。
import ...
train_log_dir = ...
with tf.device("/cpu:0"):
images, labels, dataset = set_up_input_pipeline_with_fancy_prefetching(
subset='validation', ... )
logits, end_points = set_up_model( images )
summary_ops, names_to_values, names_to_updates = create_metrics_and_summary_ops(
logits,
labels,
dataset.num_classes() )
slim.get_or_create_global_step()
slim.evaluation.evaluation_loop(
'',
checkpoint_dir=train_log_dir,
logdir=train_log_dir,
num_evals=FLAGS.num_eval_batches,
eval_op=names_to_updates.values(),
summary_op=tf.merge_summary(summary_ops),
eval_interval_secs=FLAGS.eval_interval_secs,
session_config=config)
问题:
1) 我目前有这个模型用于 evaluation_loop 占用整个 GPU,但它很少被使用。我假设有更好的方法来分配资源。如果我可以使用相同的 evaluation_loop 来监视多个不同模型(多个目录中的检查点)的进度,那就太好了。这样的事情可能吗?
2) 评估和培训之间没有反馈。我正在训练大量模型,并且很乐意使用提前停止来停止不学习或不收敛的模型。有没有办法做到这一点?理想情况下使用来自验证集的信息,但如果它必须仅基于训练数据也没关系。
3) 我的工作流程是不是全错了,我应该以不同的方式构建它?从文档中不清楚如何将评估与培训结合使用。
更新
~~似乎从 TF r0.11 开始,我在调用 slim.evaluation.evaluation_loop
时也遇到了段错误。它只是有时发生(对我来说,当我将我的工作分配到一个集群时)。它发生在 sv.managed_session
——特别是 prepare_or_wait_for_session
。~~
这只是由于评估循环(tensorflow 的第二个实例)试图使用已被第一个实例征用的 GPU。
evaluation_loop 用于(正如您当前正在使用的)单个目录。如果您想提高效率,可以使用 slim.evaluation.evaluate_once 并在您认为合适的时候添加适当的逻辑来交换目录。
您可以通过覆盖 slim.learning.train(..., train_step_fn) 参数来实现。此参数将 'train_step' 函数替换为自定义函数。在这里,您可以提供自定义训练函数,其中 returns 您认为合适的 'total_loss' 和 'should_stop' 值。
您的工作流程看起来很棒,这可能是 learning/eval 使用 TF-Slim 最常见的工作流程。
加上我的 2 美分:
I currently have this model for the evaluation_loop hogging up an
entire GPU, but it's rarely being used
通常评估模型占用的 GPU 内存较少。您可以通过将会话配置 allow_growth
设置为 True
来防止 TF 占用整个 GPU 内存。这样您就可以使用相同的 GPU 进行训练和评估
例子@培训
session_config = tf.ConfigProto()
session_config.gpu_options.allow_growth = True
slim.learning.train(train_tensor,
logdir=train_log_dir,
local_init_op=tf.initialize_local_variables(),
save_summaries_secs=FLAGS.save_summaries_secs,
save_interval_secs=FLAGS.save_interval_secs,
session_config=session_config)
示例@验证
session_config = tf.ConfigProto()
session_config.gpu_options.allow_growth = True
slim.evaluation.evaluation_loop(
'',
checkpoint_dir=train_log_dir,
logdir=train_log_dir,
num_evals=FLAGS.num_eval_batches,
eval_op=names_to_updates.values(),
summary_op=tf.merge_summary(summary_ops),
eval_interval_secs=FLAGS.eval_interval_secs,
session_config=session_config)
感谢@kmalakoff,the TensorFlow issue 为如何在 tf.slim
训练中验证或测试模型的问题提供了一个绝妙的方法。主要思想是覆盖 train_step_fn
函数:
import …
from tensorflow.contrib.slim.python.slim.learning import train_step
...
accuracy_validation = ...
accuracy_test = ...
def train_step_fn(session, *args, **kwargs):
total_loss, should_stop = train_step(session, *args, **kwargs)
if train_step_fn.step % FLAGS.validation_every_n_step == 0:
accuracy = session.run(train_step_fn.accuracy_validation)
print('your validation info')
if train_step_fn.step % FLAGS.test_every_n_step == 0:
accuracy = session.run(train_step_fn.accuracy_test)
print('your test info')
train_step_fn.step += 1
return [total_loss, should_stop]
train_step_fn.step = 0
train_step_fn.accuracy_validation = accuracy_validation
train_step_fn.accuracy_test = accuracy_test
# run training.
slim.learning.train(
train_op,
FLAGS.logs_dir,
train_step_fn=train_step_fn,
graph=graph,
number_of_steps=FLAGS.max_steps)
我正在尝试实现几个不同的模型并在 CIFAR-10 上训练它们,我想使用 TF-slim 来执行此操作。看起来 TF-slim 有两个在训练期间很有用的主要循环:train_loop 和 evaluation_loop。
我的问题是:使用这些循环的规范方法是什么? 作为后续行动:是否可以使用 train_loop 提前停止?
目前我有一个模型,我的训练文件train.py看起来像这样
import ...
train_log_dir = ...
with tf.device("/cpu:0"):
images, labels, dataset = set_up_input_pipeline_with_fancy_prefetching(
subset='train', ... )
logits, end_points = set_up_model( images ) // Possibly using many GPUs
total_loss = set_up_loss( logits, labels, dataset )
optimizer, global_step = set_up_optimizer( dataset )
train_tensor = slim.learning.create_train_op(
total_loss,
optimizer,
global_step=global_step,
clip_gradient_norm=FLAGS.clip_gradient_norm,
summarize_gradients=True)
slim.learning.train(train_tensor,
logdir=train_log_dir,
local_init_op=tf.initialize_local_variables(),
save_summaries_secs=FLAGS.save_summaries_secs,
save_interval_secs=FLAGS.save_interval_secs)
到目前为止,这很棒 - 我的模型都很好地训练和收敛。我可以从 train_log_dir
中的事件中看到这一点,其中所有指标都朝着正确的方向发展。朝着正确的方向前进让我很开心。
但我想检查验证集上的指标是否也在改进。我不知道有什么方法可以很好地处理训练循环,因此我创建了另一个名为 eval.py
的文件,其中包含我的评估循环。
import ...
train_log_dir = ...
with tf.device("/cpu:0"):
images, labels, dataset = set_up_input_pipeline_with_fancy_prefetching(
subset='validation', ... )
logits, end_points = set_up_model( images )
summary_ops, names_to_values, names_to_updates = create_metrics_and_summary_ops(
logits,
labels,
dataset.num_classes() )
slim.get_or_create_global_step()
slim.evaluation.evaluation_loop(
'',
checkpoint_dir=train_log_dir,
logdir=train_log_dir,
num_evals=FLAGS.num_eval_batches,
eval_op=names_to_updates.values(),
summary_op=tf.merge_summary(summary_ops),
eval_interval_secs=FLAGS.eval_interval_secs,
session_config=config)
问题:
1) 我目前有这个模型用于 evaluation_loop 占用整个 GPU,但它很少被使用。我假设有更好的方法来分配资源。如果我可以使用相同的 evaluation_loop 来监视多个不同模型(多个目录中的检查点)的进度,那就太好了。这样的事情可能吗?
2) 评估和培训之间没有反馈。我正在训练大量模型,并且很乐意使用提前停止来停止不学习或不收敛的模型。有没有办法做到这一点?理想情况下使用来自验证集的信息,但如果它必须仅基于训练数据也没关系。
3) 我的工作流程是不是全错了,我应该以不同的方式构建它?从文档中不清楚如何将评估与培训结合使用。
更新
~~似乎从 TF r0.11 开始,我在调用 slim.evaluation.evaluation_loop
时也遇到了段错误。它只是有时发生(对我来说,当我将我的工作分配到一个集群时)。它发生在 sv.managed_session
——特别是 prepare_or_wait_for_session
。~~
这只是由于评估循环(tensorflow 的第二个实例)试图使用已被第一个实例征用的 GPU。
evaluation_loop 用于(正如您当前正在使用的)单个目录。如果您想提高效率,可以使用 slim.evaluation.evaluate_once 并在您认为合适的时候添加适当的逻辑来交换目录。
您可以通过覆盖 slim.learning.train(..., train_step_fn) 参数来实现。此参数将 'train_step' 函数替换为自定义函数。在这里,您可以提供自定义训练函数,其中 returns 您认为合适的 'total_loss' 和 'should_stop' 值。
您的工作流程看起来很棒,这可能是 learning/eval 使用 TF-Slim 最常见的工作流程。
加上我的 2 美分:
I currently have this model for the evaluation_loop hogging up an entire GPU, but it's rarely being used
通常评估模型占用的 GPU 内存较少。您可以通过将会话配置 allow_growth
设置为 True
来防止 TF 占用整个 GPU 内存。这样您就可以使用相同的 GPU 进行训练和评估
例子@培训
session_config = tf.ConfigProto()
session_config.gpu_options.allow_growth = True
slim.learning.train(train_tensor,
logdir=train_log_dir,
local_init_op=tf.initialize_local_variables(),
save_summaries_secs=FLAGS.save_summaries_secs,
save_interval_secs=FLAGS.save_interval_secs,
session_config=session_config)
示例@验证
session_config = tf.ConfigProto()
session_config.gpu_options.allow_growth = True
slim.evaluation.evaluation_loop(
'',
checkpoint_dir=train_log_dir,
logdir=train_log_dir,
num_evals=FLAGS.num_eval_batches,
eval_op=names_to_updates.values(),
summary_op=tf.merge_summary(summary_ops),
eval_interval_secs=FLAGS.eval_interval_secs,
session_config=session_config)
感谢@kmalakoff,the TensorFlow issue 为如何在 tf.slim
训练中验证或测试模型的问题提供了一个绝妙的方法。主要思想是覆盖 train_step_fn
函数:
import …
from tensorflow.contrib.slim.python.slim.learning import train_step
...
accuracy_validation = ...
accuracy_test = ...
def train_step_fn(session, *args, **kwargs):
total_loss, should_stop = train_step(session, *args, **kwargs)
if train_step_fn.step % FLAGS.validation_every_n_step == 0:
accuracy = session.run(train_step_fn.accuracy_validation)
print('your validation info')
if train_step_fn.step % FLAGS.test_every_n_step == 0:
accuracy = session.run(train_step_fn.accuracy_test)
print('your test info')
train_step_fn.step += 1
return [total_loss, should_stop]
train_step_fn.step = 0
train_step_fn.accuracy_validation = accuracy_validation
train_step_fn.accuracy_test = accuracy_test
# run training.
slim.learning.train(
train_op,
FLAGS.logs_dir,
train_step_fn=train_step_fn,
graph=graph,
number_of_steps=FLAGS.max_steps)