TensorFlow ExportOutputs, PredictOuput и определение signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY - PullRequest
0 голосов
/ 21 ноября 2018

Контекст

У меня есть колаб с очень простой демонстрацией Estimator с целью изучения / понимания Estimator API с целью создания соглашения для модели «включай и работай» с полезными наворотами сделки (например, ранняя остановка, если набор проверки перестает улучшаться, экспорт модели и т. Д.).

Каждый из трех режимов Estimator (TRAIN, EVAL и PREDICT) возвращает EstimatorSpec.

В соответствии с docs :

__new__(
    cls,
    mode,
    predictions=None,          # required by PREDICT
    loss=None,                 # required by TRAIN and EVAL
    train_op=None,             # required by TRAIN
    eval_metric_ops=None,
    export_outputs=None,
    training_chief_hooks=None,
    training_hooks=None,
    scaffold=None,
    evaluation_hooks=None,
    prediction_hooks=None.     
)

Из этих именованных аргументов я хотел бы обратить внимание на predictions и export_outputs, которые описаны в docs как:

  • predictions: прогнозирование Тензор или диктат Тензор.
  • export_outputs: Описывает выходные сигнатурыбыть экспортированным в SavedModel и использоваться во время подачи.DICT {name: output} где:
    • name: произвольное имя для этого вывода.
    • output: объект ExportOutput, такой как ClassificationOutput, RegressionOutput или PredictOutput.Для одноголовых моделей необходимо указать только одну запись в этом словаре.Многоголовые модели должны указывать одну запись для каждой головы, одна из которых должна быть названа с использованием signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY.Если запись не указана, будет создано отображение по умолчанию PredictOutput для прогнозов.

Таким образом, должно быть понятно, почему я привожу export_outputs;а именно, как наиболее вероятно, хотелось бы использовать модель, которую они обучили в будущем (загрузив ее из SavedModel).

Чтобы сделать этот вопрос немного более доступным / добавить некоторую ясность:

  • "одноголовые" модели являются наиболее распространенной моделью, с которой встречается input_fn features преобразуются в единичные (пакетные) output

  • "многоголовые" модели - это модели, в которых имеется более одного выхода

Например, input_fn этой многоголовой модели (в соответствии с Estimator API) возвращает кортеж (features, labels), т. Е. Эта модель имеет две головки.

def input_fn():
  features = ...
  labels1 = ...
  labels2 = ...
  return features, {'head1': labels1, 'head2': labels2}

Как каждый определяет signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY является ядром этого вопроса.А именно, как это указать?(например, должен ли это быть dict {signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: head})

Верно, поэтому в colab вы видите, что export_outputs нашей модели на самом деле определяется многоголовым способом (хотя это не должно't be):

С estimator functions > model_fn colab :

def model_fn(...):

    # ...

    # send the features through the graph
    MODEL = build_fn(MODEL)

    # prediction
    MODEL['predictions'] = {'labels': MODEL['net_logits']} # <--- net_logits added in the build_fn

    MODEL['export_outputs'] = {
        k: tf.estimator.export.PredictOutput(v) for k, v in MODEL['predictions'].items()
    }

    # ...

в данном конкретном случае, если мы расширим понимание словаря, у нас будет функционалэквивалент:

MODEL['export_outputs'] = {
    'labels': tf.estimator.export.PredictOutput(MODEL['net_logits'])
}

Это работает в этом случае, так как наш словарь имеет один ключ и, следовательно, один PredictOutput, где в colab наша model_fnимеет только одну головку и будет более правильно отформатирован как:

MODEL['export_outputs'] = {
    'predictions': tf.estimator.export.PredictOutput(MODEL['predictions'])
}

, как указано в PredictOutput:

__init__(outputs)

где

  • outputs: Тензор или строка в Tensor, представляющая предсказания.

Вопрос

Таким образом, мой вопрос таков:

  1. , если PredictOutput может быть словарем, когда / почему нужно несколько PredictOutput s в качестве export_outputs для EstimatorSpec

  2. Если у вас есть многоголовая модель (скажем, с несколькими PredictOutput с), как на самом деле указать signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY

  3. в чем смысл predictions в EstimatorSpec, когда это также «требуется» (для тех, кто хочет использовать SavedModel s) в export_outputs?

1 Ответ

0 голосов
/ 18 мая 2019

Спасибо за ваш подробный вопрос;Вы явно глубоко копали здесь.

  1. Существуют также классы для RegressionOutput и ClassificationOutput, которые не могут быть словарями.Использование dict export_outputs позволяет обобщать эти случаи использования.

  2. Голова, которую вы хотите обслуживать по умолчанию из сохраненной модели, должна взять ключ подписи по умолчанию.Например:

export_outputs = {
  signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY:
    PredictOutput(outputs={'some_output_1': output_1}),
  'head-2': PredictOutput(outputs={'some_output_2': output_2}),
  'head-3': PredictOutput(outputs={'some_output_3': output_3})
}
Причина 1. Многие люди используют стандартное значение export_outputs (которое, в свою очередь, является значением прогнозов) или не экспортируют в сохраненную модель.Причина 2: История.Сначала появились прогнозы, и со временем добавлялось все больше и больше функций.Эти функции требовали гибкости и дополнительной информации и поэтому были независимо упакованы в EstimatorSpec.
...