语境

我有一个带有非常简单的colab演示的 Estimator ,目的是学习/理解 Estimator API,目的是为即插即用模型建立一个约定,并附带有用的技巧(例如,提前停止验证集停止改进,导出模型等)。

三种 Estimator 模式(TRAINEVALPREDICT)都返回一个 EstimatorSpec

根据docs:

__new__(
    cls,
    mode,
    predictions=None,          # required by PREDICT
    loss=None,                 # required by TRAIN and EVAL
    train_op=None,             # required by TRAIN
    eval_metric_ops=None,
    export_outputs=None,
    training_chief_hooks=None,
    training_hooks=None,
    scaffold=None,
    evaluation_hooks=None,
    prediction_hooks=None.
)

在这些命名参数中,我想引起注意predictionsexport_outputs,它们在docs中描述为:



因此应该清楚为什么我提起export_outputs;也就是说,就像将来最有可能使用他们训练的模型一样(通过从SavedModel加载模型)。

为了使这个问题更容易理解/增加一些清晰度:
  • “单头”模型是遇到的最常见的模型,其中input_fn features转换为单数(批处理)output
  • “多头”模型是其中有多个输出
  • 的模型

    例如此多头模型的input_fn(根据 Estimator API)返回一个元组(features, labels),即该模型有两个头。
    def input_fn():
      features = ...
      labels1 = ...
      labels2 = ...
      return features, {'head1': labels1, 'head2': labels2}
    

    这个问题的核心是如何指定signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY。即,如何指定呢? (例如,应该是dict {signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: head})

    是的,因此在colab中,您会看到我们模型的export_outputs实际上是以多头方式定义的(尽管不应如此):

    colabestimator functions > model_fn中:
    def model_fn(...):
    
        # ...
    
        # send the features through the graph
        MODEL = build_fn(MODEL)
    
        # prediction
        MODEL['predictions'] = {'labels': MODEL['net_logits']} # <--- net_logits added in the build_fn
    
        MODEL['export_outputs'] = {
            k: tf.estimator.export.PredictOutput(v) for k, v in MODEL['predictions'].items()
        }
    
        # ...
    

    在此特定情况下,如果我们扩展字典理解,我们的功能等效于:
    MODEL['export_outputs'] = {
        'labels': tf.estimator.export.PredictOutput(MODEL['net_logits'])
    }
    

    在这种情况下它可以工作,因为我们的字典有一个键,因此有一个 PredictOutput ,其中在colab中,我们的model_fn只有一个头,并且将其更正确地格式化为:
    MODEL['export_outputs'] = {
        'predictions': tf.estimator.export.PredictOutput(MODEL['predictions'])
    }
    

    PredictOutput 中所述:
    __init__(outputs)
    

    在哪里
  • outputs:Tensor或Tensor的字符串字典表示预测。

  • 问题

    因此,我的问题如下:
  • 如果 PredictOutput 可以是一本字典,那么什么时候/为什么要用多个 PredictOutput 作为 export_outputs EstimatorSpec
  • 如果一个人有一个多头模型(比如说有多个 PredictOutput ),那么一个人实际上是如何指定signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY
  • 如果在predictions中也“需要”(对于关心使用EstimatorSpec的任何人),那么 SavedModel export_outputs的意义是什么?
  • 最佳答案

    感谢您的详细问题;您显然已经在这里深挖了。

  • 也有RegressionOutput和CategoryOutput的类,它们不能是字典。使用export_outputs dict可以对这些用例进行概括。
  • 要从保存的模型默认提供服务的头部,应采用默认的签名 key 。例如:
  • export_outputs = {
      signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY:
        PredictOutput(outputs={'some_output_1': output_1}),
      'head-2': PredictOutput(outputs={'some_output_2': output_2}),
      'head-3': PredictOutput(outputs={'some_output_3': output_3})
    }
    
  • 原因1:许多人使用默认的export_outputs(反过来就是预测的值),或者不导出到保存的模型。原因2:历史。首先是预测,随着时间的流逝,越来越多的功能被添加。这些功能需要灵活性和额外的信息,因此需要独立包装到EstimatorSpec中。
  • 关于python - TensorFlow ExportOutputs,PredictOuput并指定signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53414168/

    10-11 04:30