В предыдущем вопросе цель и структура serving_input_receiver_fn
рассмотрены и в ответе:
def serving_input_receiver_fn():
"""For the sake of the example, let 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 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)
Автор ответа утверждает (в отношении receiver_tensors
):
Насколько я понимаю, это необходимо для сопоставления ввода с именем, которое вы можете получить позже
Это различие мне неясно. На практике (см. Этот колаб) один и тот же словарь может быть передан как features
и receiver_tensors
.
Из исходного кода @estimator_export('estimator.export.ServingInputReceiver')
(или документов ServingInputReceiver:
- Особенности:
Tensor
,SparseTensor
или ДИКТ строки вTensor
илиSparseTensor
, указав функции должны быть переданы модели. Примечание: если переданныеfeatures
не являются диктовкой, они будут заключены в диктовку с одной записью с использованием "функции" в качестве ключа. Следовательно, модель должна принимать характеристику в форме {'особенность': тензор}. Вы можете использоватьTensorServingInputReceiver
если хотите, чтобы тензор передавался как есть.- receiver_tensors: а
Tensor
,SparseTensor
или ДИКТ строки кTensor
илиSparseTensor
, с указанием входных узлов, где этот приемник рассчитывает быть подан по умолчанию. Как правило, это один заполнитель, ожидающий сериализованныеtf.Example
.
После прочтения мне становится ясно, какова цель features
. features
- это словарь входных данных, которые я затем посылаю через график. Многие распространенные модели имеют только один вход, но вы можете или, конечно, иметь больше.
Таким образом, то утверждение о receiver_tensors
которых " Как правило, это один - заполнитель ожидает сериализованная tf.Example
Протоса.", Мне, говорит о том, что receiver_tensors
хотят сингулярный заполнитель для пакетного (Sequence)Example
проанализированного из TF Record
s.
Зачем? Если Record
TF полностью предварительно обработана, то это избыточно? если он не полностью предварительно обработан, зачем его пропускать? Должны ли быть одинаковыми ключи в словарях features
и receiver_tensors
?
Может кто-нибудь, пожалуйста, предоставьте мне более конкретный пример разницы и того, что и где, как сейчас
input_tensors = tf.placeholder(tf.float32, <shape>, name="input_tensors")
features = receiver_tensors = {'input_tensors': input_tensors}
работает... (даже если, возможно, не должно...)