DEV Community

Cover image for How to Build and Deploy a Machine Learning model using Docker
Bravin Wasike
Bravin Wasike

Posted on • Originally published at section.io

How to Build and Deploy a Machine Learning model using Docker

Docker is a virtualization platform that is designed to create, run, and deploy applications through the use of containers. We will use Docker to deploy a simple machine learning app built using Streamlit.

In this tutorial, we will first create a simple machine learning model, save it into a pickle file to be loaded into our platform, and create its interface using Streamlit. After creating the Streamlit app, we shall use docker to deploy it.

Table of contents

Prerequisites

  1. A good understanding of Python.
  2. Good working knowledge of machine learning models.

Building a simple machine learning model

Let's start by building a simple machine learning prediction model. We will build a machine learning model to predict the gender of a person based on the user's input.

Dataset

We will use a dataset of names commonly used by people.
The format of our data used is as shown:

Image description

CSV File

Installation of the required packages

We need the following packages:

  1. Sckit-learn
  2. Pandas
  3. Numpy

The following command is used to install the packages above.

pip install sklearn
pip install pandas
pip install numpy
Enter fullscreen mode Exit fullscreen mode

Importing Panda and Numpy

import pandas as pd
import numpy as np
Enter fullscreen mode Exit fullscreen mode

Importing from sckitlearn

import CountVectorizer from sklearn.feature_extraction.text
import DictVectorizer from sklearn.feature_extraction
Enter fullscreen mode Exit fullscreen mode
df = pd.read_csv('dataset.csv')
Enter fullscreen mode Exit fullscreen mode
df.size
df.dtypes
Enter fullscreen mode Exit fullscreen mode

Checking for missing values

We need to ensure that there are no missing values in our dataset. This provides well structured data that will optimize on training our model.

df.isnull().isnull().sum()
Enter fullscreen mode Exit fullscreen mode

Checking for number of male and female

Here, we look for the total number of male and female in our dataset.

df[df.sex == 'F'].size
df[df.sex == 'M'].size
df_names = df
Enter fullscreen mode Exit fullscreen mode

Replacing the data F and M with 0 and 1

This is done so as to provide a binary output of either 0 or 1, 0 to represent female, 1 to represent male.

df_names.sex.replace({'F':0,'M':1},inplace=True)
Xfeatures =df_names['name']
Enter fullscreen mode Exit fullscreen mode

Feature extraction

cv = CountVectorizer()
X = cv.fit_transform(Xfeatures)
Enter fullscreen mode Exit fullscreen mode

Processing of model

import train_test_split from sklearn.model_selection

Enter fullscreen mode Exit fullscreen mode

Features and labels

After identifying our features and labels to be used in training the model, we can split our data set into two:

  1. Training set: This will be 75% of the data.
  2. Test Set: This will be 25% of the data.
X
y = df_names.sex
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25)
Enter fullscreen mode Exit fullscreen mode

Creating the naive bayes classifier model

We import Naive Bayes Classifier algorithm from the scikit-learn package. The model will be used to fit and train our model.

import MultinomialNB from sklearn.naive_bayes
clf = MultinomialNB()
clf.fit(X_train,y_train)
clf.score(X_test,y_test)
Enter fullscreen mode Exit fullscreen mode

Making predictions

We will use a function named predict that will be used to predict the gender of a person based on the name provided.

def predict(a):
    test_name = [a]
    vector = cv.transform(test_name).toarray()
    if clf.predict(vector) == 0:
        print("Female")
    else:
        print("Male")
Enter fullscreen mode Exit fullscreen mode

Saving the model into a pickle file

We shall save our model using Joblib. We shall accomplish this by converting our model into a byte stream which will be saved into a pickle file named 'naivemodel.pkl'.

import joblib from sklearn.externals
naiveBayesModel = open("model/naivemodel.pkl","wb")
joblib.dump(clf,naiveBayesModel)
naiveBayesModel.close()
Enter fullscreen mode Exit fullscreen mode

Introduction to Streamlit

Streamlit is a framework that is used by different machine learning engineers and data scientists to build UIs and powerful machine learning apps from a trained model.

