Estoy planeando implementar el modelo en Cloud Machine Learning (ML) Engine después de entrenarlo en las instalaciones, pero no tengo idea de cómo implementar la función de entrada de servicio .
Además, he intentado evitar las API de bajo nivel de TensorFlow y solo me he centrado en las API de alto nivel de TensorFlow ( TensorFlow Estimator ). A continuación, en los bloques de código, se encuentra el código de ejemplo en el que estoy trabajando.
import numpy as np
import tensorflow as tf
import datetime
import os
# create model
from tensorflow.python.keras.applications.vgg16 import VGG16
from tensorflow.python.keras import models
from tensorflow.python.keras import layers
conv_base = VGG16(weights='imagenet',
include_top=False,
input_shape=(150, 150, 3))
model = models.Sequential()
model.add(conv_base)
model.add(layers.Flatten())
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))
conv_base.trainable = False
model.compile(loss='binary_crossentropy',
optimizer=tf.keras.optimizers.RMSprop(lr=2e-5),
metrics=['acc'])
dt = datetime.datetime.now()
datetime_now = dt.strftime("%y%m%d_%H%M%S")
model_dir = 'models/imageclassifier_'+datetime_now
model_dir = os.path.join(os.getcwd(), model_dir)
if not os.path.exists(model_dir):
os.makedirs(model_dir)
print ("model_dir: ",model_dir)
est_imageclassifier = tf.keras.estimator.model_to_estimator(keras_model=model, model_dir=model_dir)
# input layer name
input_name = model.input_names[0]
input_name
Esta sección es para la función de entrada de imágenes.
def imgs_input_fn(filenames, labels=None, perform_shuffle=False, repeat_count=1, batch_size=1):
def _parse_function(filename, label):
image_string = tf.read_file(filename)
image = tf.image.decode_image(image_string, channels=3)
image.set_shape([None, None, None])
image = tf.image.resize_images(image, [150, 150])
image = tf.subtract(image, 116.779) # Zero-center by mean pixel
image.set_shape([150, 150, 3])
image = tf.reverse(image, axis=[2]) # 'RGB'->'BGR'
d = dict(zip([input_name], [image])), label
return d
if labels is None:
labels = [0]*len(filenames)
labels=np.array(labels)
# Expand the shape of "labels" if necessary
if len(labels.shape) == 1:
labels = np.expand_dims(labels, axis=1)
filenames = tf.constant(filenames)
labels = tf.constant(labels)
labels = tf.cast(labels, tf.float32)
dataset = tf.data.Dataset.from_tensor_slices((filenames, labels))
dataset = dataset.map(_parse_function)
if perform_shuffle:
# Randomizes input using a window of 256 elements (read into memory)
dataset = dataset.shuffle(buffer_size=256)
dataset = dataset.repeat(repeat_count) # Repeats dataset this # times
dataset = dataset.batch(batch_size) # Batch size to use
iterator = dataset.make_one_shot_iterator()
batch_features, batch_labels = iterator.get_next()
return batch_features, batch_labels
Me gustaría crear una función de entrada de servicio que
Obtenga imágenes como cadenas codificadas en base64 en formato JSON
Conviértelos en tensores y reduzca el tamaño a (?, 150, 150, 3) para la predicción
Como se muestra abajo,
def serving_input_receiver_fn():
''' CODE HERE!'''
return tf.estimator.export.ServingInputReceiver(feature_placeholders, feature_placeholders)
Para entrenar y evaluar el modelo,
train_spec = tf.estimator.TrainSpec(input_fn=lambda: imgs_input_fn(train_files,
labels=train_labels,
perform_shuffle=True,
repeat_count=1,
batch_size=20),
max_steps=500)
exporter = tf.estimator.LatestExporter('Servo', serving_input_receiver_fn)
eval_spec = tf.estimator.EvalSpec(input_fn=lambda: imgs_input_fn(val_files,
labels=val_labels,
perform_shuffle=False,
batch_size=1),
exporters=exporter)
tf.estimator.train_and_evaluate(est_imageclassifier, train_spec, eval_spec)
Si lo entiendo correctamente, el ejemplo del archivo de entrada para obtener la predicción en Cloud ML Engine debería ser algo así como
request.json
{"b64": "9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHJC...”}
{"b64": "9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHJC...”}
Y
gcloud ml-engine predict --model MODEL_NAME \
--version MODEL_VERSION \
--json-instances request.json
Si está leyendo hasta aquí y tiene alguna idea, podría sugerirme cómo implementar la función de entrada de servicio para este caso en particular.
Muchas gracias de antemano,
De acuerdo con el comentario de sdcbr, a continuación aquí está mi serve_input_receiver_fn ().
Para la función _img_string_to_tensor () o (función prepare_image), supongo que debería hacer la preparación de la imagen de la misma manera que entrené el modelo que puede ver
imgs_input_fn () => _función_parse ().
def serving_input_receiver_fn():
def _img_string_to_tensor(image_string):
image = tf.image.decode_image(image_string, channels=3)
image.set_shape([None, None, None])
image = tf.image.resize_images(image, [150, 150])
image = tf.subtract(image, 116.779) # Zero-center by mean pixel
image.set_shape([150, 150, 3])
image = tf.reverse(image, axis=[2]) # 'RGB'->'BGR'
return image
input_ph = tf.placeholder(tf.string, shape=[None])
images_tensor = tf.map_fn(_img_string_to_tensor, input_ph, back_prop=False, dtype=tf.float32)
return tf.estimator.export.ServingInputReceiver({model.input_names[0]: images_tensor}, {'image_bytes': input_ph})
Después de entrenar el modelo e implementar el modelo guardado en Cloud ML Engine. Mi imagen de entrada se preparó en el formato que se muestra a continuación.
{"image_bytes": {"b64": "YQ=="}}
Pero encontré el error después de obtener una predicción a través de gcloud.
gcloud ml-engine predict --model model_1 \
--version v1 \
--json-instances request.json
{"error": "Error de predicción: Error durante la ejecución del modelo: AbortionError (código = StatusCode.INVALID_ARGUMENT, detalles = \" error de afirmación: [No se pueden decodificar bytes como JPEG, PNG, GIF o BMP] \ n \ t [[ {{mapa de nodo / while / decode_image / cond_jpeg / cond_png / cond_gif / Assert_1 / Assert}} = Assert [T = [DT_STRING], resume = 3, _device = \ "/ job: localhost / replica: 0 / task: 0 / dispositivo: CPU: 0 \ "] (mapa / while / decode_image / cond_jpeg / cond_png / cond_gif / is_bmp, map / while / decode_image / cond_jpeg / cond_png / cond_gif / Assert_1 / Assert / data_0)]] \") "}
¿Hice algo mal en la función _img_string_to_tensor?
y ¿Podría aclararme más acerca de este tf.placeholder?
input_ph = tf.placeholder(tf.string, shape=[None])
Para el código anterior, usa shape = [1], pero creo que debería ser shape = [None].
Algo en estas líneas debería funcionar:
def serving_input_receiver_fn():
def prepare_image(image_str_tensor):
image = tf.image.decode_image(image_str_tensor,
channels=3)
image = tf.image.resize_images(image, [150, 150])
return image
# Ensure model is batchable
# https://stackoverflow.com/questions/52303403/
input_ph = tf.placeholder(tf.string, shape=[None])
images_tensor = tf.map_fn(
prepare_image, input_ph, back_prop=False, dtype=tf.float32)
return tf.estimator.export.ServingInputReceiver(
{model.input_names[0]: images_tensor},
{'image_bytes': input_ph})
Puede agregar preprocesamiento adicional en la prepare_image
función. Tenga en cuenta que images_tensor
debe asignarse el nombre de la capa en su tf.keras
modelo que se supone que debe recibir la entrada.
Este artículo se recopila de Internet, indique la fuente cuando se vuelva a imprimir.
En caso de infracción, por favor [email protected] Eliminar
Déjame decir algunas palabras