Tales of a machine learning startup

Vincent Roy
7 min readDec 13, 2019

--

How to build and deploy a diabetes diagnostic app from A to Z using Tensorflow, Google Cloud Platform and Flask

Let’s pretend for a minute that we are part a of bright new machine learning startup called ACME Learning Co. Furthermore, imagine that your team has landed a gig to build a machine learning app for the Canadian Diabetes Association. Your team is excited at the thought of giving actual gifts instead of stock options for Christmas this year. Then reality sets in, how the heck are we to pull this off!!!

As the CTO of the startup, you call an emergency meeting to explain the project goal. Your team must develop a web app that will assist doctors predict a diabetes diagnostic for female patient based on medical lab results.

Mike the data science guru asks, ‘do we have any data’. You tell Mike, ‘Keep calm, we are in luck, our contractor is providing us access to their entire research database’. The relief on Mike’s face is noticeable, ‘with quality data I can easily build a dense neural network using Tensorflow’.

Then, Kim our applications engineer, suggests that what would be really cool is if the doctors could type in the lab results of a patient and get and immediate diagnostic prediction whether or not the patient is diabetic via a web app. Kim confidently explains how with Flask we can easily build a simple web app.

Seem like your team has a plan, build a dense neural network model and then display the prediction via a Flask web app. Then just as the team is about to adjourn and start working on the project, John the architect of the team (alias party pooper), slams the door of the meeting room before anybody can leave and says, ‘Did you guys think of how you are going to deploy the model’. Grunts and sighs can be heard from the team members, since everybody knows that deploy and serving the results of a model is no fun in the park.

Then from the back of the room, in a stuttering voice, Keisha the machine leaning engineer intern says ‘How about using GCP’. I ask her to speak up and explain her self. In a more affirmative voice she tells us about the Google Computing Platform deployment mechanism and API that her classmates are using to deploy working models. It’s at this point that the team realizes that they have all the pieces of the puzzle to create the app.

The following sections highlights how the team put together the machine learning app.

Step 1 : Building the Keras Tensorflow model

Mike, our data science guru, explains that the problem at hand is a binary classification problem. We are given the lab results of 768 patients (Glucose, BMI, Insulin, etc) and the evaluation of medical experts on weather or not a patient has diabetes.

Horizontal axis blood Glucose level, vertical axis age segments, and red points indicated diabetes result

To build the prediction model we will use a shallow dense neural network architecture with 8 input nodes, 12 nodes for the first layer, 8 nodes for the middle layer, and one node for the output with a sigmoid activation function. A better performing model could be obtained with a more sophisticated architecture, however this is not the purpose of this article.

Architecture of the dense ANN

The following code highlights the model development using Keras and Tensorflow. The complete code can be obtained on the project github

# create the model
inputs = keras.Input(shape=(8,))
hidden1 = Dense(12,activation='relu')(inputs)
hidden2 = Dense(8,activation='relu',)(hidden1)
output = Dense(1,activation='sigmoid')(hidden2)
model = keras.Model(inputs,output)
# summary to verify the structure
model.summary()
# compile the keras model
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
# train the model on the training data
history = model.fit(X_train,y_train,epochs=100,batch_size=16,verbose=0)
Loss and accuracy for 100 epochs of training

For a basic ANN architecture the results are acceptable. Since the purpose of this article is not to tune the model and evaluate the performance,we will leave it at that.

Step 2 : Deploying the model on Google cloud platform (GCP)

As suggested by Keisha the intern, the team has opted here to deploy the model to the GCP platform since they can effortlessly put the model into prediction without worrying about managing issues (scaling, model versioning, etc.). GCP allows machine learning model developers to train and deploy their prediction models easily as well as manage model versions. The models are accessible via REST API, hence prediction calculations can easily be integrated in a web applications. Furthermore, the GCP infrastructure will take care of performance issues, one less thing to worry about.

To deploy your model programmatically on GCP one needs to :

  • Create an account on GCP
  • Download the GCP software development kit (SDK)

The following code shows how to programmatically deploy your model using python step by step.

A — Create a bucket on GCP and transfer the model

# set the variables for the gcp ai platform
PROJECT_ID = 'your_project_name'
# name of the bucket the will contain the model as well as the region. This must absolutely be a GLOBALLY UNIQUE name
BUCKET_NAME = 'pima_bucket'
REGION = "us-central1"
# set the project
! gcloud config set project $PROJECT_ID
! echo $PROJECT_ID
# used if we need to create a new bucket
! gsutil mb -l $REGION gs://$BUCKET_NAME
# used to copy the tensorflow model into the bucket
!gsutil cp -r {model_name} gs://{BUCKET_NAME}

