Deploying Machine Learning Models with Django APIs
Machine learning (ML) and artificial intelligence (AI) are transforming industries by enabling powerful predictive capabilities. By learning patterns from historical data, ML models can forecast unknown future outcomes, unlocking immense business value. However, one of the biggest technical challenges is integrating these sophisticated models into production-ready systems.
The typical machine learning workflow consists of two key phases:
- Training – The ML algorithm is developed using past data with known outcomes
- Inference – The trained model is applied to new data to predict results
While many tools exist for training models, deploying them into applications is often a stumbling block. One effective solution is to expose the ML model through a web API. This creates a server that can handle requests, pass them to the model for inference, and return the predictions.
In this article, we‘ll walk through the process of creating a Django API to deploy a trained ML model. Django is a high-level Python web framework that enables rapid development of secure and maintainable websites. By leveraging Django to integrate the model, we can meet the requirements for a robust ML-powered application.
Setting Up the Development Environment
The first step is to set up a development environment and install the necessary dependencies. Create a new directory for the project and navigate into it:
mkdir ml-django-api
cd ml-django-api
Create a new virtual environment and activate it:
python -m venv env
source env/bin/activate
Next, install Django and other required packages:
pip install django djangorestframework scikit-learn
We‘ll be using scikit-learn to train our example machine learning model.
Creating the Django Project
Now we can create a new Django project for our application:
django-admin startproject ml_api
cd ml_api
This generates the boilerplate code and directory structure needed for a Django project. The ml_api directory will contain configuration and settings.
Next, let‘s create a new app within our project to encapsulate the ML model and API:
python manage.py startapp ml_model
We‘ll implement the ML logic within the ml_model app. Open the settings.py file within the ml_api directory and add the newly created app to the list of installed apps:
INSTALLED_APPS = [
‘django.contrib.admin‘,
‘django.contrib.auth‘,
‘django.contrib.contenttypes‘,
‘django.contrib.sessions‘,
‘django.contrib.messages‘,
‘django.contrib.staticfiles‘,
‘rest_framework‘,
‘ml_model‘
]
We‘ve also added rest_framework since we‘ll be using Django REST Framework to build the API.
Training the Machine Learning Model
For this example, we‘ll train a simple model to predict whether an animal is a dog or cat based on the sound it makes. We‘ll use scikit-learn to build the model.
Create a new file train_model.py within the ml_model directory:
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.linear_model import LogisticRegression
import pickle
# Example training data
# X = animal sounds, y = labels (dog=1, cat=0)
X = [‘bark‘, ‘meow‘, ‘woof‘, ‘purr‘, ‘growl‘]
y = [1, 0, 1, 0, 1]
# Vectorize text features
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(X)
# Train logistic regression model
model = LogisticRegression()
model.fit(X, y)
# Save vectorizer and model
with open(‘vectorizer.pkl‘, ‘wb‘) as f:
pickle.dump(vectorizer, f)
with open(‘model.pkl‘, ‘wb‘) as f:
pickle.dump(model, f)
This code does the following:
- Defines some example training data of animal sounds and labels
- Vectorizes the text features using CountVectorizer
- Trains a logistic regression model on the vectorized data
- Saves the trained vectorizer and model as pickle files
Run this script to generate the trained model:
python ml_model/train_model.py
This will create two pickle files: vectorizer.pkl and model.pkl. We‘ll load these in our Django app to make predictions.
Integrating the Model
Now let‘s integrate the trained model into our Django app. Create a new file apps.py in the ml_model directory:
from django.apps import AppConfig
import pickle
import os
class MlModelConfig(AppConfig):
name = ‘ml_model‘
# Load vectorizer and model
with open(‘vectorizer.pkl‘, ‘rb‘) as f:
vectorizer = pickle.load(f)
with open(‘model.pkl‘, ‘rb‘) as f:
model = pickle.load(f)
This code defines a custom AppConfig that will load the vectorizer and model when the app starts up. By loading them here, we can reuse the same instances for every prediction request.
Next, create a file views.py in the ml_model directory to define the API endpoint:
from rest_framework.views import APIView
from rest_framework.response import Response
from .apps import MlModelConfig
class PredictView(APIView):
def post(self, request):
# Get sound from request
sound = request.data.get(‘sound‘)
# Vectorize sound
vectorized_sound = MlModelConfig.vectorizer.transform([sound])
# Make prediction
prediction = MlModelConfig.model.predict(vectorized_sound)[0]
# Return response
response = {‘prediction‘: int(prediction)}
return Response(response)
This defines a view for the /predict endpoint that will accept POST requests with a sound parameter. It vectorizes the sound, passes it to the model for prediction, and returns the result.
Finally, create a file urls.py in the ml_model directory to map the URL to the view:
from django.urls import path
from .views import PredictView
urlpatterns = [
path(‘predict/‘, PredictView.as_view()),
]
Update the project‘s urls.py to include the ml_model URLs:
from django.urls import include, path
urlpatterns = [
path(‘‘, include(‘ml_model.urls‘)),
]
Testing the API
We‘re now ready to test our API! Start the development server:
python manage.py runserver
We can test the /predict endpoint using cURL. Open a new terminal window and run:
curl -X POST -H "Content-Type: application/json" -d ‘{"sound":"meow"}‘ http://localhost:8000/predict/
# Should return:
# {"prediction":0}
curl -X POST -H "Content-Type: application/json" -d ‘{"sound":"woof"}‘ http://localhost:8000/predict/
# Should return:
# {"prediction":1}
The API correctly predicts "cat" for a "meow" sound and "dog" for a "woof" sound! We can also access the endpoint through a web browser or tools like Postman.
Deployment Considerations
For a real-world application, we would want to store the trained model files separately from the application code. This allows updating the model without redeploying the entire application. One approach is to store the model files in cloud storage and download them when the application starts.
When it comes to deploying the Django application itself, there are several options:
- Deploy on a cloud platform like AWS, Azure, or Google Cloud. Many of these offer managed services for deploying Django apps.
- Use a platform-as-a-service like Heroku that simplifies deployment
- Containerize the application using Docker and deploy the containers on a platform like Kubernetes
- Deploy on-premise on your own servers
The right deployment approach depends on factors like scalability needs, budget, and existing infrastructure.
Conclusion
We‘ve seen how to deploy a trained machine learning model using a Django API. This approach allows us to integrate ML into production-ready systems by providing a standard interface for making predictions. The API can be accessed by other internal services or exposed to external clients.
To recap, the key steps are:
- Train and save the ML model
- Create a Django app to load the saved model
- Define an API endpoint for making predictions using the model
- Deploy the Django app on a hosting platform
Although we used a simple example, this same architecture can be used for more complex models and use cases. You can try this approach with your own models and data.
Machine learning has immense potential, and deploying models into applications is a critical step for realizing their value. A Django API is one powerful way to achieve this. I encourage you to experiment with this technique and see what you can build!