如何在tf-slim中使用带有train_loop的evaluation_loop

时间:2016-09-27 19:04:05

标签: tensorflow 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中的事件中看到这一点,其中所有指标都朝着正确的方向发展。朝着正确的方向前进让我感到高兴。

但我也想检查验证集上的指标是否有所改善。我不知道如何处理TF-slim的方式与训练循环很好地配合,所以我创建了第二个文件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)我目前有这个模型用于评估整个GPU的evaluation_loop,但它很少被使用。我假设有更好的方法来分配资源。如果我可以使用相同的evaluation_loop来监视多个不同模型(多个目录中的检查点)的进度,那将是非常好的。这样的事情可能吗?

2)评估和培训之间没有反馈。我训练了很多模特,并且喜欢使用早期停止来停止那些没有学习或没有收敛的模型。有没有办法做到这一点?理想情况下使用来自验证集的信息,但是如果它必须仅基于训练数据也可以。

3)我的工作流程是否全部错误,我应该以不同的方式构建它?从文档中不清楚如何将评估与培训结合使用。

更新 ~~似乎从TF r0.11开始,我在调用slim.evaluation.evaluation_loop时也遇到了段错误。它有时只发生(对我来说,当我将作业发送到集群时)。它发生在sv.managed_session - 特别是prepare_or_wait_for_session。~~ 这只是由于尝试使用GPU的评估循环(张量流的第二个实例),这已经被第一个实例请求了。

3 个答案:

答案 0 :(得分:6)

  1. evaluate_loop旨在与单个目录一起使用(正如您当前使用它)。如果你想提高效率,你可以使用slim.evaluation.evaluate_once并在你认为合适时添加适当的逻辑来交换目录。

  2. 您可以通过覆盖slim.learning.train(...,train_step_fn)参数来完成此操作。这个论点取代了' train_step'具有自定义功能的功能。在这里,您可以提供自定义培训功能,该功能将返回" total_loss'和' should_stop'你认为合适的价值观。

  3. 您的工作流程看起来很棒,这可能是使用TF-Slim学习/评估的最常用工作流程。

答案 1 :(得分:6)

感谢@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)

答案 2 :(得分:1)

添加我的2美分:

  

我目前有这个模型用于评估_loop   整个GPU,但它很少使用

通常评估模型占用较少的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)