Developing Deep Learning API using Django

Akhil Haridasan
Analytics Vidhya
Published in
8 min readJun 26, 2020

I hope you guys found my last post (Deploying Deep Learning Django app to Google Cloud Platform) useful. In this post, we will learn about developing a Deep Learning application using Django REST Framework. If you would like to explore more on Django then you can find all the details here.

In this post, we will again consider a Deep Learning model for application development, the reason being there is hardly anything on developing a Deep Learning application using Django. I am using my video emotion DL model that I have developed to predict the emotions from a video.

You can find n number of ways on Google to develop your app using DJANGO (don’t get confused). However, do keep in mind Django has no limits. You can mostly put anything anywhere 😂 But it’s always a good practice to maintain the structure and naming conventions (No?)

Again, this is one of the techniques (simplest one) for developing an app using the Django REST Framework on Windows system.

Pre-requisite for Deploying a Deep Learning model:

  1. Python 3.6 (preferred 3.6.10)
  2. Tensorflow 2.1.0 and Keras 2.3.1(as we are going to work with Deep Learning models and Keras)
  3. PyCharm/VS IDE (I prefer PyCharm, works like a charm 😬)

Step 1:

Creating a directory and installing Django

  1. Go to cmd (command prompt) and create a new project, let’s say “test”.
  2. Navigate to test folder/directory through cmd and install Django in it.
> mkdir test
> cd test
> pip install django

Step 2:

Creating a Django project

  1. Create a Django project inside the test directory as follows.
> django-admin startproject video_emotion

This code will help create a Django-project named “video_emotion” with some auto-generated setting files for an instance of Django, including database configuration, Django-specific options, and other application-specific files as shown below.

Significance of each file:

  • manage.py: A command-line utility that lets us interact with this Django project in various ways.
  • video_emotion/: directory contains all the necessary files like settings.py, urls.py, wsgi.py, etc.
  • settings.py: Settings/configuration for the Django project.
  • urls.py: The URL declarations for this Django project.
  • wsgi.py: An entry-point for WSGI-compatible web servers to serve our project.

Step 3:

Creating a basic Django application

  1. Navigate to video_emotion folder and create a Django application inside our Django project “video_emotion” as follows.
> cd video_emotion
> python manage.py startapp video_app

The above command will powerup the machine learning behind our API and creates multiple files inside our app “video_app” folder as shown below. Several of these files aren’t even needed and hence, we can ignore those files. Django has a utility that will help us focus on coding than arranging directories for deployment 😛. (Best thing about Django — I personally feel)

Significance of each file:

  • apps.py: We will create our config class inside this file. This code will not run every time a request is made but runs only once. hence, we’ll place the code to load our models here.
  • views.py will contain the actual code that runs on every request. So we will place the functions and important codes that we have used apart from model configuration here.

Step 4:

Test your Django application

  1. To test our code so far, we will run the following commands.
> python manage.py makemigrations
> python manage.py migrate
> python manage.py runserver
  • makemigrations will help us in identifying any changes made to our app.
  • migrate will help in applying all the changes that have been identified.
  • runserver will help in running the server with all the changes that have been applied.

