Convert a Python Emotion Recognition Notebook into an API without extra code
Tags: machinelearning, python, jupyter, devops
Published: 2021-07-02 19:06:16


##Training an Emotion Recognition in a Jupyter Notebook and converting it into a Flask API project without additional code using Cuttle

For people who use Jupyter notebooks for development and testing quite often, you’re probably habituated to copying and pasting code around all the time.
> Deleting test snippets, using a different IDE to compile and test your code again, and developing an API is just a few of the time-consuming tasks an ML developer is used to.

Wouldn’t it be great if we could automate the drudgery of boilerplate code needed to build an API project?** **Here we will train an emotion recognition model in a Jupyter Notebook and convert it into a Flask API project with absolutely no extra code!

## Dependencies

    pip install 
    tensorflow==2.5.0 Keras==2.4.3 numpy==1.19.5 opencv-python==4.4.0.44

We also need to install [Cuttle](http://www.cuttle.it) to convert our ML notebook into a Flask API project.

    pip install cuttle

## Dataset

You can use any dataset on emotion recognition or create your own dataset. In this article, we’re using the emotion recognition dataset available on Kaggle. You should find it [here](https://www.kaggle.com/jonathanoheix/face-expression-recognition-dataset). This dataset contains images of 7 classes: angry, disgust, fear, happy, neutral, sad, and surprise. If you want to add another class, just create a new directory and add images belonging to that class.

Create the notebook in the same directory as the dataset you downloaded having ‘train’ and ‘validation’ folders.

## Imports

<iframe src="https://medium.com/media/3b34215af1aba2d3f2a26ad13e2252da" frameborder=0></iframe>

## Dataset Augmentation

The ImageDataGenerator allows you to fit models using image augmentation, transformation on each training image and also pass any pre-processing functions if available.

We’re rescaling images because colors range from [0–255] and rescaling them transforms each pixel value in the range of [0–1]. Here, we define the target size for our model as 48x48 and the batch_size as 64.

<iframe src="https://medium.com/media/1842ae5c57d30ba1307fdbd65dd872c4" frameborder=0></iframe>

## Model Training

We’re defining a CNN here but you can choose to use any of the pre-trained models available like VGG16 or ResNet, or make use of transfer learning as well.

<iframe src="https://medium.com/media/3dacf238b3bc9d19dd660bb641590c20" frameborder=0></iframe>

Your model gets saved in the given path after completing the training.

## Emotion Recognition

We now load the model, give it an image and test it. In this step, let’s introduce cuttle and turn the resultant function into an API that any frontend application can hit.

<iframe src="https://medium.com/media/8daeff059685bddb8f420dcd4a3640b8" frameborder=0></iframe>

<iframe src="https://medium.com/media/c46f4a385856122051f6358f61dfa72a" frameborder=0></iframe>

Let’s use a test image ‘test.jpeg’.

![Source: [Unsplash](http://unsplash.com)](https://cdn-images-1.medium.com/max/2000/0*9xIPrBdL1JwWIUlO)*Source: [Unsplash](http://unsplash.com)*

<iframe src="https://medium.com/media/34199de25d0f80a8930273b1391ffc8f" frameborder=0></iframe>

The output we get for this from the model prediction is **‘fear’**. Continue testing with a few more images till you’re satisfied with the model’s accuracy and results. Let’s look at how we can convert this into an API project.

## Initialize Cuttle

Initialize cuttle with ‘cuttle init’ as follows and enter the name of the notebook being used.

![Source — Author](https://cdn-images-1.medium.com/max/2256/1*bWgPEeZay_g7lQGAykf_JA.png)*Source — Author*

## Create Cuttle environment

In this step, you name the environment, specify the platform you’re using, and which transformer you want to use. We want to use the **flask** transformer in this scenario. You can choose an environment name of your convenience. I’ve used ‘**emotion-rec**’ as an example.

![Source — Author](https://cdn-images-1.medium.com/max/2056/1*-RL2yKuOMdBuvUvNvqL-DA.png)*Source — Author*

At this point, your **cuttle.json** should look something like this:

![Source — Author](https://cdn-images-1.medium.com/max/2000/1*8YAeO54RDofDXt9V7-rJwg.png)*Source — Author*

After you’re done creating the config, it’s time to edit your Jupyter notebook to include cuttle config. We only need to edit the last portion of the code to define the API route and set the output config.

**Adding Config to cells:**

We use Cuttle config to perform 2 main actions here as seen [here](https://github.com/CuttleLabs/Emotion-Recognition-API/blob/main/Emotion_recogniser.ipynb).

* disabling the training steps and load from the saved model file so as to not re-train every time we want to run the script.

* specify the cell to be executed every time the API is called along with required parameters

To disable cells, add this config at the beginning of the cell.

    #cuttle-environment-disable emotion-rec

Now add config to transform your script into an API as follows:

<iframe src="https://medium.com/media/c4ce40ad0d52e93b3b6428645d6963f4" frameborder=0></iframe>

We’re setting two configs: the **cuttle-environment-set-config** and the **cuttle-environment-assign** configs. They are cell-scoped and line-scoped respectively. The cell-scoped config sets configuration needed during transformation for **cells**. The line-scoped config allows us to configure **variables**.

In the first line, we set the cell-scoped config specifying the environment name, the method, and the route of our choice. We also configure variable ‘file’ allowing us to get-config from the request method and the ‘output’ variable which is going to be our response.

## Transform

Our last step is to cuttle-transform using the environment name we’ve been using. Let’s jump into how:

![Source — Author](https://cdn-images-1.medium.com/max/2120/1*lgC-xQFOnINSFhrZ0GV6Hw.png)*Source — Author*

After this step, you should see an **output directory** formed with another sub-directory containing the environment name. Go to this directory to spot your code that’s transformed into an API. Run this file as:

![Source — Author](https://cdn-images-1.medium.com/max/2020/1*OtSGyfjeAyHI09iruqHqKg.png)*Source — Author*

Now our code is running on localhost port 5000 by default. Test this out by sending images using Postman to get your response.

![test.jpeg sent via POST request to our flask API. Source — Author](https://cdn-images-1.medium.com/max/2636/1*P8SDk23DMo2NYSTNZehkeA.png)*test.jpeg sent via POST request to our flask API. Source — Author*

Your API project is now ready to deploy! Cuttle also allows you to convert your notebook into a script or a pipeline.

## Resources

Cuttle Website: [cuttle.it](https://www.cuttle.it/?utm_source=medium_article)
Github: [Emotion recognition API source](https://github.com/CuttleLabs/Emotion-Recognition-API)
Cuttle Source: [Cuttle CLI Source](https://github.com/CuttleLabs/cuttle-cli)

You can also find us on Twitter @ [https://twitter.com/cuttlehq](https://twitter.com/cuttlehq)