TensorFlow se publica para imágenes como cadenas codificadas en base64 en Cloud ML Engine

ES

Cómo implementar la función de entrada de publicación de TensorFlow para imágenes como cadenas codificadas en base64 y obtener predicciones en Cloud ML Engine

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

  1. Obtenga imágenes como cadenas codificadas en base64 en formato JSON

  2. 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,


2nd Post - Para actualizar lo que he hecho hasta ahora.

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].

sdcbr

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_imagefunción. Tenga en cuenta que images_tensordebe asignarse el nombre de la capa en su tf.kerasmodelo que se supone que debe recibir la entrada.

Consulte también esta y esta pregunta relacionada.

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

Editado en
0

Déjame decir algunas palabras

0Comentarios
Iniciar sesiónRevisión de participación posterior

Artículos relacionados

Google cloud vision no acepta imágenes codificadas en base64 python

Crea imágenes codificadas en base64 con JavaScript

Pasando cadenas codificadas en base64 en URL

Problemas de seguridad con imágenes codificadas en base64

Estructura de cadenas codificadas en base 64 en html

Discrepancias de cadenas codificadas en Ruby vs.Go / sha256 hmac base64

atob no decodificará las cadenas de arranque codificadas en base64

Javascript: envía dos matrices de imágenes codificadas en base64 a php a través de xhr

Devolver imágenes codificadas en base64 directamente desde un punto final central de API web

¿Eliminar la nueva línea "\ n" de las cadenas codificadas en base64 en Python3?

La compresión de imágenes codificadas en base64 en React-Native en Android no reconoce el protocolo de 'datos'

¿Cómo mostrar imágenes que se almacenan como matriz de cadenas en html?

Flutter, ¿cómo convertir Listas codificadas como cadenas para una base de datos SQFL de nuevo en Listas de forma concisa?

tensorflow fundió tf.int32 a tf.string en la versión adecuada para Google Cloud ml-engine

¿Pueden dos cadenas codificadas BASE 64 diferentes dar como resultado la misma cadena si se decodifican?

La lista de imágenes Base64 incrustadas en Thymeleaf no se mostrará

¿Debo incrustar imágenes como datos / base64 en CSS o HTML?

Cómo codificar imágenes en webassembly como base64

¿Cómo conservar la carpeta de imágenes mientras se publica en Elastic Beanstalk?

Usar TPU en Cloud ML Engine

¿Cómo mostrar imágenes Base64 en HTML?

Conversión de imágenes a Base64 en GoLang

¿Existe una "ley de rendimientos decrecientes" para convertir imágenes a Base64 en lugar de simplemente usar las imágenes en sí?

Las cadenas codificadas de 85 bits no se manejan correctamente al ser decodificadas en Python

Las texturas Three.js para imágenes en Google Colab no funcionan como se esperaba

Recupere y muestre imágenes en línea del correo electrónico cuando estén codificadas como CID con c #

No se pueden cargar imágenes en Firebase Cloud Storage

¿Método adecuado para convertir cadenas de imágenes base64 a binarias?

Convierta una serie Pandas con cadenas en una lista para crear variables codificadas

TOP Lista

CalienteEtiquetas

Archivo