B — Create a model and a version in the GCP AI

# variable for the model creation 
MODEL_NAME = "my_pima_model2"
MODEL_VERSION = "v0001"
MODEL_VERSION_NUM = '0001'
# create the model in the AI plateform
! gcloud ai-platform models create $MODEL_NAME --regions $REGION
# create a version of the model
! gcloud ai-platform versions create {MODEL_VERSION} \
--model {MODEL_NAME} \
--runtime-version 1.13 \
--python-version 3.5 \
--framework tensorflow \
--origin gs://{BUCKET_NAME}/{model_name}/{model_version}/

C — Make a prediction using the GCP REST API

# create the resource to the model web api
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "sapient-pen-260901-dc0c62411b24.json"
project_id = 'sapient-pen-260901'
model_id = MODEL_NAME
model_path = "projects/{}/models/{}".format(project_id, model_id)
model_path += "/versions/v0001/" # if you want to run a specific version
ml_resource = googleapiclient.discovery.build("ml", "v1").projects()
# function use to request a prediction from the web api of the model # and get a reponse of the predctions
def predict(X):
input_data_json = {"signature_name": "serving_default",
"instances": X.tolist()}
request = ml_resource.predict(name=model_path, body=input_data_json)
response = request.execute()
if "error" in response:
raise RuntimeError(response["error"])
return np.array([pred['dense_5'] for pred in response["predictions"]])

Step 3 : Build the Flask web app

The last part of the project that the team had to build was the web app that will allow medical practitioners to enter medical data for a patient and get a diagnostic result.

The team has decided to build a Minimal viable product (MVP) using Flask to show to their clients, before developing a web app with all the bells and whistles.

The complete code for the web app can be found on the project github. The following section highlights the important code sections.

from flask import render_template
from app import app
from app.forms import LabForm

from flask import render_template, flash, redirect

import numpy as np
import pandas as pd

from sklearn.preprocessing import MinMaxScaler
import googleapiclient.discovery

import sys
import os


@app.route('/')
@app.route('/index')
def index():

return render_template('index.html')


@app.route('/prediction', methods=['GET', 'POST'])
def lab():
form = LabForm()

if form.validate_on_submit():

# get the dorm data for the patient data and put into a form for the
X_test = np.array([[float(form.preg.data),float(form.glucose.data),float(form.blood.data),float(form.skin.data),float(form.insulin.data),float(form.bmi.data),float(form.dpf.data),float(form.age.data)]])
print(X_test.shape)
print(X_test)

# in order to make a prediction we must scale the data using the same scale as the one used to make
# model

# get the data for the diabetes data.
data = pd.read_csv('./diabetes.csv', sep=',')

# extract the X and y from the imported data
X = data.values[:, 0:8]
y = data.values[:, 8]

# use MinMaxScaler to fit a scaler object
scaler = MinMaxScaler()
scaler.fit(X)

# min max scale the data for the prediction
X_test = scaler.transform(X_test)

# create the resource to the model web api on GCP
MODEL_NAME = "my_pima_model2"
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "sapient-pen-260901-dc0c62411b24.json"
project_id = 'sapient-pen-260901'
model_id = MODEL_NAME
model_path = "projects/{}/models/{}".format(project_id, model_id)
model_path += "/versions/v0001/" # if you want to run a specific version
ml_resource = googleapiclient.discovery.build("ml", "v1").projects()


# format the data as a json to send to the web api
input_data_json = {"signature_name": "serving_default",
"instances": X_test.tolist()}
# make the prediction
request = ml_resource.predict(name=model_path, body=input_data_json)
response = request.execute()
if "error" in response:
raise RuntimeError(response["error"])

# extract the prediction from the response
predD = np.array([pred['dense_5'] for pred in response["predictions"]])
print(predD[0][0])
res = predD[0][0]

return render_template('result.html',res=res)

return render_template('prediction.html', form=form)
Data entry screen of the Flask web app
Result screen

Conclusion

So there you have it, the complete machine learning app from A to Z. Yes I know what you are saying, it’s a prototype app, but it will enable the client to see exactly where you are going, what is possible and evaluate the costs and time line to get the product out the door.

The team is happy, they have landed there first client and delivered a working prototype. The client is excited and Mike is already on Amazon buying gifts for the little ones.

--

--