使用 TensorFlow 服务为 TF 模型提供服务时,应该在哪里执行预处理和后处理步骤?

Posted

技术标签:

【中文标题】使用 TensorFlow 服务为 TF 模型提供服务时,应该在哪里执行预处理和后处理步骤?【英文标题】:Where should pre-processing and post-processing steps be executed when a TF model is served using TensorFlow serving? 【发布时间】:2018-03-10 18:04:29 【问题描述】:

通常要使用 TF 图,必须将原始数据转换为数值。我将此过程称为预处理步骤。例如,如果原始数据是一个句子,一种方法是对句子进行标记并将每个单词映射到一个唯一的数字。这种预处理为每个句子创建了一个数字序列,这将是模型的输入。

我们还需要对模型的输出进行后处理以对其进行解释。例如,将模型生成的数字序列转换为单词,然后构建一个句子。

TF Serving 是 Google 最近推出的一项新技术,用于服务于 TF 模型。我的问题是:

当使用 TensorFlow 服务为 TF 模型提供服务时,应该在哪里执行预处理和后处理?

我是否应该在我的 TF Graph 中封装预处理和后处理步骤(例如,使用 py_fun 或 map_fn)或者还有其他我不知道的 TensorFlow 技术。

【问题讨论】:

py_fun 不能成为here 中提到的解决方案: tf.py_func() 操作具有以下已知限制: 函数体(即 func)不会在 GraphDef 中序列化。因此,如果您需要序列化模型并在不同的环境中恢复,则不应使用此功能。 你解决过这个问题吗? tf.transform 似乎还不能支持复杂的标记化。 据我了解,没有简单的方法来处理这个问题。理想情况下,您希望使用 Tensorflow 操作(或添加必要的操作)来实现预处理/后处理步骤,并使用 tf.transform 将这些操作与您的 TF 图一起发送。但是,正如您可能猜到的那样,添加新的 TF OP 并不是一项简单的任务,这为实现预处理/后处理步骤增加了很多限制。当然,您总是可以在图之外进行前/后处理,但这不是一个理想的解决方案。 这是我现在使用 tensorflow-serving 的第一个问题。我在 tensorflow-serving 中就这个话题做了一个issue。 【参考方案1】:

我在这里遇到了同样的问题,即使我还不是 100% 确定如何使用 wordDict 变量(我猜你也使用一个来映射单词及其 id),主要的 pre-处理和后处理函数在这里定义:

https://www.tensorflow.org/programmers_guide/saved_model

作为export_outputsserving_input_receiver_fn

exports_outputs

如果您使用估算器,则需要在 EstimatorSpec 中定义。这是一个分类算法的例子

  predicted_classes = tf.argmax(logits, 1)
  categories_tensor = tf.convert_to_tensor(CATEGORIES, tf.string)
  export_outputs =  "categories": export_output.ClassificationOutput(classes=categories_tensor) 
  if mode == tf.estimator.ModeKeys.PREDICT:
    return tf.estimator.EstimatorSpec(
        mode=mode,
        predictions=
            'class': predicted_classes,
            'prob': tf.nn.softmax(logits)
        ,
        export_outputs=export_outputs)
serving_input_receiver_fn

需要在导出经过训练的估计器模型之前对其进行定义,它假定输入是原始字符串并从那里解析您的输入,您可以编写自己的函数,但我不确定何时可以使用外部变量。下面是一个分类算法的简单示例:

def serving_input_receiver_fn():
    feature_spec =  "words": tf.FixedLenFeature(dtype=tf.int64, shape=[4]) 
    return tf.estimator.export.build_parsing_serving_input_receiver_fn(feature_spec)()

  export_dir = classifier.export_savedmodel(export_dir_base=args.job_dir,
                                            serving_input_receiver_fn=serving_input_receiver_fn)

希望对你有帮助。

【讨论】:

感谢您的解决方案。据我了解,这种方法在图中节省了预处理和后处理步骤。这意味着这些步骤应限制为仅使用 TensorFlow Ops。这是一个很大的限制,在某些应用程序中很难做到。例如对于文本标记化,一种简单的方法是使用正则表达式将文本拆分为标记。将其转换为 TensorFlow Ops 并非易事。 true,但似乎是使用文本处理算法的方式,如谷歌在此处medium.com/towards-data-science/… 所述。 感谢您的链接,这是一篇有趣的文章。 但是,据我了解,在代码中,假设预处理已经在 tensorflow 之外完成。检查此代码:tf.constant('Some title'.split()) 例如,其中标记输入文本。 我能够将解决方案与此代码放在一起。正在使用 cnn_model 函数第一行中的算法进行处理,导出的模型包含 exports/Servo/id/assets 中的单词 dict 并按预期使用文本输入。

以上是关于使用 TensorFlow 服务为 TF 模型提供服务时,应该在哪里执行预处理和后处理步骤?的主要内容,如果未能解决你的问题,请参考以下文章

TensorFlow2 动手训练模型和部署服务

TensorFlow2 动手训练模型和部署服务

学习笔记TF066:TensorFlow移动端应用,iOSAndroid系统实践

如何在具有使用@tf.keras.utils.register_keras_serializable 注册的自定义函数的 Tensorflow Serving 中提供模型?

Tensorflow:用 tf.Variable 替换/提供图形的占位符?

tensorflow-滑动平均模型