Nano Hash - криптовалюты, майнинг, программирование

Как загрузить модель с tf.saved_model и вызвать функцию прогнозирования [TENSORFLOW 2.0 API]

Я очень новичок в tensorflow и особенно в 2.0, так как примеров этого API недостаточно, но он кажется намного удобнее, чем 1.x. Пока мне удалось обучить линейную модель с помощью api tf.estimator, а затем удалось сохранить это с помощью tf.estimator.exporter.

После этого я хотел загрузить эту модель с помощью api tf.saved_model, и я думаю, что мне это удалось, но у меня есть некоторые сомнения в моей процедуре, поэтому вот беглый взгляд на мой код:

Итак, у меня есть массив функций, созданный с использованием tf.feature_column api, и он выглядит так:

feature_columns = 
[NumericColumn(key='geoaccuracy', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=None),
 NumericColumn(key='longitude', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=None),
 NumericColumn(key='latitude', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=None),
 NumericColumn(key='bidfloor', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=None),
 VocabularyListCategoricalColumn(key='adid', vocabulary_list=('115', '124', '139', '122', '121', '146', '113', '103', '123', '104', '147', '114', '149', '148'), dtype=tf.string, default_value=-1, num_oov_buckets=0),
 VocabularyListCategoricalColumn(key='campaignid', vocabulary_list=('36', '31', '33', '28'), dtype=tf.string, default_value=-1, num_oov_buckets=0),
 VocabularyListCategoricalColumn(key='exchangeid', vocabulary_list=('1241', '823', '1240', '1238'), dtype=tf.string, default_value=-1, num_oov_buckets=0),
...]

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

linear_est = tf.estimator.LinearClassifier(feature_columns=feature_columns)

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

serving_input_parse = tf.feature_column.make_parse_example_spec(feature_columns=feature_columns)

""" view of the variable : serving_input_parse = 
 {'adid': VarLenFeature(dtype=tf.string),
 'at': VarLenFeature(dtype=tf.string),
 'basegenres': VarLenFeature(dtype=tf.string),
 'bestkw': VarLenFeature(dtype=tf.string),
 'besttopic': VarLenFeature(dtype=tf.string),
 'bidfloor': FixedLenFeature(shape=(1,), dtype=tf.float32, default_value=None),
 'browserid': VarLenFeature(dtype=tf.string),
 'browserlanguage': VarLenFeature(dtype=tf.string)
 ...} """

# exporting the model :
linear_est.export_saved_model(export_dir_base='./saved',
 serving_input_receiver_fn=tf.estimator.export.build_parsing_serving_input_receiver_fn(serving_input_receiver_fn),
 as_text=True)

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

loaded = tf.saved_model.load('saved/1573144361/')

Еще одна вещь, я попытался взглянуть на подпись модели, но я действительно не могу понять, что происходит с моими входными фигурами.

MetaGraphDef with tag-set: 'serve' contains the following SignatureDefs:

signature_def['classification']:
  The given SavedModel SignatureDef contains the following input(s):
    inputs['inputs'] tensor_info:
        dtype: DT_STRING
        shape: (-1)
        name: input_example_tensor:0
  The given SavedModel SignatureDef contains the following output(s):
    outputs['classes'] tensor_info:
        dtype: DT_STRING
        shape: (-1, 2)
        name: head/Tile:0
    outputs['scores'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, 2)
        name: head/predictions/probabilities:0
  Method name is: tensorflow/serving/classify

signature_def['predict']:
  The given SavedModel SignatureDef contains the following input(s):
    inputs['examples'] tensor_info:
        dtype: DT_STRING
        shape: (-1)
        name: input_example_tensor:0
  The given SavedModel SignatureDef contains the following output(s):
    outputs['all_class_ids'] tensor_info:
        dtype: DT_INT32
        shape: (-1, 2)
        name: head/predictions/Tile:0
    outputs['all_classes'] tensor_info:
        dtype: DT_STRING
        shape: (-1, 2)
        name: head/predictions/Tile_1:0
    outputs['class_ids'] tensor_info:
        dtype: DT_INT64
        shape: (-1, 1)
        name: head/predictions/ExpandDims:0
    outputs['classes'] tensor_info:
        dtype: DT_STRING
        shape: (-1, 1)
        name: head/predictions/str_classes:0
    outputs['logistic'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, 1)
        name: head/predictions/logistic:0
    outputs['logits'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, 1)
        name: linear/linear_model/linear/linear_model/linear/linear_model/weighted_sum:0
    outputs['probabilities'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, 2)
        name: head/predictions/probabilities:0
  Method name is: tensorflow/serving/predict

