使用实例键进行培训和预测

dob*_*002 12 tensorflow google-cloud-ml-engine

我能够训练我的模型并使用ML Engine进行预测,但我的结果不包括任何识别信息.这在一次提交一行进行预测时工作正常但在提交多行时我无法将预测连接回原始输入数据.该GCP文件讨论了使用实例密钥,但我无法找到训练和使用实例密钥预测任何示例代码.采用GCP人口普查示例如何更新输入函数以通过图表传递唯一ID并在训练期间忽略它并返回带预测的唯一ID?或者,如果有人知道已经使用了也有帮助的键的另一个例子.

来自Census Estimator Sample

def serving_input_fn():
    feature_placeholders = {
      column.name: tf.placeholder(column.dtype, [None])
      for column in INPUT_COLUMNS
    }

    features = {
      key: tf.expand_dims(tensor, -1)
      for key, tensor in feature_placeholders.items()
    }

    return input_fn_utils.InputFnOps(
      features,
      None,
      feature_placeholders
    )


def generate_input_fn(filenames,
                  num_epochs=None,
                  shuffle=True,
                  skip_header_lines=0,
                  batch_size=40):

    def _input_fn():
        files = tf.concat([
          tf.train.match_filenames_once(filename)
          for filename in filenames
        ], axis=0)

        filename_queue = tf.train.string_input_producer(
          files, num_epochs=num_epochs, shuffle=shuffle)
        reader = tf.TextLineReader(skip_header_lines=skip_header_lines)

        _, rows = reader.read_up_to(filename_queue, num_records=batch_size)

        row_columns = tf.expand_dims(rows, -1)
        columns = tf.decode_csv(row_columns, record_defaults=CSV_COLUMN_DEFAULTS)
        features = dict(zip(CSV_COLUMNS, columns))

        # Remove unused columns
        for col in UNUSED_COLUMNS:
          features.pop(col)

        if shuffle:
           features = tf.train.shuffle_batch(
             features,
             batch_size,
             capacity=batch_size * 10,
             min_after_dequeue=batch_size*2 + 1,
             num_threads=multiprocessing.cpu_count(),
             enqueue_many=True,
             allow_smaller_final_batch=True
           )
        label_tensor = parse_label_column(features.pop(LABEL_COLUMN))
        return features, label_tensor

    return _input_fn
Run Code Online (Sandbox Code Playgroud)

更新: 我能够使用下面这个答案的建议代码我只需稍微改变它来更新model_fn_ops中的输出备选,而不仅仅是预测字典.但是,这仅在我的服务输入函数被编码为类似于此的 json输入时才有效.我的服务输入功能以前是在人口普查核心样本中的CSV服务输入功能之后建模的.

我认为我的问题来自build_standardized_signature_def函数,甚至更多来自它调用的is_classification_problem函数.使用csv服务函数的输入字典长度是1,所以这个逻辑最终使用classification_signature_def,它最终只显示得分(结果实际上是概率),而输入字典长度大于1,json服务输入函数而是使用包含所有输出的predict_signature_def.

Eli*_*xby 8

更新:在版本1.3中,贡献估计器(例如tf.contrib.learn.DNNClassifier)被更改为继承自核心估计器类tf.estimator.Estimator,与其前身不同,它将模型函数隐藏为私有类成员,因此你需要estimator.model_fn在下面的解决方案中替换estimator._model_fn.

Josh的答案指向了Flowers示例,如果您想使用自定义估算器,这是一个很好的解决方案.如果您想坚持使用预制估算器(例如tf.contrib.learn.DNNClassifiers),您可以将其包装在自定义估算器中,以增加对键的支持.(注意:我认为,当它们进入核心时,罐装估算器可能会获得关键支持).

KEY = 'key'
def key_model_fn_gen(estimator):
    def _model_fn(features, labels, mode, params):
        key = features.pop(KEY, None)
        model_fn_ops = estimator.model_fn(
           features=features, labels=labels, mode=mode, params=params)
        if key:
            model_fn_ops.predictions[KEY] = key
            # This line makes it so the exported SavedModel will also require a key
            model_fn_ops.output_alternatives[None][1][KEY] = key
        return model_fn_ops
    return _model_fn

my_key_estimator = tf.contrib.learn.Estimator(
    model_fn=key_model_fn_gen(
        tf.contrib.learn.DNNClassifier(model_dir=model_dir...)
    ),
    model_dir=model_dir
)
Run Code Online (Sandbox Code Playgroud)

my_key_estimator然后可以像你DNNClassifier将要使用的那样使用,除非它期望具有'key'input_fns(预测,评估和训练)名称的特征.

EDIT2:您还需要将相应的输入张量添加到您选择的预测输入功能中.例如,新的JSON服务输入fn将如下所示:

def json_serving_input_fn():
  inputs = # ... input_dict as before
  inputs[KEY] = tf.placeholder([None], dtype=tf.int64)
  features = # .. feature dict made from input_dict as before
  tf.contrib.learn.InputFnOps(features, None, inputs)
Run Code Online (Sandbox Code Playgroud)

(在1.2和1.3之间略有不同,因为tf.contrib.learn.InputFnOps替换为tf.estimator.export.ServingInputReceiver,并且在1.3中不再需要填充张量为2的填充)

然后ML Engine将发送一个名为"key"的张量,其中包含您的预测请求,该张量将传递给您的模型,并通过您的预测.

EDIT3:已修改key_model_fn_gen为支持忽略缺少的键值.EDIT4:添加了预测键