您必须为占位符张量值输入" input_example_tensor'用dtype字符串和形状[1]

时间:2016-12-27 13:25:35

标签: tensorflow tensorflow-serving

我正在使用chatbot-retrieval项目开发一个服务客户端/服务器应用程序的tensorflow。

我的代码有两部分,即服务部分和客户部分。

以下是服务部分的代码段。

def get_features(context, utterance):

  context_len = 50
  utterance_len = 50

  features = {
    "context": context,
    "context_len": tf.constant(context_len, shape=[1,1], dtype=tf.int64),
    "utterance": utterance,
    "utterance_len": tf.constant(utterance_len, shape=[1,1], dtype=tf.int64),
  }

  return features


def my_input_fn(estimator, input_example_tensor ):
      feature_configs = {
              'context':tf.FixedLenFeature(shape=[50], dtype=tf.int64),
              'utterance':tf.FixedLenFeature(shape=[50], dtype=tf.int64)
              }
      tf_example = tf.parse_example(input_example_tensor, feature_configs)
      context = tf.identity(tf_example['context'], name='context')
      utterance = tf.identity(tf_example['utterance'], name='utterance')
      features = get_features(context, utterance)
      return features

def my_signature_fn(input_example_tensor, features, predictions):
  feature_configs = {
          'context':tf.FixedLenFeature(shape=[50], dtype=tf.int64),
          'utterance':tf.FixedLenFeature(shape=[50], dtype=tf.int64)
          }

  tf_example = tf.parse_example(input_example_tensor, feature_configs)
  tf_context = tf.identity(tf_example['context'], name='tf_context_utterance')
  tf_utterance = tf.identity(tf_example['utterance'], name='tf_utterance')

  default_graph_signature = exporter.regression_signature(
              input_tensor=input_example_tensor,
              output_tensor=tf.identity(predictions)
              )

  named_graph_signatures = {
              'inputs':exporter.generic_signature(
                  {
                      'context':tf_context,
                      'utterance':tf_utterance
                  }
               ),
              'outputs':exporter.generic_signature(
                  {
                      'scores':predictions
                  }
               )
              }

  return default_graph_signature, named_graph_signatures

def main():
      ##preliminary codes here##

      estimator.fit(input_fn=input_fn_train, steps=100, monitors=[eval_monitor])

      estimator.export(
              export_dir = FLAGS.export_dir,
              input_fn = my_input_fn,
              use_deprecated_input_fn = True,
              signature_fn = my_signature_fn,
              exports_to_keep = 1
              )

以下是客户端部分的代码段。

def tokenizer_fn(iterator):
   return (x.split(" ") for x in iterator)

    vp = tf.contrib.learn.preprocessing.VocabularyProcessor.restore(FLAGS.vocab_processor_file)

input_context = "biz banka kart farkli bir banka atmsinde para"
input_utterance = "farkli banka kart biz banka atmsinde para"

context_feature = np.array(list(vp.transform([input_context])))
utterance_feature = np.array(list(vp.transform([input_utterance])))

context_tensor = tf.contrib.util.make_tensor_proto(context_feature, shape=[1, context_feature.size])
utterance_tensor = tf.contrib.util.make_tensor_proto(context_feature, shape=[1, context_feature.size])

request.inputs['context'].CopyFrom(context_tensor)
request.inputs['utterance'].CopyFrom(utterance_tensor)

result_counter.throttle()
result_future = stub.Predict.future(request, 5.0)  # 5 seconds
result_future.add_done_callback(
_create_rpc_callback(label[0], result_counter))
   return result_counter.get_error_rate()

服务和客户端部分都构建没有错误。在运行服务应用程序然后运行客户端应用程序后,当rpc调用完成时,我得到以下奇怪的错误传播到客户端应用程序。

以下是rpc调用完成时出现的错误