signature_def['regression']:
  The given SavedModel SignatureDef contains the following input(s):
    inputs['inputs'] tensor_info:
        dtype: DT_STRING
        shape: (-1)
        name: input_example_tensor:0
  The given SavedModel SignatureDef contains the following output(s):
    outputs['outputs'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, 1)
        name: head/predictions/logistic:0
  Method name is: tensorflow/serving/regress

signature_def['serving_default']:
  The given SavedModel SignatureDef contains the following input(s):
    inputs['inputs'] tensor_info:
        dtype: DT_STRING
        shape: (-1)
        name: input_example_tensor:0
  The given SavedModel SignatureDef contains the following output(s):
    outputs['classes'] tensor_info:
        dtype: DT_STRING
        shape: (-1, 2)
        name: head/Tile:0
    outputs['scores'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, 2)
        name: head/predictions/probabilities:0
  Method name is: tensorflow/serving/classify


Ответы:


1

saved_model.load(...) документация демонстрирует следующий базовый механизм:

imported = tf.saved_model.load(path)
f = imported.signatures["serving_default"]
print(f(x=tf.constant([[1.]])))

Я сам еще новичок в этом, но serving_default, похоже, является подписью по умолчанию при использовании saved_model.save(...).

(Насколько я понимаю, saved_model.save(...) не сохраняет модель, а сохраняет график. Чтобы интерпретировать график, вам необходимо явно сохранить «сигнатуры» операций определения на графе. Если вы не делаете этого явно, то " serve_default "будет вашей единственной подписью.)

Ниже я представил реализацию. Стоит отметить несколько деталей:

  1. Входные должны быть тензором; поэтому мне нужно было выполнить преобразование вручную.
  2. На выходе получается словарь. В документации он описывается как «отслеживаемый объект с отображением атрибута подписи из ключей подписи в функции».

В моем случае ключом к словарю был относительно произвольный «density_83». Это казалось немного ... конкретным. Поэтому я обобщил решение игнорировать ключ с помощью итератора:

import tensorflow as tf
input_data = tf.constant(input_data, dtype=tf.float32)
prediction_tensors = signature_collection.signatures["serving_default"](input_data)
for _, values in prediction_tensors.items():
    predictions = values.numpy()[0]
    return predictions
raise Exception("Expected a response from predict(...).")
11.02.2020
  • спасибо, сэр, это мне очень помогло 20.05.2021
  • С большим удовольствием, @ThinkTeamwork. Это сообщество очень помогло мне. Я счастлив немного отплатить. 21.05.2021

  • 2

    Похоже, вы использовали инструмент командной строки saved_model_cli для последнего раздела вывода. Отсюда у вас есть функция «прогнозирования», которая показывает типы входных данных, столбцы и т. Д. Когда я делаю это, я вижу все свои входные столбцы. В вашем случае он просто показывает один ввод, который представляет собой строку с именем examples. Это не выглядит правильным.

    Вот выдержка из вывода $ saved_model_cli show --dir /somedir/export/exporter/123456789 --all. На выходе точки показывают удаленные строки, так как они выглядят одинаково.

    signature_def['predict']:
      The given SavedModel SignatureDef contains the following input(s):
        inputs['feature_num_1'] tensor_info:
            dtype: DT_FLOAT
            shape: (-1)
            name: Placeholder_29:0
    ...
    ...
     The given SavedModel SignatureDef contains the following output(s):
        outputs['all_class_ids'] tensor_info:
            dtype: DT_INT32
            shape: (-1, 2)
            name: dnn/head/predictions/Tile:0
        outputs['all_classes'] tensor_info:
            dtype: DT_STRING
            shape: (-1, 2)
            name: dnn/head/predictions/Tile_1:0
    ...
    ...
      Method name is: tensorflow/serving/predict
    
    07.11.2019
  • Спасибо за ответ, это очень интересно, не могли бы вы поделиться кодом того, как вы приступите к созданию этой сохраненной модели? вы использовали tf.estimator api для своей модели? потому что я пробовал это с tf.keras, и он действительно дает хорошую подпись, но я борюсь с tf.estimator ... 08.11.2019
  • Я использовал оценщик. Я думаю, что, возможно, вы используете в качестве входных данных одну строку. Так что, возможно, я ошибаюсь. Я тоже учусь, так что имейте это в виду. Я не понимаю, почему у вас шесть или более функций, но ваша функция прогноза работает как одна функция, которая является строкой. У вашей функции servebinput один или несколько параметров? 08.11.2019
  • Что ж, у моего ввода для обслуживания есть несколько параметров, и на самом деле их больше шести, я больше ожидал чего-то вроде вас. 09.11.2019
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

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

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

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

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..