- Project Overview
- Getting started immediately
- Datasets
- Model
- Dependencies
- Workflow
- Directory structure
- Follow-up Work
- Contributors
- License
- Acknowledgments
- Contributions and Feedback
- Key Concepts
Understanding human emotions is crucial for human-computer interaction, artificial intelligence, and affective computing. Whether applied in virtual assistants, sentiment analysis, or interactive systems, accurate facial emotion recognition enhances user experience and engagement. This project delves into the realm of facial emotion recognition:
- using the Kaggle Facial Expression Recognition Challenge dataset
- building a Convolutional Neural Network (CNN) Tensorflow/Keras model, and
- deploying it as an Amazon web service using ECR, Lambda and a REST API gateway.
As emotions play a pivotal role in communication, this project aims to contribute to the evolving landscape of emotion-aware technology. It was done as part of the two-week end-of-course capstone project for the Machine Learning Zoomcamp. With a dataset of low-resolution (48x48 pixel) images and limited hardware, we achieved a 65% accuracy in classifying emotions, with particularly positive results on the emotions 'happy', 'anger' and 'sad'. We hope to keep working on this project and improving it. Dive into the repository to explore the code, contribute to advancements, and potentially integrate the model into your projects for a more emotionally intelligent interface.
Pull up any image of a facial expression from the internet, and use this script to make a prediction. For example:
(base) $~> python scripts/test-aws-rest-api.py
{'Anger': 0.0, 'Disgust': 0.0, 'Fear': 0.0, 'Happy': 1.0, 'Neutral': 0.0, 'Sadness': 0.0, 'Surprise': 0.0}
The FER2013 dataset, curated by Pierre-Luc Carrier and Aaron Courville, was developed for the Kaggle competition titled Challenges in Representation Learning: Facial Expression Recognition Challenge. All the dataset files can be downloaded and decompressed from here. This dataset provides a valuable resource for exploring challenges in representation learning and advancing facial expression recognition algorithms. There are more details about the dataset here.
The facial emotion recognition model is a Convolutional Neural Network (CNN) tailored for image classification, particularly designed to discern human emotions from facial expressions. Trained on the Kaggle Facial Expression Recognition Challenge dataset, the model exhibits a robust architecture comprising convolutional and fully connected layers. It employs a series of convolutional layers, each followed by Batch Normalization, ReLU activation, MaxPooling, and Dropout, culminating in a softmax-activated output layer for multiclass classification of seven emotions. To enhance performance and mitigate overfitting, the model integrates data augmentation techniques, including random horizontal flipping and contrast adjustments.
The resulting model is saved in HDF5 format as 'models/emotion_classifier.h5' for later deployment. Furthermore, the model is converted to TensorFlow Lite format ('models/emotion_classifier.tflite') to enable its deployment in resource-constrained environments, ensuring its versatility and accessibility across various platforms. The model currently has an accuracy of 65% and works particularly well on 'happy', 'anger' and 'sad' emotions. However, with more work, it's performance can be made much better.
git clone git@github.com:abhirup-ghosh/facial-expression-classifier-app.git
The easiest way to set up the environment is to use Anaconda. I used the standard Machine Learning Zoomcamp conda environment ml-zoomcamp
, which you can create, activate, and install the relevant libraries in, using the following commands in your terminal:
conda create -n ml-zoomcamp python=3.9 -y
conda activate ml-zoomcamp
conda install numpy pandas scikit-learn seaborn jupyter tensorflow -y
# install tflite-runtime
pip install --extra-index-url https://google-coral.github.io/py-repo/ tflite_runtime
Alternatively, I have also provided a conda environment.yml
file that can be directly used to create the environment:
conda env create -f opt/environment.yml
You can run the notebook on Google Colab. Details of the instance are:
- Notebook: Python3
- Hardware: Single T4 GPU
Package : Verion
--------------------
pandas : 1.5.3
numpy : 1.23.5
matplotlib : 3.7.1
seaborn : 0.12.2
sklearn : 1.2.2
pickle : 4.0
tensorflow : 2.14.0
This notebook outlines the entire investigation and consists of the following steps [π¨ Skip this step, if you want to directly want to use the final configuration for training and/or final model for predictions]:
- Data Loading:
data/icml_face_data.csv
- Data preprocessing
- Exploratory data analysis
- Setting up a validation framwork
- Model definition: CNN (+ data augmentation)
- Model evaluation [and hyper-parameter tuning]
- Saving the best model:
models/emotion_classifier.h5
- Preparation of the test data
- Making predictions using the saved model
- Convert to TF-Lite model:
models/emotion_classifier.tflite
- Remove TF dependency
We encode our best, tuned CNN model inside the scripts/train.py file which can be run using:
cd scripts
python train.py
The output of this script can be found in: models/*
. It has an average accuracy of 65% and will be used for the following steps. The training script also converts the keras model into a light-weight TF-lite model.
This notebook provides a step-by-step guide for preparing the Lambda Code:
- Use
tflite_runtime
model instead of Keras model - Remove any tensorflow/keras dependency on preprocessing/prediction
- Define
predict(url)
function to make prediction on an image url (input); output is a dictionary of emotion classes with respective probabilities. - Create
lambda_handler(event, context)
wrapper for callingpredict(url)
Once we test out the entire lambda framework using the above notebook, we convert it into a python script.
Test Event: Happy
event = {'url': 'https://upload.wikimedia.org/wikipedia/commons/0/09/The_joy_of_the_happy_face_by_Rasheedhrasheed.jpg'}
Prediction: Happy
facial-expression-classifier-app/scripts> python
Python 3.9.18 (main, Sep 11 2023, 08:20:50)
[Clang 14.0.6 ] :: Anaconda, Inc. on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import lambda_function
>>> event = {'url': 'https://upload.wikimedia.org/wikipedia/commons/0/09/The_joy_of_the_happy_face_by_Rasheedhrasheed.jpg'}
>>> lambda_function.lambda_handler(event, None)
{'Anger': 8.256378446588042e-35, 'Disgust': 2.9382650407717056e-39, 'Fear': 2.9382650407717056e-39, 'Happy': 1.0, 'Neutral': 0.0, 'Sadness': 0.0, 'Surprise': 0.0}
Run the Dockerfile
using [make sure that the docker daemon is running] to build the image facial-emotion-recognition
:
docker build -t facial-emotion-recognition .
Add the option --platform linux/amd64
if working on amd64 architecture, as I was, to identify the appropriate wheel for for TF-Lite (Tensorflow 2.14.0). Once the image is built, we need to expose the container port (8080) to the localhost port (8080) using:
docker run -it --rm -p 8080:8080 --platform linux/amd64 facial-emotion-recognition:latest
We can now make a request using our test script scripts/test.py
:
python test.py
# {'Anger': 8.252851389563724e-35, 'Disgust': 0.0, 'Fear': 0.0, 'Happy': 1.0, 'Neutral': 0.0, 'Sadness': 0.0, 'Surprise': 0.0}
Please follow the instructions detailed here to:
- build, tag and run docker container image
- create AWS elastic container registry (ECR) repository: facial-emotion-recognition
- publish docker container image to ECR repository as tagged image: facial-emotion-recognition-001
- create, configure and test AWS Lambda function
- create, configure and test AWS Rest API Gateway to access Lambda function
- make prediction using POST METHOD
/predict
Invoke URL: https://xowsdry1bc.execute-api.eu-north-1.amazonaws.com/Test/predict
β οΈ I have now deactivated this instance because it has reached the monthly limit allowed by AWS' FreeTier model
(base) $~> python scripts/test-aws-rest-api.py
{'Anger': 0.0, 'Disgust': 0.0, 'Fear': 0.0, 'Happy': 1.0, 'Neutral': 0.0, 'Sadness': 0.0, 'Surprise': 0.0}
facial-expression-classifier-app/
βββ Dockerfile
βββ LICENSE
βββ README.md
βββ data
βΒ Β βββ README.md
βΒ Β βββ challenges-in-representation...
βΒ Β βββ example_submission.csv
βΒ Β βββ fer2013
βΒ Β βΒ Β βββ README
βΒ Β βΒ Β βββ fer2013.bib
βΒ Β βΒ Β βββ fer2013.csv
βΒ Β βββ icml_face_data.csv
βΒ Β βββ test.csv
βΒ Β βββ train.csv
βββ docs
βΒ Β βββ deployment-AWS-instructions.md
βββ media
βΒ Β βββ banner.png
βΒ Β βββ class_counts.png
βΒ Β βββ emotions.png
βΒ Β βββ test_image_happy.jpeg
βββ models
βΒ Β βββ emotion_classifier.h5
βΒ Β βββ emotion_classifier.tflite
βββ notebooks
βΒ Β βββ notebook-lambda.ipynb
βΒ Β βββ notebook.ipynb
βββ opt
βΒ Β βββ environment.yml
βββ scripts
βββ lambda_function.py
βββ test-aws-rest-api.py
βββ test.py
βββ test_image_anger.jpg
βββ train.py
11 directories, 28 files
Improvement of CNN model: currently has an accuracy of 65% and works particularly well on 'happy', 'anger' and 'sad' emotions. However, it's overall performance and it's performance on other emotions can be improved with more work.
Dataset: extend to RGB images of higher resolution.
Abhirup Ghosh, abhirup.ghosh.184098@gmail.com
This project is licensed under the MIT License.
- Alexey Grigorev
- DataTalks.Club
- Pierre-Luc Carrier, Aaron Courville [data citation]
Your contributions and feedback are highly valuable to enhance the quality and functionality of this Facial Emotion Recognition (FER) Predictor project. Whether you identify a bug, suggest an improvement, or contribute code, your involvement is crucial for the project's success.
-
Issues and Bug Reports: If you encounter any issues or bugs, please create an issue. Include detailed information about the problem, steps to reproduce it, and any relevant screenshots.
-
Feature Requests: If you have ideas for new features or enhancements, feel free to submit a feature request on GitHub. Clearly outline the proposed feature and its potential benefits.
-
Code Contributions: If you are interested in contributing code, you can fork the repository and submit pull requests with your changes. Ensure that your code follows the project's coding standards and practices.
-
Documentation Improvements: Clear and comprehensive documentation is essential. If you find areas where the documentation can be improved, please let us know or directly submit a pull request to enhance it.
Your feedback is crucial for the continuous improvement of this project. If you have any suggestions, comments, or positive experiences related to the FER Predictor, please share them. Your insights can help shape the future development of this project and make it more effective for users. Thank you for your contributions and feedback, as they play a vital role in making this project better for everyone involved.
- Computer Vision
- Data augmentation
- Keras/Tensorflow/Tensorflow-Lite
- Convolutional Neural Networks
- Docker
- AWS Lambda
- AWS ECR
- AWS API Gateway
- REST API
- Web Service