TensorFlow 1.10+自定义估算器使用train_and_evaluate提前停止

Sum*_*ron 5 python tensorflow tensorflow-estimator

假设你正在训练的自定义tf.estimator.Estimatortf.estimator.train_and_evaluate在类似的设置使用验证数据集@ simlmx的:

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
)
Run Code Online (Sandbox Code Playgroud)

通常,当训练数据集的损失继续改善而不是验证数据集时,使用验证数据集来切断训练以防止过度拟合.

目前,tf.estimator.EvalSpec允许用户指定steps评估模型的数量(默认为100).

一个(如果可能不使用tf.contrib函数)如何指定在评估丢失n数量(n * steps)之后终止训练,其中评估损失没有改善,然后将"最佳"模型/检查点(由验证数据集确定)保存到唯一文件名(例如best_validation.checkpoint)

GPh*_*ilo 13

我现在明白你的困惑.国家文件stop_if_no_decrease_hook(强调我的):

max_steps_without_decrease:int,最大训练步数,给定度量没有减少.

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

翻翻挂钩(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
Run Code Online (Sandbox Code Playgroud)

代码所做的是加载评估结果(使用您的EvalSpec参数生成)并提取eval结果以及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次eval,如果连续10次进行一系列没有任何改进,这可归结为提前停止.如果那时你决定每2k步重新运行一次,那么钩子只会考虑连续5次进攻的序列而没有改进.

保持最好的模型

首先,一个重要的注意事项:这与早期停止无关,通过培训保留最佳模型副本的问题以及一旦性能开始降级就停止训练的问题完全不相关.

保持最佳模型可以非常轻松地定义tf.estimator.BestExporter你的EvalSpec(从链接中获取的片段):

  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)]
Run Code Online (Sandbox Code Playgroud)

如果您不知道如何定义,serving_input_fn 请看这里

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