ServeIt is an open source library that lets you easily serve model predictions and supplementary information from a RESTful API on any domain using your favorite Python ML library. This post illustrates the process of deploying a pre-trained ImageNet classifier with ServeIt to a new API. The classifier accepts an image URL as a parameter in a POST request and responds with the top predicted classes for that image.
You can interact with a live DenseNet121 demo server at https://imagenet-keras.ryanlee.site/predictions
(source code and request examples can be found here) or follow along below to start serving your own classifier.
Pre-trained DenseNet121 serving using ServeIt
Let’s start by installing the dependencies listed here (pip install -r requirements.txt
, in a virtual environment). After our dependencies are installed, we’ll load a DenseNet121 model that has been pre-trained for us on the ImageNet dataset:
1
2
3
4
from keras.applications import densenet
# load DenseNet121 model pre-trained on ImageNet
model = densenet.DenseNet121(weights='imagenet')
Next we define methods for loading and preprocessing an image from a URL…
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from keras.preprocessing import image
from flask import request
import requests
from serveit.utils import make_serializable, get_bytes_to_image_callback
# define a loader callback for the API to fetch the relevant data and
# preprocessor callbacks to map to a format expected by the model
def loader():
"""Load image from URL, and preprocess for DenseNet."""
url = request.args.get('url') # read image URL as a request URL param
return requests.get(url).content # return image as bytes
# get a bytes-to-image callback to resize image to 224x224
bytes_to_image = get_bytes_to_image_callback(image_dims=(224, 224))
# create a list of different preprocessors to chain multiple steps
preprocessor = [bytes_to_image, densenet.preprocess_input]
…and now we’re ready to start serving our image classifier:
1
2
3
4
5
6
7
8
9
from serveit.server import ModelServer
# initialize a ModelServer
server = ModelServer(
model=model, predict=model.predict, data_loader=loader,
preprocessor=preprocessor, postprocessor=densenet.decode_predictions)
# start serving
server.serve()
Behold:
1
2
curl -XPOST 'localhost:5000/predictions?url=https://images.pexels.com/photos/96938/pexels-photo-96938.jpeg'
# [[["n02123045", "tabby", 0.69397], ["n02123159", "tiger_cat", 0.14688], ["n02124075", "Egyptian_cat", 0.05430], ...]]
1
2
curl -XPOST 'localhost:5000/predictions?url=https://images.pexels.com/photos/67807/plane-aircraft-take-off-sky-67807.jpeg'
# [[["n02690373", "airliner", 0.60765], ["n04592741", "wing", 0.22114], ["n04552348", "warplane", 0.14071], ...]]
Additional examples can be found here. Happy serving!