Продолжить обучение пользовательского tf.Estimator с AdamOptimizer - PullRequest
0 голосов
/ 06 января 2019

Я создал пользовательский tf.Estimator, вес которого я тренирую, используя tf.train.AdamOptimizer. Когда я продолжаю обучение существующей модели, я наблюдаю резкое изменение показателей в начале продолжения обучения в Tensorboard. Через несколько шагов показатели стабилизируются. Поведение выглядит аналогично начальным переходным процессам при обучении модели. Поведение такое же, если я продолжаю тренироваться на том же экземпляре оценщика, или если я воссоздаю оценщик с контрольной точки. Я подозреваю, что скользящие средние и / или поправочный коэффициент смещения сбрасываются при возобновлении тренировки. Кажется, что сами весы моделей должным образом восстановлены, поскольку показатели продолжают идти от того места, где они были установлены ранее, только эффективная скорость обучения представляется слишком высокой.

Предыдущие ответы о переполнении стека, по-видимому, предполагают, что эти вспомогательные параметры обучения должны храниться вместе с контрольными точками вместе с весами модели. Так что я тут делаю не так? Как я могу контролировать восстановление этих вспомогательных переменных? Я хотел бы иметь возможность продолжать тренировки, как будто они никогда не были остановлены. Однако иногда кажется, что другие люди ищут противоположный элемент управления, чтобы полностью сбросить оптимизатор без сброса весов модели. Ответ, который показывает, как можно достичь обоих эффектов, вероятно, был бы наиболее полезным.

Вот набросок моего model_fn:

def model_fn(features, labels, mode, params):
    inputs = features['inputs']
    logits = create_model(inputs, training=mode == tf.estimator.ModeKeys.TRAIN)

    if mode == tf.estimator.ModeKeys.PREDICT:
        ...

    if mode == tf.estimator.ModeKeys.TRAIN:
        outputs = labels['outputs']

        loss = tf.losses.softmax_cross_entropy(
            tf.one_hot(outputs,tf.shape(inputs)[-1]),
            logits,
#            reduction=tf.losses.Reduction.MEAN,
        )
        optimizer = tf.train.AdamOptimizer(learning_rate=params.learning_rate)

        update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)

        with tf.control_dependencies(update_ops):
            train_op = optimizer.minimize(loss, tf.train.get_or_create_global_step())

        accuracy = tf.metrics.accuracy(
            labels = outputs,
            predictions = tf.argmax(logits, axis=-1),
        )

        tf.summary.histogram('logits',logits)
        tf.summary.scalar('accuracy', accuracy[1])
        tf.summary.scalar('loss', loss)

        return tf.estimator.EstimatorSpec(
            mode=tf.estimator.ModeKeys.TRAIN,
            loss=loss,
            train_op=train_op)

    if mode == tf.estimator.ModeKeys.EVAL:
        ...

    raise ValueError(mode)

Этап обучения называется следующим образом:

cfg = tf.estimator.RunConfig(
    save_checkpoints_secs = 5*60,  # Save checkpoints every 1 minutes.
    keep_checkpoint_max = 10,       # Retain the 10 most recent checkpoints.
    save_summary_steps = 10,
    log_step_count_steps = 100,
)
estimator = tf.estimator.Estimator(
    model_fn = model_fn,
    params = dict(
        learning_rate = 1e-3,
    ),
    model_dir = model_dir,
    config=cfg,
)
# train for the first time
estimator.train(
    input_fn=train_input_fn,
)
# ... at some later time, train again
estimator.train(
    input_fn=train_input_fn,
)

EDIT:

Документация аргумента warm_start_from для tf.estimator.Estimator и tf.estimator.WarmStartSettings не совсем ясна, что именно произойдет в случае по умолчанию, как я использую в пример выше. Тем не менее, документация [tf.train.warm_start] (https://www.tensorflow.org/api_docs/python/tf/train/warm_start), по-видимому, предполагает, что в случае по умолчанию все TRAINABLE_VARIABLES будут запускаться с подогревом, что

исключает такие переменные, как аккумуляторы и статистика перемещения, из нормы партии

Действительно, я нахожу переменные-аккумуляторы Адама в VARIABLES, но не в TRAINABLE_VARIABLES. На этих страницах документации также указано, как изменить список переменных с горячим запуском на список tf.Variable экземпляров или список их имен. Однако остается один вопрос: как мне заранее создать один из этих списков, учитывая, что с tf.Estimator у меня нет графика для сбора этих переменных / их имен?

EDIT2:

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

    warm_start_from=tf.estimator.WarmStartSettings(
        ckpt_to_initialize_from=str(model_dir),
    #    vars_to_warm_start=".*", # everything in TRAINABLE_VARIABLES - excluding optimiser params 
        vars_to_warm_start=[".*"], # everything in GLOBAL_VARIABLES - including optimiser params 
    ),

чтобы загрузить все переменные. Однако, даже с этим, всплески в общей статистике остаются. С этим я полностью растерялся, что происходит.

1 Ответ

0 голосов
/ 09 января 2019

По умолчанию метрики добавляются в локальные переменные и метрические переменные коллекции, и по умолчанию они не имеют контрольных точек.

Если вы хотите включить их в контрольные точки, вы можете добавить метрические переменные в коллекцию глобальных переменных:

tf.add_to_collection(tf.GraphKeys.GLOBAL_VARIABLES, tf.get_collection(tf.GraphKeys.METRIC_VARIABLES))

Или вы можете вернуть Scaffold с помощью custom Saver set , передав переменные в контрольную точку Saver s var_list аргумент . По умолчанию это коллекция глобальных переменных.

...