Я перевожу текущую модель Tensorflow 1.x, построенную с оценщиками, в Tensorflow 2.0 Keras. Миграция была относительно плавной, пока не пришло время сериализации модели для обслуживания.
Модель указана следующим образом
model = tf.keras.Sequential()
model.add(tf.keras.layers.DenseFeatures(feature_columns))
for units in hidden_layers:
model.add(tf.keras.layers.Dense(units, activation='relu'))
model.add(tf.keras.layers.Dense(2, activation=None))
Я использую api столбцов объектов Tensorflow, который ожидает в качестве входных данных словарь столбцов объектов, и применяю преобразование к этим объектам до того, как они пройдутв модель.
Например, при обучении
def dataset_transformation_function(feature_dict: Dict[str, tf.Tensor]):
output_dict = feature_dict.copy()
output_dict['logx1'] = tf.math.log(feature_dict['x1'])
return output_dict
train_dataset = (
tf.data.Dataset.from_tensor_slices(
(train_feature_dict, train_label_vector)
)
.shuffle(n_train)
.batch(batch_size)
.map(dataset_transformation_function)
.repeat()
.prefetch(tf.data.experimental.AUTOTUNE)
)
Похоже, что для выполнения того же преобразования во время подачи мне требуется:
input_tensors = [tf.Tensorspec(name=...), ...]
@tf.function(input_signature=input_tensors)
def dataset_transformation_function(args) -> Dict[str, tf.Tensor]:
...
И
tf.saved_model.save(
model,
MODEL_DIR,
signatures=feature_transform,
)
Однако я не могу определить правильную сигнатуру для входного тензора или функции.
Метод, с которого я выполняю миграцию:
def serving_input_fn():
receiver_tensors = {
'x1': tf.placeholder(dtype=tf.float32, shape=[None, ], name='x1')
'x2': tf.placeholder(dtype=tf.string, shape=[None, ], name='x2')
}
features = dataset_transformation_function(
receiver_tensors
)
return tf.estimator.export.ServingInputReceiver(features, receiver_tensors)
estimator.export_savedmodel(
MODEL_DIR,
serving_input_fn,
as_text=False,
checkpoint_path=estimator.best_checkpoint,
)