TensorFlow 1.10+自定义估算器通过train_and_evaluate提前停止

时间:2018-10-04 07:55:36

标签: python tensorflow tensorflow-estimator

假定您正在使用tf.estimator.Estimator的类似设置中的验证数据集来训练tf.estimator.train_and_evaluate和自定义@simlmx's

classifier = tf.estimator.Estimator(
    model_fn=model_fn,
    model_dir=model_dir,
    params=params)

train_spec = tf.estimator.TrainSpec(
    input_fn = training_data_input_fn,
)

eval_spec = tf.estimator.EvalSpec(
    input_fn = validation_data_input_fn,
)

tf.estimator.train_and_evaluate(
    classifier,
    train_spec,
    eval_spec
)

通常,当损失对于训练数据集而不是对验证数据集持续改善时,通常使用验证数据集来中断训练以防止过度拟合。

当前,tf.estimator.EvalSpec允许您指定在多少steps(默认为100)之后评估模型。

如何(如果可能不使用tf.contrib函数)指定n次评估调用(n * steps)后终止培训,此时评估损失不会改善,然后保存“最佳”模型/检查点(由验证数据集确定)为唯一的文件名(例如best_validation.checkpoint

1 个答案:

答案 0 :(得分:9)

我现在了解您的困惑。 stop_if_no_decrease_hook状态的文档(强调我的意思):

  

max_steps_without_decrease:整数,培训步骤的最大数量   给定指标没有减少。

     

eval_dir:如果设置,则目录   包含具有评估指标的摘要文件。默认情况下,   estimator.eval_dir()将被使用。

the code of the hook (version 1.11)中,您发现:

def stop_if_no_metric_improvement_fn():
    """Returns `True` if metric does not improve within max steps."""

    eval_results = read_eval_metrics(eval_dir) #<<<<<<<<<<<<<<<<<<<<<<<

    best_val = None
    best_val_step = None
    for step, metrics in eval_results.items(): #<<<<<<<<<<<<<<<<<<<<<<<
      if step < min_steps:
        continue
      val = metrics[metric_name]
      if best_val is None or is_lhs_better(val, best_val):
        best_val = val
        best_val_step = step
      if step - best_val_step >= max_steps_without_improvement: #<<<<<
        tf_logging.info(
            'No %s in metric "%s" for %s steps, which is greater than or equal '
            'to max steps (%s) configured for early stopping.',
            increase_or_decrease, metric_name, step - best_val_step,
            max_steps_without_improvement)
        return True
    return False

代码的作用是加载评估结果(由您的EvalSpec参数生成),并提取评估结果和与特定目标相关联的global_step(或您用来计数的其他任何自定义步骤)评估记录。

这是文档training steps部分的来源:提前停止不是根据未改进评估的次数触发的,而是根据特定步长范围内未改进评估的次数触发的(恕我直言,这有点违反直觉。

因此,要概括一下:,提前停止挂钩会使用评估结果来决定何时停止培训,但是您需要通过您要监视的培训步骤数,并记住在该步骤数中将进行多少次评估。

带有数字的示例,希望可以进一步阐明

让我们假设您正在无限期地训练,每1000步进行一次评估。评估的运行方式没有具体要求,只要它每执行1k步就可以生成我们要监控的指标即可。

如果将挂钩设置为hook = tf.contrib.estimator.stop_if_no_decrease_hook(my_estimator, 'my_metric_to_monitor', 10000),则挂钩将考虑以10k步为单位进行的评估。

由于您每1k步运行1个评估,因此如果连续10次评估没有任何改善,则可以归结为提前停止。 如果这样,您决定每2k步使用一次评估进行重新运行,则该挂钩将仅考虑5个连续评估的序列,而无需进行任何改进。

保持最佳模式

首先,重要的注意事项:这与尽早停止无关,这是通过训练保留最佳模型的副本,以及一旦开始表现就停止训练的问题。降级完全无关。

保持最佳模型非常容易,您可以在EvalSpec中定义一个tf.estimator.BestExporter(摘录自链接):

  serving_input_receiver_fn = ... # define your serving_input_receiver_fn
  exporter = tf.estimator.BestExporter(
      name="best_exporter",
      serving_input_receiver_fn=serving_input_receiver_fn,
      exports_to_keep=5) # this will keep the 5 best checkpoints

  eval_spec = [tf.estimator.EvalSpec(
    input_fn=eval_input_fn,
    steps=100,
    exporters=exporter,
    start_delay_secs=0,
    throttle_secs=5)]

如果您不知道如何定义serving_input_fn have a look here

这使您可以保留获得的总体最佳5个模型,并以SavedModel的形式存储(这是目前存储模型的首选方式)。