TensorFlow估算器ServingInputReceiver的功能与receiver_tensors的比较:何时以及为什么?

时间:2018-11-21 10:50:01

标签: python tensorflow tensorflow-estimator

previous question中,探索了NAMESPACE NAME READY STATUS RESTARTS AGE kube-system coredns-576cbf47c7-4x7zq 1/1 Running 0 36m kube-system coredns-576cbf47c7-666jm 1/1 Running 0 36m kube-system etcd-centos-7-5 1/1 Running 0 35m kube-system kube-apiserver-centos-7-5 1/1 Running 0 35m kube-system kube-controller-manager-centos-7-5 1/1 Running 0 35m kube-system kube-flannel-ds-amd64-2bmw9 1/1 Running 0 33m kube-system kube-proxy-pcgw8 1/1 Running 0 36m kube-system kube-scheduler-centos-7-5 1/1 Running 0 35m 的目的和结构,并在answer中:

serving_input_receiver_fn

answer的作者声明(关于def serving_input_receiver_fn(): """For the sake of the example, let's assume your input to the network will be a 28x28 grayscale image that you'll then preprocess as needed""" input_images = tf.placeholder(dtype=tf.uint8, shape=[None, 28, 28, 1], name='input_images') # here you do all the operations you need on the images before they can be fed to the net (e.g., normalizing, reshaping, etc). Let's assume "images" is the resulting tensor. features = {'input_data' : images} # this is the dict that is then passed as "features" parameter to your model_fn receiver_tensors = {'input_data': input_images} # As far as I understand this is needed to map the input to a name you can retrieve later return tf.estimator.export.ServingInputReceiver(features, receiver_tensors) ):

  

据我所知,需要将输入映射到您可以稍后检索的名称

我不清楚这种区别。实际上,(请参阅此colab),可以将同一词典传递给receiver_tensorsfeatures

receiver_tensors的{​​{3}}(或source code

  
      
  • 功能:一个@estimator_export('estimator.export.ServingInputReceiver')Tensor或字符串字典到SparseTensor或     Tensor,指定要传递给模型的要素。注意:     如果传递的SparseTensor不是字典,则将其包装在字典中,并带有一个     单一条目,使用“功能”作为键。因此,模型必须     接受{'feature':张量}形式的特征字典。您可以使用     features,如果您希望按原样传递张量。
  •   
  • receiver_tensors :A TensorServingInputReceiverTensor或字符串字典到SparseTensor     或Tensor,指定此接收者希望在其中输入的节点     默认情况下被喂食。通常,这是单个占位符,期望     序列化的SparseTensor原型。
  •   

阅读后,我很清楚tf.Example的目的是什么。 features是我随后通过图形发送的输入字典。许多常见模型只有一个输入,但是您当然可以有更多输入。

因此,关于features的声明对我来说“通常是一个占位符,期望序列化receiver_tensors原型。”对tf.Example来说,想要{从TF receiver_tensors s中解析了{1}} s。

为什么?如果对TF (Sequence)Example进行了充分的预处理,那么这是否多余?如果未完全预处理,为什么要通过? RecordRecord字典中的键应该相同吗?

有人可以向我提供一个更具体的例子,说明现在的区别以及去向何处

features

有效...(即使可能不应该...)

3 个答案:

答案 0 :(得分:1)

服务输入功能的工作是将模型功能接受的原始特征转换为已处理的特征

receiver_tensors:这些是输入占位符。这会在您的图形中打开,您将在其中收到原始输入功能。

定义此占位符后,您可以对这些接收器张量执行转换,以将其转换为模型可接受的特征。其中一些转换将包括:

  • 预处理收到的数据。
  • 从tfrecord解析示例。 (如果您要提供tfrecord作为服务功能的输入)

features:转换后,将获得张量特征,这些特征将在预测期间直接馈送到模型函数中。

在这种情况下,不需要对提供给服务输入功能的数据进行预处理。因此features = receiver_tensors正在工作。

答案 1 :(得分:0)

如果您在TensorServingInputReceiver内部进行预处理,则receive_tensors和功能将有所不同。在TensorServingInputReceiver内部进行预处理后,功能将传递给模型。 receiver_tensors是TensorServingInputReceiver的输入,可以为tf。示例格式

答案 2 :(得分:0)

据我了解,SWAPNIL的答案是正确的。 我会分享一个我的例子。

假设图的输入是形状为[None,64]的占位符

inputs = tf.placeholder(dtype=tf.float32, shape=[None, 64])
prediction = ... # do some prediction

但是我们从上游得到的是32个浮点数的数组,我们需要将它们处理为[None,64]形状,例如,简单地重复它们。

def serving_fn():
    inputs = tf.placeholder(dtype=tf.float32, shape=[None, 32])  # this is raw input
    features = tf.concat([inputs, inputs], axis=1)  # this is how we get model input from raw input
    return tf.estimator.export.TensorServingInputReceiver(features, inputs)

当然,我们可以在外部进行此过程,并提供估计器数据,就像定义图的输入一样。在这种情况下,我们将上游过程中的输入连接起来,原始输入的形状将为[None,64] 所以功能应该是

def serving_fn():
    inputs = tf.placeholder(dtype=tf.float32, shape=[None, 64])  # this is raw input
    features = inputs  # we simply feed the raw input to estimator
    return tf.estimator.export.TensorServingInputReceiver(features, inputs)