TensorFlow 1.10+ пользовательская оценка ранней остановки с train_and_evaluate

Предположим, что вы tf.estimator.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 ответ


Теперь я понимаю ваше замешательство. Документация для состояний stop_if_no_decrease_hook (основное внимание):

max_steps_without_decrease: int, максимальное количество шагов обучения без снижения данной метрики.

eval_dir: если установлено, каталог, содержащий сводные файлы с метрикой eval. По умолчанию будет использоваться method.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

Что делает код, это загрузить результаты оценки (созданные с EvalSpec параметров EvalSpec ) и извлечь результаты eval и global_step (или любой другой пользовательский шаг, который вы используете для подсчета), связанный с конкретной оценочной записью.

Это является источником части training steps в документах: ранняя остановка не запускается в соответствии с количеством неулучшающих оценок, а количеством неулучшающих оценок в определенном диапазоне шагов (что ИМХО является бит-счетчиком -Интуитивный).

Итак, чтобы повторить: да , ранний стоп-крючок использует результаты оценки, чтобы решить, когда пришло время сократить обучение, но вам нужно пройти в количестве шагов обучения, которые вы хотите контролировать, и имейте в виду, сколько будет проведено оценок в этом количестве шагов.

Примеры с номерами, которые, надеюсь, уточнят больше

Предположим, вы тренируетесь бесконечно долго, оценивая каждые 1k шагов. Специфика того, как выполняется оценка, не имеет значения, если она выполняется каждые 1 тыс. Шагов, создавая метрику, которую мы хотим контролировать.

Если вы установите крючок как hook = tf.contrib.estimator.stop_if_no_decrease_hook(my_estimator, 'my_metric_to_monitor', 10000) то крючок рассмотрит оценки, происходящие в диапазоне 10 тыс. Шагов.

Поскольку вы выполняете 1 eval каждые 1k шагов, это сводится к ранней остановке, если есть последовательность из 10 последовательных оценок без каких-либо улучшений. Если тогда вы решите повторить с оценками каждые 2 тыс. Шагов, крючок будет рассматривать только последовательность из 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)]

Если вы не знаете, как определить serving_input_fn , посмотрите здесь

Это позволяет сохранить лучшие 5 моделей, которые вы получили, сохраненные как SavedModel s (что является предпочтительным способом хранения моделей на данный момент).


Есть идеи?

10000