在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_tensors
和features
。
从receiver_tensors
的{{3}}(或source code:
- 功能:一个
@estimator_export('estimator.export.ServingInputReceiver')
,Tensor
或字符串字典到SparseTensor
或Tensor
,指定要传递给模型的要素。注意: 如果传递的SparseTensor
不是字典,则将其包装在字典中,并带有一个 单一条目,使用“功能”作为键。因此,模型必须 接受{'feature':张量}形式的特征字典。您可以使用features
,如果您希望按原样传递张量。- receiver_tensors :A
TensorServingInputReceiver
,Tensor
或字符串字典到SparseTensor
或Tensor
,指定此接收者希望在其中输入的节点 默认情况下被喂食。通常,这是单个占位符,期望 序列化的SparseTensor
原型。
阅读后,我很清楚tf.Example
的目的是什么。 features
是我随后通过图形发送的输入字典。许多常见模型只有一个输入,但是您当然可以有更多输入。
因此,关于features
的声明对我来说“通常是一个占位符,期望序列化receiver_tensors
原型。”对tf.Example
来说,想要{从TF receiver_tensors
s中解析了{1}} s。
为什么?如果对TF (Sequence)Example
进行了充分的预处理,那么这是否多余?如果未完全预处理,为什么要通过? Record
和Record
字典中的键应该相同吗?
有人可以向我提供一个更具体的例子,说明现在的区别以及去向何处
features
有效...(即使可能不应该...)
答案 0 :(得分:1)
服务输入功能的工作是将模型功能接受的原始特征转换为已处理的特征。
receiver_tensors
:这些是输入占位符。这会在您的图形中打开,您将在其中收到原始输入功能。
定义此占位符后,您可以对这些接收器张量执行转换,以将其转换为模型可接受的特征。其中一些转换将包括:
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)