These apps can be used for visualization by providing interactive interfaces for the user.

They provide an easier way to build charts, tables, and different figures to meet your application's needs. They also utilize the models that have been saved or picked into the app to make a prediction.

How to install streamlit

Use the following command:

pip install streamlit

Enter fullscreen mode Exit fullscreen mode

Let's build the streamlit app

  1. Create a new Python file named app.py.
  2. Add our pickled model into a created folder called 'model'.

Our folder structure should look like this.

├── app.py
├── model
   ├── naivebayesgendermodel.pkl

Enter fullscreen mode Exit fullscreen mode
  1. Import required packages.
import streamlit as st

from sklearn.externals import joblib
import time
from PIL import Image
Enter fullscreen mode Exit fullscreen mode
  1. Unplick the model.

This will help to load our model so that it can be used for gender prediction. Here, the byte stream from the 'naivemodel.pkl' file is converted into an object hierarchy so that it can be used by the streamlit app.

gender_nv_model = open("models/naivemodel.pkl","rb")
gender_clf = joblib.load(gender_nv_model)

Enter fullscreen mode Exit fullscreen mode
  1. Building our prediction logic.
def predict_gender(data):
  vect = gender_cv.transform(data).toarray()
  result = gender_clf.predict(vect)
  return result
Enter fullscreen mode Exit fullscreen mode
  1. Styling the app We will use material UI for styles and icons for our app.
def load_css(file_name):
    with open(file_name) as f:
        st.markdown('<style>{}</style>'.format(f.read()), unsafe_allow_html=True)

def load_icon(icon_name):
    st.markdown('<i class="material-icons">{}</i>'.format(icon_name), unsafe_allow_html=True)
Enter fullscreen mode Exit fullscreen mode
  1. Adding an image
def load_images(file_name):
  img = Image.open(file_name)
  return st.image(img,width=300)
Enter fullscreen mode Exit fullscreen mode

Your file structure should be as shown:

├── male.png
├── female.png
├── model
   ├── nainvemodel.pkl

Enter fullscreen mode Exit fullscreen mode

Designing the user interface

This is where we use different tools from streamlit to design a nice UI.

def main():
  """Gender Classifier App
    With Streamlit
  """

  st.title("Gender Classifier")
  html_temp = """
  <div style="background-color:blue;padding:10px">
  <h2 style="color:grey;text-align:center;">Streamlit App </h2>
  </div>
  """
  st.markdown(html_temp,unsafe_allow_html=True)
  load_css('icon.css')
  load_icon('people')

  name = st.text_input("Enter Name","Pleas Type Here")
  if st.button("Predict"):
    result = predict_gender([name])
    if result[0] == 0:
      prediction = 'Female'
      img = 'female.png'
    else:
      result[0] == 1
      prediction = 'Male'
      img = 'male.png'

    st.success('Name: {} was classified as {}'.format(name.title(),prediction))
    load_images(img)
Enter fullscreen mode Exit fullscreen mode

The code is explained below:

  • Adding the apps title.
  • Styling our app by adding the app's background color, text color, and the general structure of our app.
  • Adding a text input area where a user can key in a name to be predicted as either male or female.
  • Adding a button that a user can use to submit the input.

We set the following styles on our app:

Background-color: blue
Text color: grey,
Padding: 10px,
App Title: Gender Classifier App
Enter fullscreen mode Exit fullscreen mode

We then run our app using this command.

streamlit run app.py
Enter fullscreen mode Exit fullscreen mode

Our user interface is as shown below.

  1. A prediction where the output is male.

Image description

  1. Prediction where the output is female

Image description

Dockerizing the streamlit app

  1. Let's create a Docker file.
  • In the working root directory, let's create a file named 'Dockerfile' without any extensions.

  • Your file structure should be as shown.

├── Dockerfile
├── male.png
├── female.png
├── model
   ├── nainvemodel.pkl

Enter fullscreen mode Exit fullscreen mode
  1. Docker Layers
  • Firstly we define our base image where we want to build our file from, as demostrated below.
