File size: 4,779 Bytes
05c0ede
 
 
 
 
 
 
 
 
9aac9e6
05c0ede
 
 
 
 
 
 
 
 
dcbc1c4
05c0ede
 
dcbc1c4
05c0ede
 
 
dcbc1c4
05c0ede
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4ebb36c
05c0ede
 
4ebb36c
 
 
 
 
 
 
05c0ede
 
4ebb36c
 
 
 
 
 
 
05c0ede
 
4ebb36c
 
 
 
 
 
 
05c0ede
 
 
 
e66a248
 
 
 
 
 
 
 
 
 
 
05c0ede
 
 
e66a248
05c0ede
 
 
e66a248
05c0ede
2a6baa6
 
 
 
 
 
 
 
 
 
 
 
 
a2b61d5
2a6baa6
 
 
e66a248
3d7fdee
 
 
 
 
 
 
 
 
 
 
 
05c0ede
3d7fdee
 
 
 
 
05c0ede
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152

import torch
import torch.nn as nn
from torchvision import transforms
from PIL import Image
import gradio as gr
from transformers import pipeline

# Load emotion classes
classes = ['Angry', 'Disgust', 'Fear', 'Sad', 'Surprise', 'Neutral', 'Happy']

# Set device
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# Define the actual architecture used for training
class EmotionModel(nn.Module):
    def __init__(self):
        super(EmotionModel, self).__init__()
        self.model = nn.Sequential(
            nn.Conv2d(1, 32, 3, padding=1),   # Match 32 out_channels
            nn.ReLU(),
            nn.MaxPool2d(2, 2),
            nn.Conv2d(32, 64, 3, padding=1),  # Match 64 out_channels
            nn.ReLU(),
            nn.MaxPool2d(2, 2),
            nn.Flatten(),
            nn.Linear(64 * 12 * 12, 128),     # 64 filters * 12x12 features = 9216
            nn.ReLU(),
            nn.Linear(128, 7)
        )

    def forward(self, x):
        return self.model(x)

# Load the model
model = EmotionModel().to(device)
model.load_state_dict(torch.load("emotion_model.pth", map_location=device))
model.eval()

# Transformation
transform = transforms.Compose([
    transforms.Grayscale(),
    transforms.Resize((48, 48)),
    transforms.ToTensor(),
    transforms.Normalize((0.5,), (0.5,))
])

# NLP pipeline
gen = pipeline("text-generation", model="distilgpt2")

# Templates with emojis included now
templates = {
    "Friendly": {
        "Happy": "You seem cheerful 😊! ",
        "Sad": "You look down 😒. Here's something to cheer you up... ",
        "Angry": "Feeling heated 😠? Let's shift the vibe... ",
        "Fear": "A little nervous 😨? No worries, try this... ",
        "Disgust": "Something bugging you 🀒?",
        "Surprise": "Whoa! 😲 That was unexpected?",
        "Neutral": "Keeping it chill 😐?"
    },
    "Professional": {
        "Happy": "You look ready to go 😊.",
        "Sad": "You seem thoughtful 😒.",
        "Angry": "Tense vibes 😠.",
        "Fear": "Unsure? 😨",
        "Disgust": "Hey! Reset your focus 🀒",
        "Surprise": "Unexpected moment 😲?",
        "Neutral": "Yo! Are you redy for this 😐?"
    },
    "Funny": {
        "Happy": "You’re all smiles 😊!",
        "Sad": "You need a laugh 😒.",
        "Angry": "Cool it down 😠",
        "Fear": "Let’s laugh the fear away 😨: ",
        "Disgust": "Weird day 🀒?",
        "Surprise": "Surprise! 😲",
        "Neutral": "Let’s wake things up 😐 with a joke. "
    }
}

# Prediction logic
# Emotion to Emoji mapping
emotion_emojis = {
    "Angry": "😠",
    "Disgust": "🀒",
    "Fear": "😨",
    "Happy": "πŸ˜„",
    "Sad": "😒",
    "Surprise": "😲",
    "Neutral": "😐"
}

def predict_emotion_and_icebreaker(image, tone):
    image = Image.fromarray(image).convert("RGB")
    image = transform(image).unsqueeze(0).to(device)

    with torch.no_grad():
        output = model(image)
        pred = output.argmax(dim=1).item()

    emotion = classes[pred]

    # Emojis per emotion
    emotion_emojis = {
        "Happy": "😊", "Sad": "😒", "Angry": "😠",
        "Fear": "😨", "Disgust": "🀒", "Surprise": "😲", "Neutral": "😐"
    }

    emoji = emotion_emojis[emotion]
    tone_prefix = templates[tone][emotion]

    # Prompt for generation
    prompt = f"{tone_prefix} {emoji} Try saying:"

    response = gen(prompt, max_length=40, num_return_sequences=1, do_sample=True, temperature=0.7, top_k=50)[0]['generated_text']
    clean_response = response.replace(prompt, "").strip().split("\n")[0]

    return f"🧠 Emotion Detected: {emotion} {emoji}\nπŸ’¬ Icebreaker ({tone}):\n{clean_response}"

    # Generate icebreaker with better sampling
    generated = gen(
        prompt,
        max_length=60,
        num_return_sequences=1,
        do_sample=True,
        temperature=0.9,
        top_p=0.95
    )[0]['generated_text']

    # Remove the prompt part from the response
    response = generated[len(prompt):].strip()

    # Fallback if no content was generated
    if not response:
        response = "Here's a fun question to get started: What's your hidden talent?"

    return f"🧠 Emotion Detected: {emotion}\nπŸ’¬ Icebreaker ({tone}):\n{response}"
# Interface
webcam_input = gr.Image(type="numpy", label="Upload or Take a Photo")
tone_dropdown = gr.Dropdown(choices=["Friendly", "Professional", "Funny"], value="Friendly", label="Tone")

demo = gr.Interface(
    fn=predict_emotion_and_icebreaker,
    inputs=[webcam_input, tone_dropdown],
    outputs="text",
    title="Emotion + Icebreaker Generator",
    description="Upload or capture a face photo. AI will predict the emotion and generate a tone-specific conversation starter."
)

demo.launch()