Skip to content

Instantly share code, notes, and snippets.

@nvg
Created May 21, 2021 02:40
Show Gist options
  • Select an option

  • Save nvg/16b5bc144d20bc6c3c478178879705b6 to your computer and use it in GitHub Desktop.

Select an option

Save nvg/16b5bc144d20bc6c3c478178879705b6 to your computer and use it in GitHub Desktop.
Sample Python Server
import io
import flask
import keras.applications
import numpy as np
from PIL import Image
from keras.layers import Input
from keras.layers.core import Dense
from keras.models import Model
from skimage.transform import resize
# initialize our Flask application and the Keras model
app = flask.Flask(__name__)
model = None
class_names = ['Atelectasis', 'Cardiomegaly', 'Effusion', 'Infiltration', 'Mass', 'Nodule', 'Pneumonia',
'Pneumothorax', 'Consolidation', 'Edema', 'Emphysema', 'Fibrosis', 'Pleural_Thickening', 'Hernia']
def load_model():
"""
Initializes the model and loads the weights
"""
global model
input_shape = (224, 224, 3)
img_input = Input(shape=input_shape)
x = keras.applications.DenseNet121(
include_top=False,
input_tensor=img_input,
input_shape=input_shape,
weights=None,
pooling="avg").output
predictions = Dense(len(class_names), activation="sigmoid", name="predictions")(x)
model = Model(inputs=img_input, outputs=predictions)
model.load_weights("./weights.h5")
return model
def prepare_image(image, target):
"""
Prepares the image by converting to RGB, normalizing to grayscale and resizing to the target dimensions
@param image image image to prepare
@param target target dimension of the image
@return string formatted string
"""
if image.mode != "RGB":
image = image.convert("RGB")
image_array = np.asarray(image)
image_array = image_array / 255.
image_array = resize(image_array, target)
image_array = np.asarray([image_array])
imagenet_mean = np.array([0.485, 0.456, 0.406])
imagenet_std = np.array([0.229, 0.224, 0.225])
image_array = (image_array - imagenet_mean) / imagenet_std
return image_array
@app.route("/predict", methods=["POST"])
def predict():
# initialize the data dictionary that will be returned from the
# view
data = {"success": False}
# ensure an image was properly uploaded to our endpoint
if flask.request.method != "POST":
return flask.jsonify({"success": False, "message": f"Method ${flask.request.method} is not allowed"})
image_request_param = flask.request.files.get("image")
if image_request_param is None:
return flask.jsonify({"success": False, "message": "Unable to find 'image' parameter"})
# read the image in PIL format
image = flask.request.files["image"].read()
image = Image.open(io.BytesIO(image))
# preprocess the image and prepare it for classification
image = prepare_image(image, target=(224, 224))
# classify the input image and then initialize the list
# of predictions to return to the client
predictions = model.predict(image)
data["predictions"] = []
# loop over the results and add them to the list of
# returned predictions
for i in range(len(class_names)):
r = {"label": class_names[i], "probability": round(float(predictions[0][i]), 3)}
data["predictions"].append(r)
# indicate that the request was a success
data["success"] = True
# return the data dictionary as a JSON response
return flask.jsonify(data)
if __name__ == "__main__":
load_model()
# Keras throws strange errors in a multi-threaded environment
app.run(threaded=False)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment