Deploying a Trained ML Model using Flask | by Harshit Tyagi | Towards Data Science

Continuing from my last post on End-to-End Machine Learning Project Tutorial where we discussed major tasks of building a robust ML model, this post offers you a simple and fast solution to deploying your ML model on the web.
This is the last task in our End-to-End ML fuel consumption project which we started here.
In order to deploy any trained model, you need the following:
A trained model ready to deploy — save the model into a file to be further loaded and used by the web service.
A web service — that gives a purpose for your model to be used in practice. For our fuel consumption model, it can be using the vehicle configuration to predict its efficiency. We’ll use Flask to develop this service.
A cloud service provider — you need special cloud servers to deploy the application and for simplicity, we are going to use Heroku(there are going to be AWS and GCP covered in the Data Engineering series) for this.
Let’s get started by looking at each one of these processes one by one.
Once you’re confident enough to take your trained and tested model into the production-ready environment, the first step is to save it into a .h5 or .bin file using a library like pickle .
Make sure you have pickle installed in your environment.
Next, let’s import the module and dump the model into a .bin file:
import pickle##dump the model into a filewith open("model.bin", 'wb') as f_out:    pickle.dump(final_model, f_out) # write final_model in .bin file    f_out.close()  # close the file 
This will save your model in your present working directory unless you specify some other path.
It’s time to test if we are able to use this file to load our model and make predictions, we are going to use the same(as defined in prev blog) vehicle config:
##vehicle configvehicle_config = {    'Cylinders': [4, 6, 8],    'Displacement': [155.0, 160.0, 165.5],    'Horsepower': [93.0, 130.0, 98.0],    'Weight': [2500.0, 3150.0, 2600.0],    'Acceleration': [15.0, 14.0, 16.0],    'Model Year': [81, 80, 78],    'Origin': [3, 2, 1]}
Let’ load the model from the file:
##loading the model from the saved filewith open('model.bin', 'rb') as f_in:    model = pickle.load(f_in)
Make predictions on the vehicle_config
##defined in prev_blogpredict_mpg(vehicle_config, model)##output: array([34.83333333, 18.50666667, 20.56333333])
The output is the same as we predicted earlier using final_model.
The next step is to package this model into a web service that when given the data through a POST request returns the MPG(Miles per Gallon) predictions as a response.
I am using the Flask web framework, a commonly used lightweight framework for developing web services in Python. In my opinion, it is probably the easiest way to implement a web service.
Flask requires gets you started with very little code and you don’t need to worry about the complexity of handling with HTTP requests and responses.
Here are the steps:
Create a new directory for your flask application.
Set up a dedicated environment with dependencies installed using pip.
Install the following packages:
pandasnumpysklearnflaskgunicornseaborn
The next step is to activate this environment and start developing a simple endpoint to test the application:
Create a new file, main.py and import the flask module:
from flask import Flask
Create a Flask app by instantiating the Flask class:
##creating a flask app and naming it "app"app = Flask('app')
Create a route and a function corresponding to it that will return a simple string:
@app.route('/test', methods=['GET'])def test():    return 'Pinging Model Application!!'
The above code makes use of decorators — an advanced python feature. You can read more about decorators here. We don’t need a deep understanding of decorators, just that adding a decorator @app.route on top of the test() function assigns that web service address to that function.
Now, to run the application we need this last piece of code:
if __name__ == ‘__main__’:    app.run(debug=True, host=’0.0.0.0', port=9696)
The run method starts our flask application service. The 3 parameters specify:
debug=True — restarts the application automatically when it encounters any change in the code
host=’0.0.0.0' — makes the web service public
port=9696 — the port that we use to access the application
Now, in your terminal run the main.py
python main.py
Opening the URL http://0.0.0.0:9696/test in your browser will print the response string on the webpage:
With the application now, running, let’s run the model:
Create a new directory model_files to store all the model-related code.
In this directory, create a ml_model.py file which will contain the data preparation code and the predict function we wrote here.
Copy and paste the libraries you imported in the first part and the preprocessing/transformation functions. The file should look like this:
In the same directory, place your saved model.bin file as well.
Now, in the main.py we are going to import the predict_mpg function to make predictions but to do that we are required to create an empty __init__.py file to tell Python that the directory is a package.
Your directory should have this tree:
Next up, define the predict/ route that will accept the vehicle_config from an HTTP POST request and return the predictions using the model and predict_mpg() method.
In your main.py, first import:
import picklefrom flask import Flask, request, jsonifyfrom model_files.ml_model import predict_mpg
Then add the predict route and the corresponding function:
Here, we’ll only be accepting POST request for our function and thus we have methods=[‘POST’] in the decorator.
First, we capture the data(vehicle_config) from our request using get_json() method and stored it in the variable vehicle.
Then we load the trained model into the model variable from the file we have in model_files folder.
Now, we make the predictions by calling the predict_mpg function and passing the vehicle and model.
We create a JSON response of this array returned in the predictions variable and return this JSON as the method response.
We can test this route using Postman or the requests package, start the server running the main.py and then in your notebook, add this code to send a POST request with the vehicle_config:
import requestsurl = “http://localhost:9696/predict"r = requests.post(url, json = vehicle_config)r.text.strip()##output: '{"mpg_predictions":[34.60333333333333,19.32333333333333,14.893333333333333]}'
Great! Now, comes the last part, this same functionality should work when deployed on a remote server.
To deploy this flask application on Heroku, you need to follow these very simple steps:
Create a Procfile in the main directory — this contains the command to get the run the application on the server.Add the following in your Procfile:
Create a Procfile in the main directory — this contains the command to get the run the application on the server.
Add the following in your Procfile:
web: gunicorn wsgi:app
We are using gunicorn(installed earlier) to deploy the application:
Gunicorn is a pure-Python HTTP server for WSGI applications. It allows you to run any Python application concurrently by running multiple Python processes within a single dyno. It provides a perfect balance of performance, flexibility, and configuration simplicity.
3. Create a wsgi.py file and add:
##importing the app from main filefrom main import appif __name__ == “__main__”:     app.run()
Make sure you delete the run code from the main.py .
4. Write all the python dependencies into requirements.txt:
you can use pip freeze > requirements.txt or simply put the above-mentioned list of packages + any other package that your application is using.
5. Using the terminal,
initialize an empty git repository,
add the files to the staging area
commit files to the local repository:
$ git init $ git add .$ git commit -m "Initial Commit"
6. Create a Heroku account if you haven’t already, login to Heroku CLI:
heroku login
Approve the login from the browser as the page pops up:
7. Create a flask app:
heroku create <name of your app>
I named it mpg-flask-app. It will create a flask app and will give us a URL on which the app will be deployed.
8. Finally, push all your code to Heroku remote:
$ git push heroku master
And Voila! your web service is now deployed on https://mpg-flask-app.herokuapp.com/predict.
Again, test the endpoint using request package by sending the same vehicle config:
With that, you have all the major skills you need to get on to building more complex ML applications.
You can refer to my GitHub repository for this project:
github.com
And you can develop this entire project along with me:
This was still a simple project, for the next steps, I’d recommend you take up a more complex dataset, maybe pick up a classification problem and repeat these tasks till deployment.
But if you don’t want to wait, here is the complete tutorial series(playlist) on my YouTube channel where you can follow me while working on this project.
With this channel, I plan to roll out a couple of series covering the entire data science space. Here is why you should be subscribing to the channel:
These series would cover all the required/demanded quality tutorials on each of the topics and subtopics like Python fundamentals for Data Science.
Explained Mathematics and derivations of why we do what we do in ML and Deep Learning.
Podcasts with Data Scientists and Engineers at Google, Microsoft, Amazon, etc, and CEOs of big data-driven companies.
Projects and instructions to implement the topics learned so far. Learn about new certifications, Bootcamp, and resources to crack those certifications like this TensorFlow Developer Certificate Exam by Google.