Похоже, вы пытаетесь выполнить декодирование base64 в TensorFlow , а использовать формат {"b64": ...}
JSON.Вам нужно сделать одно или другое;как правило, мы рекомендуем последнее.
В качестве примечания, ваш входной заполнитель должен иметь внешний размер None
.Это может усложнить некоторые вещи, например, вам придется либо изменить размеры до размера 1 (что помешает вам использовать службу пакетного прогнозирования в ее текущем состоянии), либо вам придется tf.map_fn
применитьодинаковый набор преобразований для каждого элемента входного «пакета».Вы можете найти пример этой техники в этом примере .
Наконец, я рекомендую использовать tf.saved_model.simple_save
.
В целом, вот некоторый модифицированный код.Обратите внимание, что я встраиваю вашу функцию ввода (в отличие от ее сериализации в графическое определение и повторного импорта):
HEIGHT = 299
WIDTH = 299
# Get Keras Model
from keras.applications.inception_v3 import InceptionV3
model = InceptionV3(weights='imagenet')
from keras.models import Model
intermediate_layer_model = Model(inputs=model.input,outputs=model.layers[311].output)
K.set_learning_phase(0)
sess = K.get_session()
from tensorflow.python.framework import graph_util
g_trans = sess.graph
g_trans_def = graph_util.convert_variables_to_constants(sess,
g_trans.as_graph_def(),
[intermediate_layer_model.output.name.replace(':0','')])
# Create inputs to model and export
with tf.Graph().as_default() as g_combined:
def decode_and_resize(image_bytes):
image = tf.image.decode_image(image_bytes)
# Note resize expects a batch_size, but tf_map supresses that index,
# thus we have to expand then squeeze. Resize returns float32 in the
# range [0, uint8_max]
image = tf.expand_dims(image, 0)
image = tf.image.resize_bilinear(
image, [HEIGHT, WIDTH], align_corners=False)
image = tf.squeeze(image, squeeze_dims=[0])
image = tf.cast(image, dtype=tf.uint8)
return image
input_byes = tf.placeholder(shape=(None,),
dtype=tf.string,
name='input')
images = tf.map_fn(
decode_and_resize, input_bytes, back_prop=False, dtype=tf.uint8)
images = tf.image.convert_image_dtype(images, dtype=tf.float32)
pred, = tf.import_graph_def(g_trans_def,
input_map={intermediate_layer_model.input.name: images,
'batch_normalization_1/keras_learning_phase:0': False},
return_elements=[intermediate_layer_model.output.name])
with tf.Session() as sess2:
tf.saved_model.simple_save(
sess2,
model_dir='inceptionv4/'
inputs={"inputs": input_bytes},
outputs={"outputs": pred})
Примечание: Я не уверен на 100%, что фигурыintermediate_layer_model
и images
совместимы.Форма images
будет [Нет, высота, ширина, num_channels].
Также обратите внимание, что ваш локальный код предсказания немного изменится.Вы не кодируете изображения base64, и вам нужно отправить «пакет» / список изображений, а не отдельные изображения.Что-то вроде:
with open('MEL_BE_0.jpg', 'rb') as image_file:
encoded_string = image_file.read()
input_tensor = tf.get_default_graph().get_tensor_by_name('input:0')
print(input_tensor)
avg_tensor = tf.get_default_graph().get_tensor_by_name('import_1/avg_pool/Mean:0')
print(avg_tensor)
predictions = sess.run(avg_tensor, {input_tensor: [encoded_string]})
Вы не указали, используете ли вы пакетное прогнозирование или онлайн-прогнозирование, которые имеют похожие, но немного отличающиеся «форматы» для входных данных.В любом случае ваша модель не экспортирует поле «ключ» (вы имели в виду? Возможно, это полезно для пакетного прогнозирования, но не для онлайн).
Для пакетного прогнозирования формат файла - строки JSON;каждая строка содержит один пример.Каждая строка может быть сгенерирована следующим образом из Python:
example = json.dumps({"image_bytes": {"b64": ENCODED_STRING}})
(обратите внимание на пропуск "ключа" на данный момент).Поскольку у вас есть только один вход, есть сокращение:
example = json.dumps({"b64": ENCODED_STRING})
Если вы хотите делать онлайн-прогнозирование, вы заметите, что если вы используете gcloud
для отправки запросов, вы фактически используете тот жеформат файла как для пакетного прогнозирования.
На самом деле, мы настоятельно рекомендуем использовать gcloud ml-engine local predict --json-instances=FILE --model-dir=...
перед развертыванием в облаке, чтобы помочь отладке.
Если вы собираетесь использовать какой-то другой клиент помимо gcloud, напримерв веб-приложении, мобильном приложении, веб-сервере и т. д. вы не будете отправлять файл, и вам нужно будет самостоятельно создать полный запрос.Это очень похоже на формат файла выше.В основном, возьмите каждую строку файла строк JSON и поместите их в массив, называемый «instances», то есть
request_body= json.dumps({"instances": [{"image_bytes": {"b64": [encoded_string]}}]})
Вы можете использовать тот же синтаксический сахар, если хотите:
request_body= json.dumps({"instances": [{"b64": [encoded_string]}]})
Надеюсь, это поможет!