代码之家  ›  专栏  ›  技术社区  ›  Patrick Hund

如何对保存的估计器模型执行简单的cli查询?

  •  7
  • Patrick Hund  · 技术社区  · 6 年前

    我成功地训练了一个dnnclassifier来分类文本(来自在线讨论板的帖子)。我已经保存了模型,现在想使用tensorflow cli对文本进行分类。

    当我奔跑 saved_model_cli show 对于我保存的模型,我得到以下输出:

    saved_model_cli show --dir /my/model --tag_set serve --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['class_ids'] tensor_info:
          dtype: DT_INT64
          shape: (-1, 1)
          name: dnn/head/predictions/ExpandDims:0
      outputs['classes'] tensor_info:
          dtype: DT_STRING
          shape: (-1, 1)
          name: dnn/head/predictions/str_classes:0
      outputs['logistic'] tensor_info:
          dtype: DT_FLOAT
          shape: (-1, 1)
          name: dnn/head/predictions/logistic:0
      outputs['logits'] tensor_info:
          dtype: DT_FLOAT
          shape: (-1, 1)
          name: dnn/logits/BiasAdd:0
      outputs['probabilities'] tensor_info:
          dtype: DT_FLOAT
          shape: (-1, 2)
          name: dnn/head/predictions/probabilities:0
    Method name is: tensorflow/serving/predict
    

    我无法找出正确的参数 saved_model_cli run 得到一个预测。

    我尝试了几种方法,例如:

    saved_model_cli run --dir /my/model --tag_set serve --signature_def predict --input_exprs='examples=["klassifiziere mich bitte"]'
    

    这给了我这个错误信息:

    InvalidArgumentError (see above for traceback): Could not parse example input, value: 'klassifiziere mich bitte'
     [[Node: ParseExample/ParseExample = ParseExample[Ndense=1, Nsparse=0, Tdense=[DT_STRING], dense_shapes=[[1]], sparse_types=[], _device="/job:localhost/replica:0/task:0/device:CPU:0"](_arg_input_example_tensor_0_0, ParseExample/ParseExample/names, ParseExample/ParseExample/dense_keys_0, ParseExample/ParseExample/names)]]
    

    将输入字符串传递给cli以获取分类的正确方法是什么?

    您可以在github上找到我的项目代码,包括培训数据: https://github.com/pahund/beitragstuev

    我正在这样建立和保存我的模型(简化, see GitHub for original code )以下内容:

    embedded_text_feature_column = hub.text_embedding_column(
        key="sentence",
        module_spec="https://tfhub.dev/google/nnlm-de-dim128/1")
    feature_columns = [embedded_text_feature_column]
    estimator = tf.estimator.DNNClassifier(
        hidden_units=[500, 100],
        feature_columns=feature_columns,
        n_classes=2,
        optimizer=tf.train.AdagradOptimizer(learning_rate=0.003))
    feature_spec = tf.feature_column.make_parse_example_spec(feature_columns)
    serving_input_receiver_fn = tf.estimator.export.build_parsing_serving_input_receiver_fn(feature_spec)
    estimator.export_savedmodel(export_dir_base="/my/dir/base", serving_input_receiver_fn=serving_input_receiver_fn)
    
    2 回复  |  直到 6 年前
        1
  •  6
  •   0xsx    6 年前

    这个 ServingInputReceiver 您为模型导出创建的是告诉保存的模型期望序列化 tf.Example 原型而不是你想要分类的原始字符串。

    the Save and Restore documentation :

    一个典型的模式是推理请求以序列化tf.examples的形式到达,因此serving_input_receiver_fn()创建一个字符串占位符来接收它们。然后,serving_input_receiver_fn()还负责通过向图中添加tf.parse_example op来解析tf.examples。

    tf.estimator.export.build_parsing_serving_input_receiver_fn实用函数为常见情况提供输入接收器。

    所以导出的模型包含 tf.parse_example 希望接收序列化的操作 tf.示例 满足您传递给的特性规范的protos build_parsing_serving_input_receiver_fn ,也就是说,在你的情况下 序列化示例 有着 sentence 特色。要使用模型进行预测,必须提供那些序列化的原型。

    幸运的是,tensorflow使得构建这些非常容易。这里有一个可能的函数返回一个表达式 examples 输入一批字符串的密钥,然后可以将其传递给cli:

    import tensorflow as tf
    
    def serialize_example_string(strings):
    
      serialized_examples = []
      for s in strings:
        try:
          value = [bytes(s, "utf-8")]
        except TypeError:  # python 2
          value = [bytes(s)]
    
        example = tf.train.Example(
                    features=tf.train.Features(
                      feature={
                        "sentence": tf.train.Feature(bytes_list=tf.train.BytesList(value=value))
                      }
                    )
                  )
        serialized_examples.append(example.SerializeToString())
    
      return "examples=" + repr(serialized_examples).replace("'", "\"")
    

    因此,使用从示例中提取的一些字符串:

    strings = ["klassifiziere mich bitte",
               "Das Paket „S Line Competition“ umfasst unter anderem optische Details, eine neue Farbe (Turboblau), 19-Zöller und LED-Lampen.",
               "(pro Stimme geht 1 Euro Spende von Pfuscher ans Forum) ah du sack, also so gehts ja net :D:D:D"]
    
    print (serialize_example_string(strings))
    

    cli命令将是:

    saved_model_cli run --dir /path/to/model --tag_set serve --signature_def predict --input_exprs='examples=[b"\n*\n(\n\x08sentence\x12\x1c\n\x1a\n\x18klassifiziere mich bitte", b"\n\x98\x01\n\x95\x01\n\x08sentence\x12\x88\x01\n\x85\x01\n\x82\x01Das Paket \xe2\x80\x9eS Line Competition\xe2\x80\x9c umfasst unter anderem optische Details, eine neue Farbe (Turboblau), 19-Z\xc3\xb6ller und LED-Lampen.", b"\np\nn\n\x08sentence\x12b\n`\n^(pro Stimme geht 1 Euro Spende von Pfuscher ans Forum) ah du sack, also so gehts ja net :D:D:D"]'
    

    这会给你想要的结果:

    Result for output key class_ids:
    [[0]
     [1]
     [0]]
    Result for output key classes:
    [[b'0']
     [b'1']
     [b'0']]
    Result for output key logistic:
    [[0.05852016]
     [0.88453305]
     [0.04373989]]
    Result for output key logits:
    [[-2.7780817]
     [ 2.0360758]
     [-3.0847695]]
    Result for output key probabilities:
    [[0.94147986 0.05852016]
     [0.11546692 0.88453305]
     [0.9562601  0.04373989]]
    
        2
  •  2
  •   Happy Gene    6 年前

    或者,saved_model_cli提供了另一个选项 --input_examples ,而不是 --input_exprs ,以便您可以直接在命令行中传递tf.examples数据,而无需手动序列化。

    例如:

    --input_examples 'examples=[{"sentence":["this is a sentence"]}]'

    https://www.tensorflow.org/guide/saved_model#--input_examples 详细情况。