Building Digit prediction web application using TensorFlow with Keras and Flask

Image result for flask tensorflow

This post will give you an idea about how to build a web application which predicts digit in the image uploaded.

We are going to use the model which we have already for predicting digits which was trained on MNIST data. If you don’t know how to build a model with MNIST data please read my previous article.

Sometime back I got a request from Satish Tripathi for building this application. So built it. I thought why not share it with everyone. I will try to keep this small and simple. Please don’t expect any fancy UI stuff.

First, let’s write our backend code which is going to serve our model and API for prediction. First, let’s start with our usual imports.

from flask import Flask, render_template, request
from PIL import Image
import numpy as np
from keras.models import load_model
import tensorflow as tf

Flask is our framework which we are going to use to run/serve our application.
render_template is for our HTML template rendering.
request is for accessing file which was uploaded by the user on our application.
Image from Pillow(PIL) library is for manipulating image uploaded by the user.
numpy library is for converting image to an array which we are going to use as input for our model to get the prediction.
load_model from keras is to load our model trained with MNIST data.
tensorflow is to run our model.

Next, we will load our Flask stuff and model

app = Flask(__name__, template_folder='templates')

def init():
   global model,graph
   model = load_model('model/mnistCNN.h5')
   graph = tf.get_default_graph()

if __name__ == '__main__':
   print(("* Loading Keras model and Flask starting server..."
      "please wait until server has fully started"))
   init()
   app.run(debug = True)

Here we are doing the usual Flask stuff and one more thing. i.e., loading our model. We are loading the model and graph as global variables so that we don’t load each and every time to get the prediction.

@app.route('/')
def upload_file():
   return render_template('index.html')

This code is to render index.html when the user lands on our main/home page.

@app.route('/uploader', methods = ['POST'])
def upload_image_file():
   if request.method == 'POST':
      img = Image.open(request.files['file'].stream).convert("L")
      img = img.resize((28,28))
      im2arr = np.array(img)
      im2arr = im2arr.reshape(1,28,28,1)
      with graph.as_default():
         y_pred = model.predict_classes(im2arr)

      return 'Predicted Number: ' + str(y_pred[0])

Our main secret sauce is here.
Basically, this code takes the image stream of the image uploaded by the user.
Then resize it 28×28 because we trained our model with the images which have 28×28 dimension.
Create an array out the image and reshape it to the required dimensions.
Now we will predict the digit and returns the predicted number to the user.

Now our backend code is ready it’s time to write UI for it.

<html>
  <body>
    <form action = "{{ url_for('upload_image_file') }}" method = "POST" enctype = "multipart/form-data">
      <input type = "file" name = "file" />
      <input type = "submit"/>
    </form>
  </body>
</html>

Here we are creating a form with the URL for uploading the image. That’s it.

Our code is ready. It’s time to install the required libraries.

pip3 install numpy
pip3 install Flask
pip3 install Keras
pip3 install Pillow

Run application with the following command

python3 app.py

Now our application ready. Open your browser and hit this URL.

http://localhost:5000/

Now you will see this boring UI

Upload an image. I am uploading below image

Hurray!!! we got the prediction.

Congrats!!!
You will find this code at my GitHub repository.

Peace. Happy Coding.

Related Post

Leave a Reply

Your email address will not be published. Required fields are marked *