Как отслеживать тренировочные сессии?

Я пытаюсь понять разницу между использованием tf.Session и tf.train.MonitoredTrainingSession, и где я могу предпочесть один за другим. Похоже, что когда я использую последнее, я могу избежать многих "обязанностей", таких как инициализация переменных, запуск бегущих очередей или настройка файловых писателей для сводных операций. С другой стороны, с контролируемой обучающей сессией я не могу указать граф вычислений, который я хочу использовать явно. Все это кажется мне довольно загадочным. Есть ли какая-то основополагающая философия в отношении того, как эти классы были созданы, которые я не понимаю?

Ответ 1

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

tf.Session - это объект низкого уровня в API-интерфейсе python TensorFlow, как вы сказали, tf.train.MonitoredTrainingSession поставляется с множеством удобных функций, особенно полезными в большинстве распространенных случаев.

Прежде чем описывать некоторые преимущества tf.train.MonitoredTrainingSession, позвольте мне ответить на вопрос о графике, используемом сеансом. Вы можете указать tf.Graph, используемый MonitoredTrainingSession, с помощью диспетчера контекстов with your_graph.as_default():

from __future__ import print_function
import tensorflow as tf

def example():
    g1 = tf.Graph()
    with g1.as_default():
        # Define operations and tensors in `g`.
        c1 = tf.constant(42)
        assert c1.graph is g1

    g2 = tf.Graph()
    with g2.as_default():
        # Define operations and tensors in `g`.
        c2 = tf.constant(3.14)
        assert c2.graph is g2

    # MonitoredTrainingSession example
    with g1.as_default():
        with tf.train.MonitoredTrainingSession() as sess:
            print(c1.eval(session=sess))
            # Next line raises
            # ValueError: Cannot use the given session to evaluate tensor:
            # the tensor graph is different from the session graph.
            try:
                print(c2.eval(session=sess))
            except ValueError as e:
                print(e)

    # Session example
    with tf.Session(graph=g2) as sess:
        print(c2.eval(session=sess))
        # Next line raises
        # ValueError: Cannot use the given session to evaluate tensor:
        # the tensor graph is different from the session graph.
        try:
            print(c1.eval(session=sess))
        except ValueError as e:
            print(e)

if __name__ == '__main__':
    example()

Итак, как вы сказали, преимущества использования MonitoredTrainingSession заключаются в том, что этот объект заботится о

  • инициализирующие переменные,
  • запуск очереди, а также
  • настройка файлов,

но также имеет преимущество в том, что ваш код легко распределяется, так как он также работает по-разному в зависимости от того, задан ли хост процесс как мастер или нет.

Например, вы можете запустить что-то вроде:

def run_my_model(train_op, session_args):
    with tf.train.MonitoredTrainingSession(**session_args) as sess:
        sess.run(train_op)

который вы вызываете нераспространенным способом:

run_my_model(train_op, {})`

или распределенным способом (см. распределенный документ для получения дополнительной информации о входах):

run_my_model(train_op, {"master": server.target,
                        "is_chief": (FLAGS.task_index == 0)})

С другой стороны, преимущество использования raw tf.Session заключается в том, что у вас нет дополнительных преимуществ tf.train.MonitoredTrainingSession, которые могут быть полезны, если вы не планируете их использовать, или если вы хотите получить больше контроля (например, о том, как запускаются очереди).

EDIT (согласно комментарию): Для инициализации op вам нужно будет сделать что-то вроде (см. официальный документ:

# Define your graph and your ops
init_op = tf.global_variables_initializer()
with tf.Session() as sess:
    sess.run(init_p)
    sess.run(your_graph_ops,...)

Для QueueRunner я отсылаю вас к официальному документу где вы найдете более полные примеры.

EDIT2:

Основная концепция, чтобы понять, как работает tf.train.MonitoredTrainingSession - класс _WrappedSession:

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

tf.train.MonitoredTrainingSession работает (с версия 1.1) следующим образом:

  • Сначала он проверяет, является ли это главным или рабочим (см. распределенный документ для лексического вопроса).
  • Он начинает предлагаемые крючки (например, StopAtStepHook будет просто извлекать тензор global_step на этом этапе.
  • Он создает сеанс, который представляет собой сеанс Chief (или Worker), завернутый в _HookedSession, завернутый в _CoordinatedSession, завернутый в _RecoverableSession.
    Серии Chief/Worker отвечают за запуск инициализирующих операционных систем, предоставляемых Scaffold.
      scaffold: A `Scaffold` used for gathering or building supportive ops. If
    not specified a default one is created. It used to finalize the graph.
    
  • Сеанс Chief также выполняет все части контрольной точки: например, восстановление из контрольных точек с помощью Saver из Scaffold.
  • _HookedSession в основном там, чтобы украсить метод run: он вызывает методы _call_hook_before_run и after_run, когда это необходимо.
  • При создании _CoordinatedSession строит a Coordinator, который запускает очередь очередей и будет отвечать за их закрытие.
  • _RecoverableSession обеспечит повторную попытку в случае tf.errors.AbortedError.

В заключение, tf.train.MonitoredTrainingSession избегает большого количества кода плиты котла, будучи легко расширяемым механизмом крючков.