Demystifying AI/ML Microservice With TensorFlow
By: Afzal Muhammad
Tags: Microservices, Kubernetes, Openshift, TensorFlow, Machine Learning

This tutorial will walk you through how to build and deploy a sample microservice application using the Red Hat OpenShift Container Platform. The scope of this service is to perform prediction of handwritten digit from 0 to 9 by accepting an image pixel array as a parameter. This sample application also provides an HTML file that offers you a canvas to draw your number and convert it into an image pixel array. The intention of this article is to give you a high-level idea, the same concept can be taken to the next level for addressing many other complex use cases.

Image recognition is one of the major capabilities of deep learning. In this article, we will be identifying our own handwritten digit. However, in order to accurately predict what digit is it, learning has to be performed, so that it understands the different characteristics of each digit as well as the subtle variations in writing the same digit. Thus, we need to train the model with a dataset of labelled handwritten digit. This is where MNIST dataset comes handy.

Sample dataset

MNIST dataset is comprised of 60,000 small 28x28 square pixel gray scale images and 10,000 test images. These are handwritten single digit images from 0 to 9. Instead of downloading it manually, we can download it using Tensorflow Keras API

We will be performing following steps in this exercise

Build and train the model using MNIST dataset Saving the learned model in persistent storage Build and launch microservice for prediction using the provided dockerfile Generate image pixel array of your handwritten digit using the provided HTML file Perform prediction using microservice by providing image pixel array as a parameter to this service.

You can find the dockerfile and python code by clicking the following git repository.

https://github.com/mafzal786/tensorflow-microservice.git

Model Training

Below is the python code that performs building, compiling, training, and saving the model based on MNIST dataset. This code can also be executed in Jupyter Notebook. It is important to save this model in a persistent storage once the model training is successsfully completed so that it can be used by the microservice application for prediction. Also make sure that saved model file should be accessible by the container running the microservice.

Prediction microservice with Flask

Following instructions will help you building the microservice using Red Hat OpenShift Container Platform. For the sake of simplicity, it’s a single source file and written in python. This source file is copied inside the container image via Dockerfile during the container image build process, which will be discussed later in this article. The sole purposes of this microservice to is to predict the handwritten digit using the already learned model. It simply takes the image pixel array as a parameter and predict it.

Dockerfile

Below is the dockerfile that will be used to initiate the image build and launch the container in OpenShift platform. requirements.txt file contains the pre-requisite packages for this microservice to work. requirements.txt file contains the following.

Flask==0.12.1 tensorflow==2.3.0 scikit-learn==0.22.1

Launch the microservice

Now login to your Red Hat OpenShift cluster. Click Developer and then click Add to create an application. Click “From Dockerfile”. This will import your dockerfile from your git repo and initiate the image build and deploy the container.

Supply the Git Repo URL. The dockerfile for this project is located at https://github.com/mafzal786/tensorflow-microservice.git. Also give name to your application. Click create.

This will create the build config and build will start. To view the logs for your build, click “Builds” under Administrator tab and click the build as shown below. Once the build is completed, container image is pushed to your configured image registry.

After the build is completed and image is pushed to the registry, OpenShift will launch the container.

OpenShift will create a route for this service to be exposed by giving an externally reachable hostname. Service end point will be available in Networking →Routes tab. Clicking on the Location as shown below will launch the microservice in the browser.

Below figure shows when microservice is launched in the browser.

Or run the following CLI as below

# oc get routes/ms-handwritten-digit-prediction-git

Canvas for writing digit

Below html file offers you a canvas to draw digit. Copy below code and save it as html on your computer and then launch it in the browser. Click “Convert” button to convert the image into image pixel array. Then click “Copy Image Pixel Array in Clipboard” button to copy the pixel array in your clipboard for providing it to the microservice as a parameter for prediction.

Draw Your Number

Perform prediction using the microservice

Now pass this image pixel array to the microservice as a parameter as show below.



<h1>Your handwritten digit is: 3</h1> # curl http://`oc get routes/ms-handwritten-digit-prediction-git — template=’{{.spec.host}}’`/predict?pixelarray=0,0,0,0,0,0,0.03137254901960784,0.5764705882352941,1,1,1,1,1,1,0.17254901960784313,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.011764705882352941,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0.984313725490196,0.07450980392156863,0,0,0,0,0,0,0,0,0,0,1,1,1,0.6196078431372549,0,0,0,0,0,0,0,0,0,0,0,0.8980392156862745,1,1,1,1,0,0,0,0,0,0,0,0,0.48627450980392156,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0.8470588235294118,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.0784313725490196,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.07058823529411765,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.7098039215686275,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.7568627450980392,1,0.7843137254901961,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0.3176470588235294,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.4470588235294118,1,1,1,0,0,0,0,0,0,0,0,0,0.8980392156862745,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0.03137254901960784,0,0,0,0,0,0,0,0,0,0,0,0,0,0.06274509803921569,0.07058823529411765,0.07058823529411765,0.803921568627451,1,1,0.8941176470588236,0.07058823529411765,0.06666666666666667,0,0,0,0.0392156862745098,1,1,1,0.5098039215686274,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.9254901960784314,1,0.6901960784313725,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.5254901960784314,1,0.07450980392156863,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0.9254901960784314,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.3803921568627451,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0.24705882352941178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.34509803921568627,1,0,0,0,0,0,0.9803921568627451,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0.3686274509803922,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0.9882352941176471,1,1,1,1,0.6784313725490196,0.08235294117647059,0,0,0,0,0,0.4235294117647059,1,1,1,1,1,1,1,0.3333333333333333,0,0,0,0,0,0,0,0,0,0.10588235294117647,0.8117647058823529,1,1,1,1,1,1,1,1,1,1,1,1,0.21568627450980393,0.12941176470588237,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Your handwritten digit is: 3

You can run the same in the browser as follows.