1

I am having a problem trying to invoke via HTTP rest request an online Prediction to a deployed model on Google AI Platform. I get the following error regardless of how I package the data. The error is:

 Expected float32, got *******

I have confirmed the Google Credentials work and I can perform a query from my Android App to get information about the model and that is successful.

The issue I believe is with formatting of the data. I have followed the instructions at https://cloud.google.com/ml-engine/docs/online-predict and also at https://cloud.google.com/ml-engine/docs/v1/predict-request. I have tried to send various versions like

{"instances": [xxx]} where have formatted xxx in many different ways.

It should take as input a 3D array -basically the input to the model is a 150x150x3 array where each pixel has a value from 0 to 1.0 (float). Because the model wants a float input I can not convert the original 150x150x3 pixel values to base64. So, I am using the explanation at the link above for sending in a 3D array. I have tried so many different ways and do not know what to do at this point. Here is an image showing the 3D string array representing the scaled input input the model needs

enter image description here

Note: I am reading the data in from a JSON file -the same one I use below in a command line successful gcloud call to perform prediction. Here is an image illustrating the contents.

enter image description here

Note: I am able to do this on the command line using gcloud as shown here enter image description here

gogasca
  • 9,283
  • 6
  • 80
  • 125

1 Answers1

0

This is a common problem:

There is a slight difference between the format required for gcloud and the body of the HTTP requests sent to the service. We understand it is confusing and we will work towards addressing the confusion in the future. Here's a brief explanation to help you get started.

The body of the request sent to the API has the form:

{"instances": [<instance 1>, <instance 2>, ...]}

The file used in gcloud is simply a newline-separated list of instances:

<instance 1>
<instance 2>

I looked at your file, I have 2 recommendations:

a) Since it works fine using gcloud command, I would use AI Platform UI to test your JSON input similar as the API will use.

enter image description here

Note: Use test after you copy and paste the input

As specified in documentation we need something like this:

{
    "instances": [
        <object>
        ...
    ]
}

In this case you have

{ 
    "conv2d_input": [
         <object>
     ...
    ]
}

b) You need to replace conv2d_input to instances and add extra []: I tested your input with a model of my own and works fine.

{  
    "instances": 
     [
       [[[0.23137255012989044, 0.27450981736183167, 0.250980406999588], 
       ...
       ,[0.2980392277240753, 0.43529412150382996, 0.2078431397676468]]]
     ]
}

I use this code normally:

import numpy as np
import json
from PIL import Image

INPUT_FILE = 'image.jpg'
OUTPUT_FILE = 'image_array.json'

def convert_to_json(image_file):
 """Open image, convert it to numpy and create JSON request"""
 img = Image.open(image_file).resize((224, 224))
 img_array = np.array(img)
 predict_request = {"instances": [img_array.tolist()]}
 with open(OUTPUT_FILE, 'w') as output_file:
   json.dump(predict_request, output_file)
 return predict_request

prediction_data = convert_to_json(INPUT_FILE)
gogasca
  • 9,283
  • 6
  • 80
  • 125