Deploy Deep Learning or Machine Learning Model using Flask on Heroku


What does deploying a model mean?

The process of taking a trained Deep Learning or machine learning model and making its predictions available to users is known as Model Deployment. so, first train the model using the Colab or local machine and then deploy the model.

Deploying to Heroku with Flask

Flask is one of the quickest and easiest ways to deploy your work. flask gives more control on your application. There are other options available to deploy your Model using Jupyter notebook like anvil , ipywidgets but we will go with flask.

It is an option on various deployment platforms, one of which is Heroku. Heroku gives you different options for how to create your web application, including proper web applications in Python, Ruby, PHP, etc but in this guide we are simply going to create a free account and deploy your first model using flask and heroku CLI.

Prerequisites

Let's Start

we will devide this guide in two parts:

NOTE: you can skip to STEP 2 if you have already setup your flask app.

STEP 1: flask app setup

if you are new to flask or lazy to design forntend of web app than you can follow my design. we will see what needs to be changed but before going to that let's Look at how web app is going to looks like : object Detection

Object Detection app

copy your all Model code in single python Module(file) and define function that is responsible for predictions of input. in my case i have define one function detect that take image name as argument and run detection on it and save result in uploads directory.you can download all files from Here.

          

            @app.route('/', methods=['POST'])
            def upload_image():
                if 'file' not in request.files:
                    flash('No file part')
                    return redirect(request.url)
                file = request.files['file']
                if file.filename == '':
                    flash('No image selected for uploading')
                    return redirect(request.url)
                if file and allowed_file(file.filename):
                    filename = secure_filename(file.filename)
                    file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
                    # replace this function
                    detect(file.filename,False)
                    #print('upload_image filename: ' + filename)
                    flash('Image successfully uploaded and displayed below')
                    return render_template('index.html', filename=filename)
                else:
                    flash('Allowed image types are - png, jpg, jpeg')
                    return redirect(request.url)
          
        

In above given app.py:upload_image() you just need to change one line detect(file.filename,False) with yours if you are building image classifier. when user click on submit button it will save image in uploads directory and run your algorithm on it and again save that image(in case of image classifier) in uploads directory to serve it to user.

It's better to give some examples to user. by one Click user can see what your model does. e.g. i have given 3 Try it example.

STEP 2: Deploy

Creating your Git repo. What do you need?

You project needs to be in a Git repository as we’re going to tell Heroku to copy it from there, and the simplest way to get your demo deployed is to have everything you need in your repo (unless you start getting close to the size limit which we will discuss at the end).

Let's see, minimum you need in your directory is as follows:

Here is my directory structure:

directory structure

app.py

it's your main file that responsible for your app's working. it may import your model and essential imports.

Procfile

Your Procfile (process file) only needs to contain 1 line, and it tells Heroku what kind of application to create.

web: gunicorn app:app

you should be aware of that, Procfile dosen't have any file extension. sometimes people save it as .txt file and than get's Error. you can check that in above directory structure image.

requirements.txt

When you deploy your application, Heroku builds a server image, essentially one giant file that it can quickly copy onto a server when someone wants to run your app. All of the packages you need must be specified in your requirements.txt. That means all of the things you pip install at the top of your any python file should be moved to here (plus any packages you use which your particular platform makes available by default). mine is given below:

          
            click==8.0.1
            colorama==0.4.4
            cycler==0.10.0
            Flask==2.0.1
            Flask-SQLAlchemy==2.5.1
            greenlet==1.1.0
            gunicorn==20.1.0
            itsdangerous==2.0.1
            Jinja2==3.0.1
            kiwisolver==1.3.1
            MarkupSafe==2.0.1
            matplotlib==3.4.2
            numpy==1.20.3
            opencv-python-headless==4.5.2.52
            Pillow==8.2.0
            pyparsing==2.4.7
            python-dateutil==2.8.1
            six==1.16.0
            SQLAlchemy==1.4.17
          
        

you can easly generate this file: open command prompt and navigate to project directory and run below command:

pip freeze > requirements.txt

But problem with pip freeze is that, it will write all available libraries in your environment rather than only import libraries. you can also use pigar for this task it will only write your import requirements.

NOTE: if you are using opencv-python in your model than you needs to make changes in requirements.txt file. change line opencv-python==version to opencv-python-headless==version

500 MB "slug" limit

Heroku limits the size of the final "slug" as they call it (the server image they create) to 500 MB, and that includes all of the libraries you use along with all of their dependancies, so what you thought was quite a small project, may well be closer to the limit than you expected.

Most basic beginner projects should be fine but if you do need to reduce the size of your server image (especially once you start hosting multiple demo projects), you can store your model exports (and any other large files) on Google Drive or Dropbox or somewhere similar, and load them across from there.

          
            import urllib.request

            MODEL_URL = "https://drive.google.com/uc?export=download&id=YOUR_FILE_ID"
            urllib.request.urlretrieve(MODEL_URL, "filename.weights")

            learner = load_learner(Path("."), "filename.weights")
          
        

NOTE: Mostly we create virtual environment(python venv) to develope flask app. it's better to delete that folder when you are deploying your model. it will help you to decrease slug size.

Step 1: Open command prompt and Navigate to flask app directory. login to your heroku account.

heroku login

heroku loging

Step 2: initialize empty Git repository.

git init

Step 3: if your file is large than 100MB than it's better to use Git LFS tool. if your file is smaller than 100MB, than no needs to run below commands.

git lfs track '*.weights'

git add .gitattributes

Step 4: Commit changes to Git.

git add .

git commit -m "initial commit"

Step 5: Create heroku app and give it unique name. if you get error of name than try to give another name and try again.

heroku create "objdetect"

NOTE : Name must start with a letter, end with a letter or digit and can only contain lowercase letter and dashes.

You can check that we are using heroku's Git version control

git remote -v

Step 6: Push all files to heroku

git push heroku master

After compeleting above operation you can see your slug size and url to access app.

heroku app

Conclusion

Developing end-to-end Machine Learning web apps can be daunting. But this is a free, simpler, easier way to create demo web applications.