Оценщик TensorFlow Оценщик ServingInputReceiver отличается от receive_tensors: когда и почему?
В предыдущем вопросе цель и структура 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}
работает... (даже если, возможно, не должно...)
Ответы
Ответ 1
Если вы выполняете предварительную обработку внутри TensorServingInputReceiver, то приемник и функции будут другими. функции будут переданы в модель после предварительной обработки внутри TensorServingInputReceiver. receive_tensors являются входными данными для TensorServingInputReceiver, и они могут быть в формате tf.Example
Ответ 2
Задача обслуживающей входной функции - преобразовать полученные необработанные функции в обработанные функции, которые принимает функция вашей модели.
receiver_tensors
: это входные заполнители. Это откроется на вашем графике, где вы получите свои исходные функции ввода.
После определения этого заполнителя вы выполняете преобразования этих тензоров приемника, чтобы преобразовать их в объекты, приемлемые для модели. Некоторые из этих преобразований будут включать:
- Предварительная обработка полученных данных.
- Пример разбора от tfrecord. (Если вы предоставляете tfrecord в качестве входных данных для функции обслуживания)
features
: Как только вы преобразуете, получают признаки тензора, которые напрямую передаются в функцию модели во время прогнозирования.
В вашем случае предварительная обработка не требуется для данных, которые вы предоставляете для своей входной функции обслуживания. Следовательно, features = receiver_tensors
работает.