haydenbanz commited on
Commit
3599d7d
·
1 Parent(s): ea71e0b

📝Updated app.py

Browse files
Files changed (1) hide show
  1. app.py +97 -0
app.py ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import torch
3
+ import torch.nn as nn
4
+ import torch.nn.functional as F
5
+ from torchvision import transforms
6
+ from PIL import Image
7
+ import os
8
+
9
+ # Define the device
10
+ device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
11
+
12
+ # Define the CNN model (must match the architecture used during training)
13
+ class EmotionCNN(nn.Module):
14
+ def __init__(self, num_classes=7): # Updated to 7 classes
15
+ super(EmotionCNN, self).__init__()
16
+ self.conv1 = nn.Conv2d(1, 32, kernel_size=3, padding=1) # 1 input channel for grayscale
17
+ self.pool = nn.MaxPool2d(2, 2)
18
+ self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
19
+ self.conv3 = nn.Conv2d(64, 128, kernel_size=3, padding=1)
20
+ self.flatten = nn.Flatten()
21
+ self.fc1 = nn.Linear(128 * 6 * 6, 128) # 48x48 -> 6x6 after 3 pooling layers
22
+ self.dropout = nn.Dropout(0.5)
23
+ self.fc2 = nn.Linear(128, num_classes) # Number of classes
24
+
25
+ def forward(self, x):
26
+ x = F.relu(self.conv1(x))
27
+ x = self.pool(x)
28
+ x = F.relu(self.conv2(x))
29
+ x = self.pool(x)
30
+ x = F.relu(self.conv3(x))
31
+ x = self.pool(x)
32
+ x = self.flatten(x)
33
+ x = F.relu(self.fc1(x))
34
+ x = self.dropout(x)
35
+ x = self.fc2(x)
36
+ return x
37
+
38
+ # Define the image preprocessing (must match training)
39
+ preprocess = transforms.Compose([
40
+ transforms.Grayscale(), # Convert to grayscale
41
+ transforms.Resize((48, 48)), # Resize to 48x48
42
+ transforms.ToTensor(), # Convert to tensor and normalize to [0, 1]
43
+ ])
44
+
45
+ # Load the class names (update this based on your training subfolders)
46
+ class_names = ['angry', 'disgusted', 'fearful', 'happy', 'neutral', 'sad', 'surprised'] # 7 classes
47
+
48
+ # Function to predict emotion from an image
49
+ def predict_emotion(image, model_path='emotion_model.pth'):
50
+ # Load the model
51
+ model = EmotionCNN(num_classes=len(class_names))
52
+ model.load_state_dict(torch.load(model_path, map_location=device))
53
+ model.to(device)
54
+ model.eval() # Set to evaluation mode
55
+
56
+ # Preprocess the image
57
+ try:
58
+ image = preprocess(image)
59
+ image = image.unsqueeze(0) # Add batch dimension (1, 1, 48, 48)
60
+ except Exception as e:
61
+ st.error(f"Error preprocessing image: {e}")
62
+ return None, None
63
+
64
+ # Perform prediction
65
+ with torch.no_grad():
66
+ image = image.to(device)
67
+ outputs = model(image)
68
+ probabilities = F.softmax(outputs, dim=1) # Convert to probabilities
69
+ confidence, predicted = torch.max(probabilities, 1) # Get highest probability and class
70
+ emotion = class_names[predicted.item()]
71
+ confidence_score = confidence.item() * 100 # Convert to percentage
72
+
73
+ return emotion, confidence_score
74
+
75
+ # Streamlit app
76
+ def main():
77
+ st.title("Emotion Detection App")
78
+ st.write("Upload an image to detect the emotion using a pre-trained model.")
79
+
80
+ # File uploader
81
+ uploaded_file = st.file_uploader("Choose an image...", type=["jpg", "png", "jpeg"])
82
+
83
+ if uploaded_file is not None:
84
+ # Display the uploaded image
85
+ image = Image.open(uploaded_file)
86
+ st.image(image, caption="Uploaded Image", use_column_width=True)
87
+
88
+ # Predict emotion
89
+ emotion, confidence = predict_emotion(image)
90
+
91
+ if emotion:
92
+ st.success(f"Predicted Emotion: **{emotion}** (Confidence: {confidence:.2f}%)")
93
+ else:
94
+ st.error("Failed to predict emotion. Please try another image.")
95
+
96
+ if __name__ == "__main__":
97
+ main()