【问题标题】:TensorFlow 1.10+ custom estimator early stopping with train_and_evaluateTensorFlow 1.10+ 自定义估算器使用 train_and_evaluate 提前停止
【发布时间】:2019-03-09 13:14:27
【问题描述】:

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

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

【问题讨论】:

  • @GPhilo 类似,但不完全一样。尚不清楚提前停止 (tf.contrib.estimator.stop_if_no_decrease_hook) 钩子是否适用于 EvalSpec
  • 我不确定我是否收到您的评论。 EvalSpec 仅指定评估的完成方式。 early-stop hook 决定在一系列非改进评估后停止训练。每一个都将根据您提供的 EvalSpec 执行,early-stop hook 与特定的评估规范无关,只关心评估周期的结果
  • @GPhilo 很可能我错了,但就我目前对stop_if_no_decrease_hook 的理解而言,max_steps_without_decrease 参数(int,最大训练步骤数,不减少给定指标)使用TrainSpec 输入函数而不是EvalSpec 输入函数?

标签: python tensorflow tensorflow-estimator


【解决方案1】:

我现在明白你的困惑了。 stop_if_no_decrease_hook 状态的文档(强调我的):

max_steps_without_decrease:int,训练步数的最大数量 给定指标没有减少。

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 部分的来源:提前停止不是根据非改进评估的数量触发的,而是根据一定步长范围内非改进评估的数量(恕我直言)有点反直觉)。

所以,回顾一下:是的,早停钩子使用评估结果来决定何时停止训练,但是你需要传入您要监控的训练步骤的数量,并记住在该数量的步骤中将进行多少次评估。

有数字的例子希望能更清楚地说明

假设您正在无限期地训练,每 1k 步进行一次评估。评估如何运行的细节无关紧要,只要它每 1k 步运行一次,产生我们想要监控的指标。

如果您将钩子设置为hook = tf.contrib.estimator.stop_if_no_decrease_hook(my_estimator, 'my_metric_to_monitor', 10000),钩子将考虑在 10k 步范围内发生的评估。

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

保持最佳模型

首先,重要说明:这与提前停止无关,在训练过程中保留最佳模型副本的问题以及在性能开始后停止训练的问题降级是完全不相关的。

保持最佳模型可以很容易地在您的EvalSpec 中定义一个tf.estimator.BestExporter(sn-p 取自链接):

  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_fnhave a look here

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

【讨论】:

  • 感谢您的澄清和解释。在这个钩子中,我怎样才能将最好的模型(根据给定的指标)导出到特定的检查点?
  • 很有用我很感激,但是serving_input_fn 的文档与许多文档一样,还有很多不足之处。什么被传递给函数?如果它是一个序列示例怎么办?为什么没有它的默认值?通过阅读这些文档以及return 的内容,我看不出我应该在该函数中写什么。
  • 另外,虽然它与提前停止没有任何关系是 OP 的一部分 :) 如果您想通过一个简单的示例深入了解服务功能(可能在 google colab 中)那会很酷。
  • "什么被传递给函数?" 任何看起来像你从input_fn 返回的东西,然后在你的模型中用作“特征”。本质上,它通过将input_fn 替换为具有适当形状的占位符来获取直接馈送到模型输入的输入。 “如果它是一个序列示例怎么办?” 没什么特别的,占位符将具有相应的形状(您定义它的形状)。 “为什么没有它的默认值?”有一些函数可以帮助你,但不可能有一个万能的默认值,因为你的模型的 input_shape 是未知的。
  • 然而,要理解这一点,您需要查看在为推理服务时如何使用已保存模型(关键字:估计器导出模型、已保存模型等)
猜你喜欢
  • 2019-04-20
  • 2019-08-09
  • 1970-01-01
  • 1970-01-01
  • 2022-11-04
  • 1970-01-01
  • 1970-01-01
  • 2020-06-01
  • 2018-08-24
相关资源
最近更新 更多