Now copy the localhost url (which should look like: http://127.0.0.1:8000/) and paste that to your browser. You should see something like below on a successful build.

TADAAAA !!!!! Initial milestone achieved. ✌️✌️✌️✌️ Let’s move on to developing our Deep Learning application.

Step 5:

Make changes in Django app to accommodate ML changes

1. Making changes in “settings.py”

Search for INSTALLED_APPS and write the below mentioned.

Add rest_framework and video_app (name of the app) to “settings.py”.

Add the path to your models in “settings.py”. I have saved mine under models directory/folder (i.e. my model.h5 and other useful xml files). This variable “MODEL” is going to be used in “apps.py” for linking model weights. (This is only applicable for an ML/DL model development, where you have weights stored in .h5 or .hdf5 formats)

2. Making changes in “views.py”

Firstly, copy all the additional functions that you have used for your Deep Learning model (For instance, in my case, I have one function for extracting face features, one for detecting face, one for getting frames from video, etc) apart from the pre-trained models and paste that inside “views.py” as shown below. Keep in mind that there is no function to train your model included here because I am assuming that you’ve already trained your models and saved their weights to load them here in the application and directly link and use it here.

Now, we will create a function to get the request from user (in this case it would be a video url). And, hence, we will be using a POST method. There are two ways of getting the request, GET and POST. GET is used to access the website/localhost and get a JSON response from the server, but no user input is passed. Whereas in POST method, user can pass the input to the website/localhost and get a JSON response from the server.

from django.shortcuts import render
from django.http import JsonResponse
from django.conf import settings
from .apps import VideoAppConfig
//for linking apps.py - model weights
from rest_framework.decorators import api_view
import os
import cv2
import numpy as np
import pandas as pd
import time
import glob
import requests
from scipy import ndimage
from scipy.ndimage import zoom
@api_view(["POST"]) //recieve the request

def check_result(request):
#Get video file url
url = request.POST.get('url') //we are using form-data (key-value) format to store the request
head, tail = os.path.split(url)

r = requests.get(url, allow_redirects=True)
open("resume/" + tail, 'wb').write(r.content)

video_path = "resume/"
files = []
for i in os.listdir(video_path):
if i.endswith('.mp4'):
files.append(i)
for j in files:
vidcap = cv2.VideoCapture("resume/" + j)
sec = 0
count = 1
frameRate = 5
success = getFrame(vidcap, sec, count)

while success:
count = count + 1
sec = sec + frameRate
sec = round(sec, 2) # it will capture image every 2 second
success = getFrame(vidcap, sec, count)

img_path = glob.glob("frames/*.jpg")
data = []
for image1 in img_path:
n = cv2.imread(image1)
image_emo = emotion_extract(n)
data.append(image_emo)

emo_data = freq_persona(data)
print(emo_data)

# setting emotional values to its respective labels
emo_data.loc[emo_data['Emotion'] == 0, 'Emotion_Label'] = 'Angry'
emo_data.loc[emo_data['Emotion'] == 1, 'Emotion_Label'] = 'Disgust'
emo_data.loc[emo_data['Emotion'] == 2, 'Emotion_Label'] = 'Nervous'
emo_data.loc[emo_data['Emotion'] == 3, 'Emotion_Label'] = 'Happy'
emo_data.loc[emo_data['Emotion'] == 4, 'Emotion_Label'] = 'Sad'
emo_data.loc[emo_data['Emotion'] == 5, 'Emotion_Label'] = 'Surprise'
emo_data.loc[emo_data['Emotion'] == 6, 'Emotion_Label'] = 'Neutral'

emo_data = emo_data[emo_data['Count'].notna()]
emo_data = emo_data[emo_data['Emotion'].notna()]
emo_disp = emo_data[['Emotion_Label', 'Count']]

emo_jso = emo_disp.to_json(orient='values') //convert dataframe to json format

return JsonResponse(emo_jso, safe=False)

The highlighted commands are necessary commands to run your code. Hence, no messing with those commands.

Tips:

  • Do import all the libraries that are required to run your code. (I have mentioned some of mine for your understanding)
  • Convert dataframes to JSON format, as they are not going to work otherwise when you are returning a JSON response.

3. Making changes in “apps.py”

Before moving ahead, create a folder named models or however you wanna name it. And put all your model weights under that directory.

Now let’s make changes in “apps.py”. I prefer putting all my model weights in apps.py. Hence, the next step is to add your model load commands here as follows.

import os
import keras
import tensorflow

from django.apps import AppConfig
from django.conf import settings
from tensorflow.keras.models import model_from_json

class VideoAppConfig(AppConfig):
name = 'video_app' //name of your app

#load your models and model weights here and these are linked "MODELS" variable that we mentioned in "settings.py"
path = os.path.join(settings.MODELS, "your_model.h5")
path1 = os.path.join(settings.MODELS, 'your_model.json')

json_file = open(path1, 'r')
loaded_model_json = json_file.read()
json_file.close()
loaded_model = model_from_json(loaded_model_json)
loaded_model.load_weights(path)

Again reminding you guys, do import all your libraries that are required to load your model weights. If you are not using a JSON formatted model weights then it’s absolutely fine. Just load model weights and you are good to go 😬

4. Making changes in “urls.py”

Our last milestone to success would be to make changes here. (lol kidding !) But yes, this is our last step. Provide a url path to your application. For example, I have my application path set here as videos/. If I would like to make a call to my application then I would use something like http://127.0.0.1:8000/video/ (where the IP address is my localhost).

from django.contrib import admin
from django.urls import path
from video_app import views

urlpatterns = [
path('admin/', admin.site.urls),
path('video/', views.check_result)
]

Also, keep in mind that you need to import your views from the app (highlighted import) to link urls with the “views.py” file.

Step 6:

Run and test your application

Run migrations and then runserver commands to initialize your application on your IDE (PyCharm or any other).

> python manage.py makemigrations
> python manage.py migrate
> python manage.py runserver

When you don’t have an API (HTML) ready with you to test. “Postman” tool to the rescue. Yaayyyyyy !!! If you guys would like to have a read on what Postman tool is here is the link. Download the software and run your DJANGO application as follows.

And there you go !! That’s it guys. Peace out !!!!!!!!!!!!!

Some additional FYI thing

Django is one of the most desirable skills in the technology industry these days. It’s time to show off guys 😉

Advantages of using Django over Flask?

  1. Structured project — Conventional layout that will help you save time during development
  2. Navigation — There is a specific naming convention. Each file has names that will help a third person understand what these files are and where to look for at the time of issues.
  3. Swiftness — Django is created to support complex and large apps. On top of that, it has high scalability and reliability.
  4. Multiple URL formats — It has a toolkit that supports multiple URL formats and thus makes it less onerous for us. Formats can be: (abc.com/v1/test/, v1.abc.com/test/, or abc.com/test/?version=v1).

Libraries, dependencies and versions check is a mandate. Do keep in mind all the pre-requisites.

I know it was a bit lengthy but worth trying and I am sure you are gonna yield what you were looking for. If there are any issues do let me know. Or if you are facing any issue pertaining to Deep Learning models / ML models. You can contact me via LinkedIn or Facebook. Or else comment here itself, feedbacks are always a good way to improve.

I will be posting something interesting again with easy steps soon. Till then Enjoy coding !! 👍

--

--

Akhil Haridasan
Analytics Vidhya

Tech-savvy individual with good leadership, management and technical skills looking for a platform to learn and showcase my work ethics and skills