avimittal30 commited on
Commit
f2aa636
·
1 Parent(s): 80e9b5e

adding files

Browse files
Dockerfile ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.9
2
+
3
+ RUN useradd -m -u 1000 user
4
+ USER user
5
+ ENV PATH="/home/user/.local/bin:$PATH"
6
+
7
+ WORKDIR /app
8
+
9
+ COPY --chown=user ./requirements.txt requirements.txt
10
+ RUN pip install --no-cache-dir --upgrade -r requirements.txt
11
+
12
+ COPY --chown=user . /app
13
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
EmotionDetection.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
Finetuning.png ADDED
README.md CHANGED
@@ -1,12 +1,26 @@
1
- ---
2
- title: Human Emotion Detection
3
- emoji: 👀
4
- colorFrom: yellow
5
- colorTo: purple
6
- sdk: docker
7
- pinned: false
8
- license: apache-2.0
9
- short_description: 'Finetuned efficient-net50 model to classify emotions '
10
- ---
11
-
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Human Emotion Detection
2
+ A full fledged application that detects human emotion from an Image.
3
+ In this project, I have finetuned Efficient model to achieve 80% accuracy on the validation dataset.
4
+
5
+ This project uses human emotions dataset from Kaggle to finetune efficientnet model
6
+
7
+ The application is created using flask framework and deployed on AWS EC2 instance . The docker image was pushed to ECR and pulled into EC2 instance using Github actions as a part of CI/CD pipeline implementation
8
+
9
+ I tried using TransferNet approach and Finetuning approach. With Transfernet, the model accuracy was only 63% while it increased to 80% with a finetuned model
10
+
11
+ ## Evaluation Metrics
12
+
13
+ Loss: 0.5
14
+ Accuracy: 80%
15
+ Top_k_accuracy: 93%
16
+
17
+ ### Example: How finetuning improved the model performance
18
+
19
+ Before finetuning, this image was incorrecly labeled as Sad
20
+
21
+ ![Incorrect labeling with transfer learning](TransferLearning.png)
22
+
23
+ After finetuning, this image was correctly labeled as happy
24
+
25
+ ![Correct labeling with finetuned model](Finetuning.png)
26
+
TransferLearning.png ADDED
app.py ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, request, render_template
2
+ import numpy as np
3
+ import tensorflow
4
+ from tensorflow.keras.models import load_model
5
+ from tensorflow.keras.preprocessing.image import img_to_array
6
+ import os
7
+ import tensorflow as tf
8
+ from PIL import Image
9
+ import cv2
10
+ from transformers import AutoModel
11
+ from huggingface_hub import hf_hub_download
12
+
13
+
14
+ # Loading trained model
15
+
16
+ os.environ["KERAS_BACKEND"] = "tensorflow"
17
+ import keras
18
+ model_path = hf_hub_download(repo_id="avimittal30/emotion_detector", filename="ed_model1.keras")
19
+ model = keras.models.load_model(model_path)
20
+
21
+ # model=load_model('my_model.keras')
22
+
23
+ app = Flask(__name__)
24
+
25
+
26
+ # Home route to render the upload form
27
+ @app.route('/')
28
+ def index():
29
+ return render_template('index.html')
30
+
31
+
32
+ # Prediction route
33
+ @app.route('/predict', methods=['POST'])
34
+ def predict():
35
+
36
+ if 'image' not in request.files:
37
+ return render_template('index.html', error='No image uploaded!')
38
+
39
+ file = request.files['image']
40
+
41
+
42
+ filepath = os.path.join('static', file.filename)
43
+ file.save(filepath)
44
+ print(f'filepath:{filepath}')
45
+ print(f'file:{file}')
46
+ # Process the image to be fed to the model for prediction
47
+ image = cv2.imread(filepath)
48
+ test_image = cv2.resize(image, (256 ,256))
49
+ im=tf.constant(test_image, dtype=tf.float32 ) # Resizing the image to make it compatible with model
50
+ im=tf.expand_dims(im, axis=0)
51
+ # Predict emotion
52
+ predictions = model.predict(im)
53
+ emotion_labels = ['Angry', 'Happy', 'Sad'] # Emotion labels
54
+ predicted_emotion = emotion_labels[np.argmax(predictions)]
55
+
56
+ return render_template('result.html', emotion=predicted_emotion, image_file=filepath)
57
+
58
+ if __name__ == '__main__':
59
+ # app.run(debug=True)
60
+ app.run(host="0.0.0.0", port=8080)
requirements.txt ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ tensorflow=2.18.0
2
+ numpy
3
+ matplotlib
4
+ scikit-learn
5
+ opencv-python-headless
6
+ seaborn
7
+ Pillow
8
+ albumentations
9
+ tensorflow-datasets
10
+ flask
11
+ huggingface_hub
12
+ transformers
13
+
14
+
static/styles.css ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Reset some default browser styles */
2
+ * {
3
+ margin: 0;
4
+ padding: 0;
5
+ box-sizing: border-box;
6
+ }
7
+
8
+ body {
9
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
10
+ background-color: #f3f4f6;
11
+ color: #333;
12
+ display: flex;
13
+ justify-content: center;
14
+ align-items: center;
15
+ height: 100vh;
16
+ margin: 0;
17
+ }
18
+
19
+ .container {
20
+ background: #ffffff;
21
+ border-radius: 10px;
22
+ box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
23
+ padding: 30px;
24
+ text-align: center;
25
+ width: 400px;
26
+ }
27
+
28
+ h1 {
29
+ font-size: 60px;
30
+ margin-bottom: 20px;
31
+ color: #00509d;
32
+ }
33
+
34
+ .upload-section {
35
+ margin-bottom: 20px;
36
+ }
37
+
38
+ .upload-btn {
39
+ display: inline-block;
40
+ background-color: #0078D7;
41
+ color: white;
42
+ padding: 10px 20px;
43
+ border-radius: 5px;
44
+ cursor: pointer;
45
+ transition: background-color 0.3s ease;
46
+ }
47
+
48
+ .upload-btn:hover {
49
+ background-color: #00509d;
50
+ }
51
+
52
+ #file-upload {
53
+ display: none;
54
+ }
55
+
56
+ .image-preview {
57
+ margin: 20px 0;
58
+ }
59
+
60
+ .image-preview img {
61
+ max-width: 100%;
62
+ border: 2px solid #0078D7;
63
+ border-radius: 8px;
64
+ height: auto;
65
+ }
66
+
67
+ .result-section {
68
+ margin-top: 20px;
69
+ }
70
+
71
+ .result-section h2 {
72
+ font-size: 20px;
73
+ margin-bottom: 10px;
74
+ color: #00509d;
75
+ }
76
+
77
+ .result-section p {
78
+ font-size: 16px;
79
+ color: #666;
80
+ }
static/test_image1.jpg ADDED
templates/index.html ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Emotion Detection App</title>
7
+ <link rel="stylesheet" href="/static/styles.css">
8
+ </head>
9
+ <body>
10
+ <div class="container">
11
+ <h1>Emotion Detection from Image</h1>
12
+
13
+ <!-- Upload Section -->
14
+ <div class="upload-section">
15
+ <!-- Form to upload the image -->
16
+ <form id="upload-form" action="/predict" method="POST" enctype="multipart/form-data">
17
+ <label for="file-upload" class="upload-btn">Upload Image</label>
18
+ <input type="file" id="file-upload" name="image" accept="image/*" onchange="previewImage(event)">
19
+ <button type="submit">Submit for Emotion Detection</button>
20
+ </form>
21
+ </div>
22
+
23
+ <!-- Image Preview -->
24
+ <div class="image-preview" id="image-preview">
25
+ <img id="output" alt="Your Image Preview Will Appear Here" />
26
+ </div>
27
+
28
+ <!-- Result Section -->
29
+ <div class="result-section">
30
+ <h2>Detected Emotion:</h2>
31
+ <p id="emotion-result">Upload an image to see the result.</p>
32
+ </div>
33
+ </div>
34
+
35
+ <script>
36
+ // Function to preview the selected image before upload
37
+ function previewImage(event) {
38
+ const output = document.getElementById('output');
39
+ output.src = URL.createObjectURL(event.target.files[0]);
40
+ output.onload = () => {
41
+ URL.revokeObjectURL(output.src); // Free memory after image is loaded
42
+ };
43
+ // Reset the motion detection result when a new image is selected
44
+ const emotionResult = document.getElementById('emotion-result');
45
+ emotionResult.innerText = "Image selected, ready for detection.";
46
+ }
47
+ </script>
48
+ </body>
49
+ </html>
templates/result.html ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Emotion Detection Result</title>
7
+ <style>
8
+ body {
9
+ font-family: Arial, sans-serif;
10
+ text-align: center;
11
+ background-color: #f0f0f0;
12
+ padding: 50px;
13
+ }
14
+ h1 {
15
+ color: #333;
16
+ }
17
+ img {
18
+ max-width: 300px;
19
+ height: auto;
20
+ border: 2px solid #333;
21
+ margin-top: 20px;
22
+ }
23
+ .result {
24
+ margin-top: 20px;
25
+ font-size: 24px;
26
+ font-weight: bold;
27
+ color: #333;
28
+ }
29
+ .back-button {
30
+ display: inline-block;
31
+ margin-top: 20px;
32
+ padding: 10px 20px;
33
+ background-color: #4CAF50;
34
+ color: white;
35
+ text-decoration: none;
36
+ border-radius: 5px;
37
+ }
38
+ </style>
39
+ </head>
40
+ <body>
41
+ <h1>Emotion Detection Result</h1>
42
+
43
+ <div class="result">
44
+ <p>Predicted Emotion: <strong>{{ emotion }}</strong></p>
45
+ </div>
46
+
47
+ <div>
48
+ <img src="{{ image_file }}" alt="Uploaded Image">
49
+ </div>
50
+
51
+ <a href="/" class="back-button">Try Again</a>
52
+ </body>
53
+ </html>
templates/styles.css ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Reset some default browser styles */
2
+ * {
3
+ margin: 0;
4
+ padding: 0;
5
+ box-sizing: border-box;
6
+ }
7
+
8
+ body {
9
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
10
+ background-color: #f3f4f6;
11
+ color: #333;
12
+ display: flex;
13
+ justify-content: center;
14
+ align-items: center;
15
+ height: 100vh;
16
+ margin: 0;
17
+ }
18
+
19
+ .container {
20
+ background: #ffffff;
21
+ border-radius: 10px;
22
+ box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
23
+ padding: 30px;
24
+ text-align: center;
25
+ width: 400px;
26
+ }
27
+
28
+ h1 {
29
+ font-size: 60px;
30
+ margin-bottom: 20px;
31
+ color: #00509d;
32
+ }
33
+
34
+ .upload-section {
35
+ margin-bottom: 20px;
36
+ }
37
+
38
+ .upload-btn {
39
+ display: inline-block;
40
+ background-color: #0078D7;
41
+ color: white;
42
+ padding: 10px 20px;
43
+ border-radius: 5px;
44
+ cursor: pointer;
45
+ transition: background-color 0.3s ease;
46
+ }
47
+
48
+ .upload-btn:hover {
49
+ background-color: #00509d;
50
+ }
51
+
52
+ #file-upload {
53
+ display: none;
54
+ }
55
+
56
+ .image-preview {
57
+ margin: 20px 0;
58
+ }
59
+
60
+ .image-preview img {
61
+ max-width: 100%;
62
+ border: 2px solid #0078D7;
63
+ border-radius: 8px;
64
+ height: auto;
65
+ }
66
+
67
+ .result-section {
68
+ margin-top: 20px;
69
+ }
70
+
71
+ .result-section h2 {
72
+ font-size: 20px;
73
+ margin-bottom: 10px;
74
+ color: #00509d;
75
+ }
76
+
77
+ .result-section p {
78
+ font-size: 16px;
79
+ color: #666;
80
+ }
test.py ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, request, render_template
2
+ import numpy as np
3
+ from tensorflow.keras.models import load_model
4
+ from tensorflow.keras.preprocessing.image import img_to_array
5
+ import os
6
+ # from PIL import Image
7
+ # import cv2
8
+
9
+ # Load your pre-trained model
10
+ model = load_model('my_model.keras') # Replace with your model path
11
+
12
+ filepath = os.path.join('static', file.filename)
13
+ file.save(filepath)
14
+
15
+ # Process the image
16
+ image = Image.open(file)
17
+ image = image.convert('RGB')
18
+ image = image.resize((48, 48)) # Resize the image for the model
19
+ image = img_to_array(image)
20
+ image = np.expand_dims(image, axis=0) / 255.0 # Normalize the image
21
+