【问题标题】:How to use evaluation_loop with train_loop in tf-slim如何在 tf-slim 中使用evaluation_loop和train_loop
【发布时间】:2017-02-05 13:05:54
【问题描述】:

我正在尝试实现几个不同的模型并在 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,但它很少被使用。我认为有更好的方法来分配资源。如果我可以使用相同的评估循环来监控多个不同模型的进度(多个目录中的检查点),那就太好了。这样的事情可能吗?

2) 评估和培训之间没有反馈。我正在训练大量模型,并且希望使用提前停止来停止未学习或未收敛的模型。有没有办法做到这一点?理想情况下使用来自验证集的信息,但如果它必须仅基于训练数据,也可以。

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

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

【问题讨论】:

  • 您解决了评估和培训之间的反馈问题吗?如果是,你能详细说明一下吗?

标签: tensorflow tf-slim


【解决方案1】:
  1. evaluation_loop 旨在与单个目录一起使用(正如您当前正在使用的那样)。如果您想提高效率,可以使用 slim.evaluation.evaluate_once 并根据需要添加适当的逻辑来交换目录。

  2. 您可以通过覆盖 slim.learning.train(..., train_step_fn) 参数来做到这一点。此参数将“train_step”函数替换为自定义函数。在这里,您可以提供自定义训练函数,该函数返回您认为合适的“total_loss”和“should_stop”值。

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

【讨论】:

    【解决方案2】:

    添加我的 2 美分:

    我目前有这个用于评估循环的模型 整个 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)
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 如何在整个 epoch 中运行 accuracy_validation?我只能让它为 1 个小批量工作。
      • @michael 你的意思是代码中的accuracy_validation 只是计算一个小批量数据的准确性吗?如果是,那么您可以在源问题中阅读更多详细信息。 accuracy_validation 实际上是一个操作,您可以根据需要提供尽可能多的数据,包括整个验证数据。
      猜你喜欢
      • 2017-10-28
      • 2018-04-16
      • 2017-11-06
      • 1970-01-01
      • 2018-07-11
      • 2018-03-04
      • 2018-08-13
      • 1970-01-01
      • 2018-07-14
      相关资源
      最近更新 更多