Deploying Keras Deep Learning Model as a Python Web Application

The translation of the article was prepared specifically for students of the course "Web-developer in Python . "








Creating a cool machine learning project is one thing, another thing when you need other people to be able to see it too. Of course, you can put the whole project on GitHub, but how will your grandparents understand what you did? No, we need to deploy our deep learning model as a web application that will be available to anyone in the world.



In this article, we will learn how to write a web application that uses the Keras trained recurrent neural network and allows users to create new patent annotations. This project is based on the work from the article “Recurrent Neural Networks by Example” , however, it is not necessary to know how RNN is built now. At the moment, we will just consider it as a black box: we set the initial sequence, and it displays a completely new patent annotation, which can be viewed in a browser!



Typically, data analysts develop models, and front-end show them to the world. In this project, we will have to play both roles and plunge into web development (albeit almost entirely in Python).



This project will require combining several tools:





Ultimately, we get a web application that allows users to create completely new patent annotations using a trained recurrent neural network.







All project code is available on GitHub .



An approach



The goal was to deploy the web application as quickly as possible. For this, I chose Flask, which allows you to write applications in Python. I don’t like messing with styles (I think you’ve already seen), so I copy and paste almost all CSS from third-party sources. This Keras team article was useful for learning the basics, and this article is also a helpful guide.

In general, this project meets my design principles: create a prototype that works quickly (copying and pasting as much code as needed), and then just repeat the same thing to improve the product.

Basic web application on Flask



