Как получить прогнозы gcloud, передав изображение base64 в начальную модель переподготовки?

Я пытаюсь получить прогноз с помощью gcloud, передав кодированное в base64 изображение в начальную модель переподготовки, используя подход, подобный тому, который был принят Davide Biraghi в этом посте. Когда используешь 'DecodeJpeg/contents:0' в качестве входных данных я также получаю ту же ошибку при попытке получить прогнозы, поэтому я принял несколько иной подход.

Следуя rhaertel80 в его ответе на этот пост, я создал график, который принимает изображение JPEG в качестве входных данных в 'B64Connector/input', предварительно обработать его и передать в начальную модель в 'ResizeBilinear:0',

Прогноз возвращает значения, хотя и неправильные (я пытаюсь найти решение в другом посте), но, по крайней мере, это не сбои. Заполнитель, который я использую в качестве ввода

images_placeholder = tf.placeholder(dtype=tf.string, shape=(None,), name='B64Connector/input')

И я добавляю его к входам модели с

inputs = {"b64_bytes": 'B64Connector/input:0'}
tf.add_to_collection("inputs", json.dumps(inputs))

Как Давид, я следую предложениям, найденным в этих постах: здесь, здесь и здесь, и я пытаюсь получить прогнозы с

    gcloud beta ml predict --json-instances=request.json --model=MODEL

где файл request.json был получен с этим кодом

jpgtxt = base64.b64encode(open(imagefile ,"rb").read())

with open( outputfile, 'w' ) as f :
  f.write( json.dumps( {"b64_bytes": {"b64": jpgtxt}} ) )

Я хотел бы знать, почему прогноз не работает, когда я использую в качестве входных данных 'DecodeJpeg/contents:0' и это не так, когда я использую этот другой подход, так как они выглядят почти идентично мне: я использую один и тот же сценарий для генерации экземпляров (изменение input_key) и одну и ту же командную строку для запроса прогнозов

Есть ли способ передать инстанс на фид 'B64Connector/input:0' в 'DecodeJpeg/contents:0' для того, чтобы получить правильные прогнозы?

1 ответ

Здесь я опишу более подробно мой подход и как я использую images_placeholder.

Я определяю функцию, которая изменяет размер изображения:

  def decode_and_resize(image_str_tensor):
    """Decodes jpeg string, resizes it and returns a uint8 tensor."""

    image = tf.image.decode_jpeg(image_str_tensor, channels=MODEL_INPUT_DEPTH)

    # 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, [MODEL_INPUT_HEIGHT, MODEL_INPUT_WIDTH], align_corners=False)
    image = tf.squeeze(image, squeeze_dims=[0])
    image = tf.cast(image, dtype=tf.uint8)
    return image

и тот, который генерирует определение графа, в котором происходит изменение размера и где images_placeholder определяется и используется

def create_b64_graph() :
  with tf.Graph().as_default() as b64_graph:

    images_placeholder = tf.placeholder(dtype=tf.string, shape=(None,),
                                     name='B64Connector/input')
    decoded_images = tf.map_fn(
        decode_and_resize, images_placeholder, back_prop=False, dtype=tf.uint8)

    # convert_image_dtype, also scales [0, uint8_max] -> [0, 1).
    images = tf.image.convert_image_dtype(decoded_images, dtype=tf.float32)

    # Finally, rescale to [-1,1] instead of [0, 1)
    images = tf.sub(images, 0.5)
    images = tf.mul(images, 2.0)

    # NOTE: using identity to get a known name for the output tensor.
    output = tf.identity(images, name='B64Connector/output')

    b64_graph_def = b64_graph.as_graph_def()

    return b64_graph_def

Кроме того, я использую следующий код для объединения графа изменения размеров с начальным графом. Могу ли я использовать аналогичный подход для ссылки images_placeholder прямо к 'DecodeJpeg/contents:0'?

def concatenate_to_inception_graph( b64_graph_def ):

  model_dir = INPUT_MODEL_PATH
  model_filename = os.path.join(
       model_dir, 'classify_image_graph_def.pb')

  with tf.Session() as sess:

    # Import the b64_graph and get its output tensor
    resized_b64_tensor, = (tf.import_graph_def(b64_graph_def, name='',
                             return_elements=['B64Connector/output:0']))

    with gfile.FastGFile(model_filename, 'rb') as f:
      inception_graph_def = tf.GraphDef()
      inception_graph_def.ParseFromString(f.read())

      # Concatenate b64_graph and inception_graph
      g_1 = tf.import_graph_def(inception_graph_def, name='inception',
               input_map={'ResizeBilinear:0' : resized_b64_tensor} )

    return sess.graph
Другие вопросы по тегам