Как создать Tensorflow serve_input_receiver_fn с несколькими функциями?

В руководстве TF по сохранению моделей есть параграф по serv_input_receiver_fn, в котором рассказывается о реализации функций для предварительной обработки. логика. Я пытаюсь нормализовать входные данные для DNNRegressor. Их код функции выглядит так:

feature_spec = {'foo': tf.FixedLenFeature(...),
                'bar': tf.VarLenFeature(...)}

def serving_input_receiver_fn():
  """An input receiver that expects a serialized tf.Example."""
  serialized_tf_example = tf.placeholder(dtype=tf.string,
                                         shape=[default_batch_size],
                                         name='input_example_tensor')
  receiver_tensors = {'examples': serialized_tf_example}
  features = tf.parse_example(serialized_tf_example, feature_spec)
  return tf.estimator.export.ServingInputReceiver(features, receiver_tensors)

Мой код выглядит так:

feat_cols = [
    tf.feature_column.numeric_column(key="FEATURE1"),
    tf.feature_column.numeric_column(key="FEATURE2")
]

def serving_input_receiver_fn():
    feature_spec = tf.feature_column.make_parse_example_spec(feat_cols)

    default_batch_size = 1

    serialized_tf_example = tf.placeholder(dtype=tf.string, shape=[default_batch_size], name='tf_example')

    receiver_tensors = { 'examples': serialized_tf_example}

    features = tf.parse_example(serialized_tf_example, feature_spec)

    fn_norm1 = lamba FEATURE1: normalize_input_data('FEATURE1', FEATURE1)
    fn_norm2 = lamba FEATURE2: normalize_input_data('FEATURE2', FEATURE2)
    features['FEATURE1'] = tf.map_fn(fn_norm1, features['FEATURE1'], dtype=tf.float32)
    features['FEATURE2'] = tf.map_fn(fn_norm2, features['FEATURE2'], dtype=tf.float32)

    return tf.estimator.export.ServingInputReceiver(features, receiver_tensors)

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

Я создал пример, используя данные keras MPG. Он находится здесь:


person Geoff Craig    schedule 18.01.2019    source источник
comment
Где определяется receiver_tensors?   -  person Siyuan Ren    schedule 18.01.2019
comment
Извините, забыл эту строчку. Receiver_tensors = {'examples': serialized_tf_example} Я обновлю сообщение   -  person Geoff Craig    schedule 18.01.2019
comment
В какой-то момент у меня был receiver_tensors как диктатор с определенными функциями. В коде не было ошибок, но когда я перешел к его обслуживанию, возникла ошибка, в которой говорилось, что мне нужно предоставить значение для tf_example.   -  person Geoff Craig    schedule 18.01.2019
comment
Вы все еще не предоставили много контекста. Опубликуйте код MVCE.   -  person Siyuan Ren    schedule 19.01.2019
comment
@SiyuanRen Я создал пример, основанный на коде keras MPG, но он имеет ту же проблему. Мне нужно знать, как создать функциональный serve_input_receiver_fn для нормализации данных при использовании веб-API TF Serving.   -  person Geoff Craig    schedule 22.01.2019
comment
Что вы имеете в виду, что сохраненная модель не имеет ни одной из функций? Вы хотите, скажем, питать сеть не tf.Example прото, а отдельными «Цилиндрами», «Смещением», ... тензорами?   -  person Siyuan Ren    schedule 23.01.2019
comment
Я хочу использовать веб-API Tensorflow для прогнозов. Для других моделей я просто передаю документ JSON следующим образом: { "signature_name": "predict", "instances":[{ "Cylinders": [4.0], "Displacement": [140.0], "Horsepower": [86.0], "Weight": [2790.0], "Acceleration": [15.6], "Model_Year": [82.0], "USA": [1.0], "Europe": [0.0], "Japan": [0.0] }] }   -  person Geoff Craig    schedule 23.01.2019
comment
Однако я получаю сообщение об ошибке { "error": "Failed to process element: 0 key: Cylinders of \'instances\' list. Error: Invalid argument: JSON object: does not have named input: Cylinders" } Я предполагаю, что я либо неправильно создаю функцию ввода для обслуживания, либо мне нужно изменить полезную нагрузку JSON. Я просто не знаю какой. Было бы действительно полезно, если бы был бесконечный пример, я думаю, что любой, кто обслуживает регрессор, должен будет это сделать.   -  person Geoff Craig    schedule 23.01.2019


Ответы (1)


features в ServingInputReceiver передается непосредственно вашей модельной функции. Вам нужно receive_tensors или receive_tensor_alternatives, то есть второй и третий аргумент конструктора ServingInputReceiver.

Например, вы можете сделать это

serialized_tf_example = tf.placeholder(dtype=tf.string, shape=[default_batch_size], name='tf_example')

receiver_tensors = { 'examples': serialized_tf_example}

raw_features = tf.parse_example(serialized_tf_example, feature_spec)

fn_norm1 = lamba FEATURE1: normalize_input_data('FEATURE1', FEATURE1)
fn_norm2 = lamba FEATURE2: normalize_input_data('FEATURE2', FEATURE2)
features['FEATURE1'] = tf.map_fn(fn_norm1, raw_features['FEATURE1'], dtype=tf.float32)
features['FEATURE2'] = tf.map_fn(fn_norm2, raw_features['FEATURE2'], dtype=tf.float32)
return tf.estimator.export.ServingInputReceiver(
      features=features,
      receiver_tensors=receiver_tensors,
      receiver_tensors_alternatives={'SOME_KEY': raw_features})

Если вам никогда не нужно питать сеть с помощью Example proto, вы можете полностью его пропустить.

raw_features = {'FEATURE1': tf.placeholder(...), 'FEATURE2': tf.placeholder(...)}
features = preprepocess(raw_features)
return tf.estimator.export.ServingInputReceiver(features, {'SOME_OTHER_KEY': raw_features})
person Siyuan Ren    schedule 26.01.2019