How to make predictions using a model that requires an input shape with more than two dimensions using MLflow?

雨燕双飞 提交于 2021-02-07 23:00:16

问题


I'm trying to implement a tensorflow (keras) based model into mlflow while learning how it works and if it suite our needs. I'm trying to implement the Fashion MNIST example from tensorflow website Here the link

I was able to train and to log the model successfully into mlflow using this code:

import mlflow
import mlflow.tensorflow
import mlflow.keras

# TensorFlow and tf.keras
import tensorflow as tf
from tensorflow import keras

# Helper libraries
import numpy as np
import matplotlib.pyplot as plt

print(tf.__version__)

fashion_mnist = keras.datasets.fashion_mnist

(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()

class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
           'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

train_images = train_images / 255.0

test_images = test_images / 255.0

model = keras.Sequential([
    keras.layers.Flatten(input_shape=(28, 28)),
    keras.layers.Dense(128, activation='relu'),
    keras.layers.Dense(10, activation='softmax')
])

model.compile(optimizer='adam',
          loss='sparse_categorical_crossentropy',
          metrics=['accuracy'])

if __name__ == "__main__":

    model.fit(train_images, train_labels, epochs=10)
    test_loss, test_acc = model.evaluate(test_images,  test_labels, verbose=2)
    print('\nTest accuracy:', test_acc)

    mlflow.log_metric("validation accuracy", float(test_acc))
    mlflow.log_metric("validation loss", float(test_loss))
    mlflow.keras.log_model(model, 
                        "model", 
                        registered_model_name = "Fashion MNIST")

Then I'm now serving it with the models serve subcommand

$ mlflow models serve -m [model_path_here] -p 1234

The problem is that I'm not able to make predictions:

fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
train_images = train_images / 255.0
test_images = test_images / 255.0
labels = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
           'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

url = "http://127.0.0.1:1234/invocations"

to_predict = test_images[0]

data = {
    "data": [to_predict.tolist()]
}
headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
r = requests.post(url, data=json.dumps(data), headers=headers)
res = r.json()

I'm getting this error:

{'error_code': 'BAD_REQUEST', 'message': 'Encountered an unexpected error while evaluating the model. Verify that the serialized input Dataframe is compatible with the model for inference.', 'stack_trace': 'Traceback (most recent call last):\n  File "/home/ferama/.local/lib/python3.6/site-packages/mlflow/pyfunc/scoring_server/__init__.py", line 196, in transformation\n    raw_predictions = model.predict(data)\n  File "/home/ferama/.local/lib/python3.6/site-packages/mlflow/keras.py", line 298, in predict\n    predicted = pd.DataFrame(self.keras_model.predict(dataframe))\n  File "/home/ferama/.local/lib/python3.6/site-packages/tensorflow_core/python/keras/engine/training.py", line 909, in predict\n    use_multiprocessing=use_multiprocessing)\n  File "/home/ferama/.local/lib/python3.6/site-packages/tensorflow_core/python/keras/engine/training_arrays.py", line 715, in predict\n    x, check_steps=True, steps_name=\'steps\', steps=steps)\n  File "/home/ferama/.local/lib/python3.6/site-packages/tensorflow_core/python/keras/engine/training.py", line 2472, in _standardize_user_data\n    exception_prefix=\'input\')\n  File "/home/ferama/.local/lib/python3.6/site-packages/tensorflow_core/python/keras/engine/training_utils.py", line 564, in standardize_input_data\n    \'with shape \' + str(data_shape))\nValueError: Error when checking input: expected flatten_input to have 3 dimensions, but got array with shape (1, 28)\n'}

That code above worked fine with a one dimension model

The error seems to me related to the fact that a pandas DataFrame is a two dimensional data structure and the model instead requires a three dimensional input.

The latest words from the error "...but got array with shape (1, 28)". The input shape should be (1, 28, 28) instead

There is a way to use this kind of models with mlflow? There is a way to serialize and send numpy arrays directly as input instead of pandas dataframes?


回答1:


Try to convert your input in base64

import base64

to_predict = test_images[0]
inputs = base64.b64encode(to_predict)

then convert it to Dataframe and send request

decode it back to original at backend by

np.frombuffer(base64.b64decode(encoded), np.uint8)


来源:https://stackoverflow.com/questions/58917918/how-to-make-predictions-using-a-model-that-requires-an-input-shape-with-more-tha

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!