The fastest way to create a Python web application is to use Flask (http://flask.pocoo.org/). To create our own application, we can use the following:



from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "<h1>Not Much Going On Here</h1>" app.run(host='0.0.0.0', port=50000)
      
      





If you run this code, you will see your own application at localhost: 50000. Of course, we need something more, so we will use a more complex function that generally does the same: it processes requests from your browser and serves some content in the form of HTML.



User input form



When users go to the main page of the application, we will show them a form with three options:



  1. Enter the source sequence for the RNN or randomly generate it.
  2. Selection of the “diversity” of RNN forecasts.
  3. The choice of the number of words output from the RNN.


To create a form in Python, we use wtforms . You will see the code for its creation below:



 from wtforms import (Form, TextField, validators, SubmitField, DecimalField, IntegerField) class ReusableForm(Form): """User entry form for entering specifics for generation""" # Starting seed seed = TextField("Enter a seed string or 'random':", validators=[ validators.InputRequired()]) # Diversity of predictions diversity = DecimalField('Enter diversity:', default=0.8, validators=[validators.InputRequired(), validators.NumberRange(min=0.5, max=5.0, message='Diversity must be between 0.5 and 5.')]) # Number of words words = IntegerField('Enter number of words to generate:', default=50, validators=[validators.InputRequired(), validators.NumberRange(min=10, max=100, message='Number of words must be between 10 and 100')]) # Submit button submit = SubmitField("Enter")
      
      





Using it, we created the form shown below (with styles from main.css



):







A check in the code is needed to make sure that the user enters the correct information. For example, we check that all fields are filled, and that the value of the diversity parameter is between 0.5 and 5. These conditions must be met in order to get started.





Error validating entered data



We process this form using templates on Flask



.



Patterns



A template is a file with an already prepared “frame” that just needs to be filled in a certain way. For a Flask web application, we can use the Jinja template library to translate Python code into an HTML document. For example, in our main function, we will send the contents of the form to a template called index.html



.



 from flask import render_template # Home page @app.route("/", methods=['GET', 'POST']) def home(): """Home page of app with form""" # Create form form = ReusableForm(request.form) # Send template information to index.html return render_template('index.html', form=form)
      
      





When the user goes to the main page, our application will provide index.html



input from the form. A template is a complete HTML structure in which we refer to Python variables using the {{variable}}



syntax.



 <!DOCTYPE html> <html> <head> <title>RNN Patent Writing</title> <link rel="stylesheet" href="/static/css/main.css"> <link rel="shortcut icon" href="/static/images/lstm.ico"> </head> <body> <div class="container"> <h1> <center>Writing Novel Patent Abstracts with Recurrent Neural Networks</center> </h1> {% block content %} {% for message in form.seed.errors %} <div class="flash">{{ message }}</div> {% endfor %} {% for message in form.diversity.errors %} <div class="flash">{{ message }}</div> {% endfor %} {% for message in form.words.errors %} <div class="flash">{{ message }}</div> {% endfor %} <form method=post> {{ form.seed.label }} {{ form.seed }} {{ form.diversity.label }} {{ form.diversity }} {{ form.words.label }} {{ form.words }} {{ form.submit }} </form> {% endblock %} </div> </body> </html>
      
      





When an error occurs in the form (input that cannot be verified), an error message will flash. In addition, the form will be displayed as in the file above.



When the user enters information and clicks submit



( POST



request), if the information is correct, we redirect the input data to the corresponding function to make predictions using trained RNN. This means that you need to modify home()



.



 from flask import request # User defined utility functions from utils import generate_random_start, generate_from_seed # Home page @app.route("/", methods=['GET', 'POST']) def home(): """Home page of app with form""" # Create form form = ReusableForm(request.form) # On form entry and all conditions met if request.method == 'POST' and form.validate(): # Extract information seed = request.form['seed'] diversity = float(request.form['diversity']) words = int(request.form['words']) # Generate a random sequence if seed == 'random': return render_template('random.html', input=generate_random_start(model=model, graph=graph, new_words=words, diversity=diversity)) # Generate starting from a seed sequence else: return render_template('seeded.html', input=generate_from_seed(model=model, graph=graph, seed=seed, new_words=words, diversity=diversity)) # Send template information to index.html return render_template('index.html', form=form)
      
      





Now, when the user clicks submit



and the entered information is correct, depending on the input, the input is sent either to generate_random_start



or to generate_from_seed



. These features use the Keras trained model to create a new patent with the user and diversity



parameters num_words



. The output of this function, in turn, is sent randomly to random.html



or seeded.html



templates to display as a web page.



Creating Predictions Using the Keras Pre-trained Model



The parameter parameter contains the pre-trained Keras model, which loads as follows:



 from keras.models import load_model import tensorflow as tf def load_keras_model(): """Load in the pre-trained model""" global model model = load_model('../models/train-embeddings-rnn.h5') # Required for model to work global graph graph = tf.get_default_graph() load_keras_model()
      
      





(Essentially, there is a workaround that looks like tf.get_default_graph()



)

I won’t show completely two util



functions (the code you will find here ), because all you need to understand is that they store the already trained Keras model along with the parameters and make predictions - patent annotations.



Both of these functions return a string in Python with formatted HTML. This line is sent to another template, which will appear as a web page. For example, generate_random_start



returns formatted HTML that is sent to random.html



:



 <!DOCTYPE html> <html> <header> <title>Random Starting Abstract </title> <link rel="stylesheet" href="/static/css/main.css"> <link rel="shortcut icon" href="/static/images/lstm.ico"> <ul> <li><a href="/">Home</a></li> </ul> </header> <body> <div class="container"> {% block content %} {{input|safe}} {% endblock %} </div> </body>
      
      





Here we again use the Jinja



template engine to display a formatted HTML file. Since the Python string is already translated into HTML, all we need to do to display it is use {{input|safe}}



(where input



is a Python variable). Then in main.css



we can add styles to this page, however, as well as other HTML pages.



Work result



The generate_random_start



function selects a random patent annotation as an input sequence and makes predictions based on it. It then displays the input sequence, the RNN generated output, and the actual output:





The output is based on a random input sequence.



The generate_from_seed



function accepts the initial sequence entered by the user and builds forecasts based on it. The output is as follows:





Output based on user input sequence.



Although the results do not always form logical sequences, they nevertheless show that the neural network is familiar with the basics of the English language. She was trained to predict each next word based on the previous 50 and thereby select a compelling annotation. Depending on the diversity



parameter, the output may turn out to be completely random or cyclical.



Application launch



To start the application for yourself, all you need to do is download the repository, go to the directory where the deployment is and enter run_keras_server.py



. The application will be available at localhost:10000



.



Depending on how your home Wi-Fi is configured, you should be able to access the application from any computer on the network using your IP address.



Next steps



The web application running on your personal computer is great for sharing with friends and family. However, I definitely do not recommend opening it to everyone on your home network. Later we will learn how to deploy the application on AWS EC2 and finally show it to the world.



To improve the application, you can change the styles ( in main.css ) and, possibly, add additional parameters, such as the ability to select a pre-trained network . The great thing about personal projects is that you can develop them as long as you want. If you want to play with the application, download the repository and get started.







Conclusion



In this article, we learned how to deploy a Keras pre-trained deep learning model as a web application. This required the integration of a number of different technologies, including recurrent neural networks, web applications, templates, HTML, CSS and, of course, Python .



Although this is a basic application, it shows that you can create web applications using deep learning with relatively little effort. Few people can say that they were able to deploy a deep learning model in the form of a web application, but if you follow the instructions in this article, you can become one of them!



All Articles