четверг, 11 октября 2018 г.

TensorFlow Estimators: сохранение и восстановление моделей

В этом посте мы рассмотрим как сохранять и восстанавливать TensorFlow модели, построенные с Estimators. TensorFlow предоставляет два формата моделей:

  • Контрольные точки - это формат, зависимый от кода, создающего модель.
  • SavedModel - формат, независимый от кода, создающего модель.

В этом посте мы будем использовать формат контрольных точек.

Код примера

Мы будем использовать пример классификации ирисов из предыдущего поста. Чтобы загрузить этот пример выполните следующее:

git clone https://github.com/tensorflow/models/
cd models/samples/core/get_started

Большинство отрывков кода в этом посте - это минимальные вариации premade_estimator.py.

Сохранение частично-тренированных моделей.

Estimators автоматически записывают следующее на диск:

  • Контрольные точки - версии модели, созданные в ходе тренировки.
  • Файлы событий, содержащие информацию, которую использует TensorBoard для создания визуализаций.

Чтобы определить директорию верхнего уровня, в которую Estimator сохраняет эту информацию, назначим значение для опционального model_dir аргумента любого Estimator конструктора. Для DNNClassifier, например, следующий код устанавливает model_dir аргумент равным models/iris директории:

classifier = tf.estimator.DNNClassifier(
    feature_columns=my_feature_columns,
    hidden_units=[10, 10],
    n_classes=3,
    model_dir='models/iris')

Предположим был вызван train метод Estimator'а. Например:

classifier.train(
        input_fn=lambda:train_input_fn(train_x, train_y, batch_size=100),
                steps=200)

Как изображено на следующей диаграмме, первый вызов train добавляет контрольные точки и другие файлы в model_dir директорию:

Первый вызов train()


Чтобы увидеть объекты в созданной model_dir директории в системе UNIX семейства просто вызовете ls команду:

$ ls -1 models/iris
checkpoint
events.out.tfevents.timestamp.hostname
graph.pbtxt
model.ckpt-1.data-00000-of-00001
model.ckpt-1.index
model.ckpt-1.meta
model.ckpt-200.data-00000-of-00001
model.ckpt-200.index
model.ckpt-200.meta

Предыдущая ls команда показывает, что Estimator создал контрольные точки на шаге 1 (начало тренировки) и 200 (конец тренировки).

Директория контрольных точек по умолчанию

Если не определить model_dir в конструкторе Estimator'а, Estimator запишет файлы контрольной точки во временную директорию, выбранную Python tempfile.mkdtemp фукнцией. Например, следующий Estimator конструктор не определяет model_dir аргумент:

classifier = tf.estimator.DNNClassifier(
    feature_columns=my_feature_columns,
    hidden_units=[10, 10],
    n_classes=3)

print(classifier.model_dir)

tempfile.mkdtemp функция выбирает защищенную, временную директорию согласно операционной системе. Например, обычная временная директория для macOS может выглядеть примерно следующим образом:

/var/folders/0s/5q9kfzfj3gx2knj0vj8p68yc00dhcr/T/tmpYm1Rwa

Частота создания контрольных точек

По умолчанию, Estimator сохраняет контрольные точки в model_dir согласно следующему расписанию:

  • Записывает контрольную точку каждые 10 минут (600 секунд).
  • Записывает контрольную точку когда метод train начинается (первая итерация) и завершается (последняя итерация).
  • Оставляет только 5 наиболее недавних контрольных точек в директории.

Можно изменить расписание по умолчанию, выполнив следующие шаги:

  1. Создать tf.estimator.RunConfig объект, который определяет желаемое расписание.
  2. При создании инстанса Estimator передать этот RunConfig объект в качестве Estimator config аргумента.

Например, следующий код изменяет расписание создания контрольных точек - записывать каждые 20 минут и оставлять 10 последних контрольных точек:

my_checkpointing_config = tf.estimator.RunConfig(
    # Сохраняем контрольные точки каждые 20 минут
    save_checkpoints_secs = 20*60,  
    # Оставляем 10 последних контрольных точек
    keep_checkpoint_max = 10,       
)

classifier = tf.estimator.DNNClassifier(
    feature_columns=my_feature_columns,
    hidden_units=[10, 10],
    n_classes=3,
    model_dir='models/iris',
    config=my_checkpointing_config)

Восстановление модели

При первом вызове Estimator train метода, TensorFlow сохраняет контрольную точку в model_dir. Каждый последующий вызов Estimator train, evaluate, или predict метода вызывает следующее:

  1. Estimator строит граф модели, выполняя model_fn().
  2. Estimator инициализирует веса новой модели из данных сохраненных в наиболее недавней контрольной точке.

Другими словами, как показано на следующем графике, если контрольная точка существует TensorFlow перестраивает модель каждый раз когда вызывается train(), evaluate(), или predict().

Последовательные вызовы train(), evaluate(), или predict()


Как избежать ошибок при восстановлении.

Восстановление состояния модели из контрольной точки работает только если модель и контрольная точка совместимы. Например, возьмем тренировку DNNClassifier Estimator, содержащего два скрытых слоя, каждый имеющий 10 узлов:

classifier = tf.estimator.DNNClassifier(
    feature_columns=feature_columns,
    hidden_units=[10, 10],
    n_classes=3,
    model_dir='models/iris')

classifier.train(
    input_fn=lambda:train_input_fn(train_x, train_y, batch_size=100),
        steps=200)

После тренировки (и, следовательно, после создания контрольных точек в models/iris), представим, что было изменено количество нейронов в каждом скрытом слое с 10 на 20, и затем попытаемся восстановить модель:

classifier2 = tf.estimator.DNNClassifier(
    feature_columns=my_feature_columns,
    hidden_units=[20, 20],  # Изменяем количество нейронов в модели.
    n_classes=3,
    model_dir='models/iris')

classifier.train(
    input_fn=lambda:train_input_fn(train_x, train_y, batch_size=100),
        steps=200)

Ввиду того, что состояние в контрольной точки несовместимо с моделью, описанной в classifier2, повторная тренировка проваливается со следующей ошибкой:

...
InvalidArgumentError (see above for traceback): tensor_name =
dnn/hiddenlayer_1/bias/t_0/Adagrad; shape in shape_and_slice spec [10]
does not match the shape stored in checkpoint: [20]

Для выполнения экспериментов, в которых происходит тренировка и сравнение незначительно отличающихся версий модели, сохраняйте копии кода, каждая из которых создает свою model_dir, например, это возможно созданием отдельных git веток для каждой версии. Такое разделение сохранит контрольные точки восстанавливаемыми.

Резюме

Контрольные точки предоставляют простой автоматизированный метод для сохранения и восстановления моделей, созданных с помощью Estimators.