FROM python:3.7
Enter fullscreen mode Exit fullscreen mode
  • Here we will use the official Python imge from Docker.

  • Create a working directory as shown.

WORKDIR /app
Enter fullscreen mode Exit fullscreen mode
  • Copy all the requirements into the new directory created.
COPY requirements.txt ./requirements.txt
Enter fullscreen mode Exit fullscreen mode
  • Copying from the source to the destination.

  • Install all that is in the requirments.txt file.

RUN pip install -r requiremts.txt
Enter fullscreen mode Exit fullscreen mode
  • Expose the port to be used to run the application.
EXPOSE 8501
Enter fullscreen mode Exit fullscreen mode
  • This is the same port that our streamlit app was running on.

  • Copy our app from the current directory to the working area.

COPY ./app
Enter fullscreen mode Exit fullscreen mode
  • Create an entry point to make our image executable.
ENTRYPOINT ["streamlit", "run"]
CMD ["app.py"]
Enter fullscreen mode Exit fullscreen mode
  1. Building a Docker image
  • We build using the following command then "." to run the current directory.
docker build -t streamlitapp:latest .
Enter fullscreen mode Exit fullscreen mode
  • You can also use the following command to specify the file.
docker build -t streamlitapp:latest .f Dockerfile
Enter fullscreen mode Exit fullscreen mode
  • The output will be as shown below.
Sending building context to the Docker daemon  34.90kb
Step 1/8 : FROM python:3.8
  --->d6568b1g3y4h
Step 2/8 : WORKDIR /app
  --->Using Cache
  --->25cyf5dfpbfd
Step 3/8 : COPY requirements.txt ./requirements.txt
    --->Using Cache
    --->52jdf5dffbfd
Step 4/8 : RUN pip install -r requiremts.txt
    --->Using Cache
    --->81cdf5dffedf
Step 5/8 : EXPOSE 8501
    --->Using Cache
    --->62d29afd9eb
Step 6/8 : COPY ./app
    --->9rraeb07t4d
Step 6/8 : EXPOSE 8501
    --->4b2ap4h557cc
Step 7/8 : ENTRYPOINT ["streamlit", "run"]
    --->2egaeb07tdte
Removing intermediate container 5ta3824edte
 ---> 65dv092efstfu
step 8/8 : CMD ["app.py"]
Successfully built 65dv092efstfu
Successfully tagged streamlitapp:latest
Enter fullscreen mode Exit fullscreen mode
  • Use the following command to view all your images.
docker image ls
Enter fullscreen mode Exit fullscreen mode
  • Output is as shown.
REPOSITORY                   TAG                 IMAGE ID            CREATED             SIZE
streamlitapp                 latest             65dv092efstfu        2 minutes ago       1.24GB
testapp                      latest             d660b1f1t3e         1 weeks ago          794MB
Enter fullscreen mode Exit fullscreen mode
  1. Creating a container
docker run -p 8501:8501 streamlitapp:latest
Enter fullscreen mode Exit fullscreen mode

Result:

gv092e0ff6btdte593a7dad8e50ef01f7t3e89fy41816624gdted7fu1h1bid1o
Enter fullscreen mode Exit fullscreen mode

It also starts our streamlit app in the following urls:

  1. Network URL: http://172.17.0.2.8501
  2. External URL: https://193.106.63.249:8501

With that, the Streamlit app is now deployed with docker.

Conclusion

In this tutorial, we have learned how to create a simple machine learning model, how to create a steamlit app using the model and finally used Docker to run the app.

We first began by building a gender classification model using our machine learning model. After building the model we designed a user interface using streamlit. Streamlit is a good library used by most developers when building machine learning apps within a short time frame.

Streamlit designs a user interface that the end-user can use to make a prediction of gender based on the name the user has provided.

After we made sure that our streamlit app was fully functional, we finally deployed to docker by creating a docker image.
We then used that image to create a docker container, and finally run our app.

By using these steps, a reader should be able to comfortably deploy a streamlit app using Docker.

Happy coding!

References

Top comments (0)