Docker based Deployment of Machine Learning Model using Flask

Prerequisites

Photo by tylercaseyprodon on Unsplash

Overview

In a real-world setting, testing and training machine learning models is one phase of machine learning model development lifecycle. These models need to be deployed in real-world application to utilize it’s benefits. In this article I will discuss on how machine learning model can be deployed as a microservice in a plain Docker environment.

Now a days Kubernetes becoming more popular which act as a management layer for the Docker runtime. It provide necessary container management functionalities which suitable for production grade deployment. However choosing the deployment strategy is upto the organization that building the applications that utilize the machine learning models.

What is a microservice?

Couple of years ago, microservice became a buzzword in tech world which accompanied by rise of container technologies.

Prior to microservice architecture, applications built using monolothic architecture where every service sits in a single large application. This has it’s own pros and cons. Main issue of monolithic architecture is the scalability of single component without scaling whole application.

With the rise of containers, independence and scalability of single component became more easy and fundamental concept of application development.

Microservice can be defined as a small service unit of business functionality which are independent and communicate with other units across standard interfaces such as APIs and REST interfaces like HTTP.

What is a container?

A container is a standard unit of software that packages up code and all its dependencies, so the application runs quickly and reliably across diverse computing environments.

What is Docker?

Docker is a tool that is used to ease the deployment of the containers. Docker allow users to create, deploy and run services using containers. You might have worked with virtual machines. Docker is like a virtual machine, but it can share the underline operating system without need of all dedicated operating system.

Building the Maching Learning Model

In this blog, we are going to deploy the simple linear regression model (a Machine Learning Model).

Following are the steps that we will be going to perform in the blog:

Step-1: Exposing Model’s Functionality using Flask APIs

We’ll start with creating “app.py” module. In this module, we’ll be going to create Flask APIs to expose our model’s functionalities. Here, I’m assuming that you guys have basic understanding of Flask.

First, we are going to expose an “/LinearRegression/Train” API that will be used to train the model.

@app.route(‘/LinearRegression/Train’)def train():# Step 1 :: Prepossess the data# Reading the datasetprint(“Reading the Dataset”)dataset = pd.read_csv(‘height_and_weight_data.csv’)print(“Dataset contains {0} records”.format(dataset.count()))# Extracting height(independent variable) and weight(dependent variable)# from datasetprint(“Extracting height and weight from the dataset”)height = dataset.iloc[:, :-1].valuesweight = dataset.iloc[:, -1].values# Splitting dataset for training and testing purposesprint(“Splitting dataset for training and testing purposes”)from sklearn.model_selection import train_test_splitheight_train, height_test, weight_train, weight_test = train_test_split(height, weight, test_size=1 / 3,random_state=0)print(“Training dataset contains {0} records”.format(len(height_train)))print(“Test dataset contains {0} records”.format(len(height_test)))# Step 2 :: Training model on training setprint(“Fitting linear regression model to dataset”)from sklearn.linear_model import LinearRegressionlinear_regression = LinearRegression()linear_regression.fit(X=height_train, y=weight_train)with open(“linear_regression.pickle”,”wb”) as pickle_out:pickle.dump(linear_regression, pickle_out)return “Train Successfully”

When the “/LinearRegression/Train” API is invoked, it trains the model and save it in a file named as “linear_regression.pickle”.

Now, in order to make the predictions, we are going expose “/LinearRegression/Predict” API that will take height from the user and returns the predicted weight value.

@app.route(‘/LinearRegression/Predict’)def predict():height = request.args.get(‘height’)_input = np.array([height], dtype=float).reshape(-1, 1)with open(“linear_regression.pickle”, “rb”) as pickle_in:linear_regression = pickle.load(pickle_in)result = linear_regression.predict(_input)return “The predict weight against height {0} is {1}”.format(height, round(result[0], 2))

What the “/LinearRegression/Predict” API does is that it loads the trained model (from the file “linear_regression.pickle” created by the “/LinearRegression/Train” API) and use it to predict the weight.

Step-2: Creating the Dockerfile

After creating the flask app, the next step is to create the docker file. This will be used to build the docker image.

FROM python:3.7MAINTAINER Hemant Jain “jainhemant163@gmail.com”COPY ./requirements.txt /app/requirements.txtWORKDIR /appRUN pip install — upgrade pipRUN pip install -r requirements.txtCOPY . /appENTRYPOINT [ “python” ]CMD [ “app.py” ]

I’m using python 3.7 as base image. I’m specifying my contact information for the image maintainer. Then, I’m copying the requirements.txt into the working directory. After that setting the working directory. The next couple of commands are going to update the pip and then going to install all the requirements, respectively. Finally copying the content of the directory, containing the docker file, into the working directory. The last two commands are use to run the created Flask app.

Step-3: Building & Running the Docker Image

Uptill now, we have created Flask app that is going to expose our model’s functionalities and prepared a Dockerfile . The next step is to build the docker image from the docker file. To build the docker image run the following command in the CMD.

docker build -t linear_regression:1.0 .

To run above command, CMD should point to the directory where Dockerfile is present. After the command is executed, a docker image will get created.

Once you have build the docker container, you may decide to push it into a docker repository which you can pull from anywhere and run the application.

Finally, we are going to run the image using following command:

docker run -d -p 5000:5000 linear_regression:1.0

In this example, I assume you trying it in your environment. I’m starting the docker container using ‘docker run’ command and expose port 5000 to access our service.

Once the above command is executed our flask app will be available on http://localhost:5000/.

To train the model we’ll have to invoke the “/LinearRegression/Train” API as shown below:

To predict the weight for height equals to 2, invoke the “/LinearRegression/Predict” API as shown below:

Congratulations, we have successfully deployed our first Machine Learning Model using docker containers.

In a production grade deployment, you need to decide which python package going to act as the python HTTP server for your application. I prefer combination of NGINX, UWSGI and Flask for my deployment as NGINX can provide more functionalities for the server.

Useful Resources

[1] https://flask.palletsprojects.com/en/1.1.x/deploying/wsgi-standalone/

[2] https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-gunicorn-and-nginx-on-ubuntu-18-04

[3] Docker Installation for Windows Pro/Enterprise/Education: Follow Docker Desktop Installation guidelines https://docs.docker.com/docker-for-windows/

Done!

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Hemant Jain

Sr. SRE at Oracle, Ex-PayPal, Ex-RedHat. Professional Graduate Student interested in Cloud Computing and Advanced Big Data Processing and Optimization.