AbortionError(code=StatusCode.INVALID_ARGUMENT, details="You must feed a value for placeholder tensor 'input_example_tensor' with dtype string and shape [1]
         [[Node: input_example_tensor = Placeholder[_output_shapes=[[1]], dtype=DT_STRING, shape=[1], _device="/job:localhost/replica:0/task:0/cpu:0"]()]]")

错误很奇怪,因为似乎无法从客户端应用程序中提供占位符。

如何为占位符提供数据" input_example_tensor'如果我通过tensorflow服务访问模型?

解答: (我在这里发布了我的答案,因为由于缺少StackOverflow徽章而无法将其作为答案发布。任何自愿提交它作为他/她对问题的答案的人都非常欢迎。我会批准它为答案。)

我可以通过在estimator.export函数中使用选项use_deprecated_input_fn = False来解决问题,并相应地更改输入签名。

下面是没有问题的最终代码。

def get_features(input_example_tensor, context, utterance):
  context_len = 50
  utterance_len = 50
  features = {
    "my_input_example_tensor": input_example_tensor,
    "context": context,
    "context_len": tf.constant(context_len, shape=[1,1], dtype=tf.int64),
    "utterance": utterance,
    "utterance_len": tf.constant(utterance_len, shape=[1,1], dtype=tf.int64),
  }

  return features

def my_input_fn():
  input_example_tensor = tf.placeholder(tf.string, name='tf_example_placeholder')

  feature_configs = {
          'context':tf.FixedLenFeature(shape=[50], dtype=tf.int64),
          'utterance':tf.FixedLenFeature(shape=[50], dtype=tf.int64)
          }
  tf_example = tf.parse_example(input_example_tensor, feature_configs)
  context = tf.identity(tf_example['context'], name='context')
  utterance = tf.identity(tf_example['utterance'], name='utterance')
  features = get_features(input_example_tensor, context, utterance)

  return features, None

def my_signature_fn(input_example_tensor, features, predictions):   
  default_graph_signature = exporter.regression_signature(
              input_tensor=input_example_tensor,
              output_tensor=predictions
              )

  named_graph_signatures = {
              'inputs':exporter.generic_signature(
                  {
                      'context':features['context'],
                      'utterance':features['utterance']
                  }
               ),
              'outputs':exporter.generic_signature(
                  {
                      'scores':predictions
                  }
               )
              }

  return default_graph_signature, named_graph_signatures

def main():
  ##preliminary codes here##

  estimator.fit(input_fn=input_fn_train, steps=100, monitors=[eval_monitor])

  estimator._targets_info = tf.contrib.learn.estimators.tensor_signature.TensorSignature(tf.constant(0, shape=[1,1]))

  estimator.export(
          export_dir = FLAGS.export_dir,
          input_fn = my_input_fn,
          input_feature_key ="my_input_example_tensor",
          use_deprecated_input_fn = False,
          signature_fn = my_signature_fn,
          exports_to_keep = 1
          )

1 个答案:

答案 0 :(得分:1)

OP自我解决但无法自我回答,所以这里有他们的回答:

通过在use_deprecated_input_fn = False函数中使用选项estimator.export并相应更改输入签名来解决问题:

def my_signature_fn(input_example_tensor, features, predictions):   
  default_graph_signature = exporter.regression_signature(
      input_tensor=input_example_tensor,
      output_tensor=predictions
      )

  named_graph_signatures = {
      'inputs':exporter.generic_signature(
          {
          'context':features['context'],
          'utterance':features['utterance']
          }
       ),
      'outputs':exporter.generic_signature(
          {
          'scores':predictions
          }
       )
      }

  return default_graph_signature, named_graph_signatures

def main():
  ##preliminary codes here##

  estimator.fit(input_fn=input_fn_train, steps=100, monitors=[eval_monitor])

  estimator._targets_info = tf.contrib.learn.estimators.tensor_signature.TensorSignature(tf.constant(0, shape=[1,1]))

  estimator.export(
      export_dir = FLAGS.export_dir,
      input_fn = my_input_fn,
      input_feature_key ="my_input_example_tensor",
      use_deprecated_input_fn = False,
      signature_fn = my_signature_fn,
      exports_to_keep = 1
      )