首页 文章

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

提问于
浏览
2

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

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"模型/检查点(由验证数据集确定)保存到唯一文件名(例如 best_validation.checkpoint

1 回答

  • 7

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

    max_steps_without_decrease:int,最大训练步数,给定度量没有减少 . eval_dir:如果设置,则包含带有eval指标的摘要文件的目录 . 默认情况下,将使用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 参数生成)并提取与特定评估记录关联的eval结果和 global_step (或用于计算的其他任何自定义步骤) .

    这是文档的一部分来源:早期停止不是根据非改进评估的数量触发的,而是根据某一步骤范围内的非改进性逃避的数量触发(恕我直言有点反...直观) .

    所以,回顾一下: Yes ,早期停止的钩子使用评估结果来决定什么时候削减训练, but 你需要传递你想要监控的训练步数,并记住会发生多少次评估在那个步骤 .

    有数字的例子有希望澄清更多

    让我们假设您每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次进攻而没有改进 .

    保持最佳模式

    首先,一个重要的注意事项: this has nothing to do with early stopping ,通过培训保留最佳模型的副本以及一旦性能开始降级就停止培训的问题完全不相关 .

    保持最佳模型可以非常轻松地在 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 (这是目前存储模型的首选方式) .

相关问题