cs751 / app.py
fajarah's picture
Update app.py
69f23c0 verified
raw
history blame
5.88 kB
import gradio as gr
from transformers import AutoTokenizer, AutoModelForSequenceClassification, AutoImageProcessor, AutoModelForImageClassification
from torch.nn.functional import sigmoid
import torch
from PIL import Image
# Load text emotion model
model_name = "SamLowe/roberta-base-go_emotions"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(model_name)
# Load image emotion model
image_model_name = "Celal11/resnet-50-finetuned-FER2013-0.001"
image_processor = AutoImageProcessor.from_pretrained(image_model_name)
image_model = AutoModelForImageClassification.from_pretrained(image_model_name)
# Islamic advice mapping based on emotion
islamic_advice = {
"sadness": "\"Do not grieve; indeed Allah is with us.\"\n\n**Arabic:** ู„ูŽุง ุชูŽุญู’ุฒูŽู†ู’ ุฅูู†ู‘ูŽ ุงู„ู„ู‘ูŽู‡ูŽ ู…ูŽุนูŽู†ูŽุง\n(Qur'an, At-Tawbah 9:40)",
"joy": "\"If you are grateful, I will surely increase your favor.\"\n\n**Arabic:** ู„ูŽุฆูู† ุดูŽูƒูŽุฑู’ุชูู…ู’ ู„ูŽุฃูŽุฒููŠุฏูŽู†ู‘ูŽูƒูู…ู’\n(Qur'an, Ibrahim 14:7)",
"fear": "\"Sufficient for us is Allah, and [He is] the best Disposer of affairs.\"\n\n**Arabic:** ุญูŽุณู’ุจูู†ูŽุง ุงู„ู„ู‘ูŽู‡ู ูˆูŽู†ูุนู’ู…ูŽ ุงู„ู’ูˆูŽูƒููŠู„ู\n(Qur'an, Al Imran 3:173)",
"anger": "\"The strong is not the one who overcomes people by his strength, but the strong is the one who controls himself while in anger.\"\n\n(Hadith, Sahih al-Bukhari 6114)",
"confusion": "\"Seek help through patience and prayer.\"\n\n**Arabic:** ูˆูŽุงุณู’ุชูŽุนููŠู†ููˆุง ุจูุงู„ุตู‘ูŽุจู’ุฑู ูˆูŽุงู„ุตู‘ูŽู„ูŽุงุฉู\n(Qur'an, Al-Baqarah 2:45)",
"love": "\"Indeed, those who have believed and done righteous deeds - the Most Merciful will appoint for them affection.\"\n\n**Arabic:** ุณูŽูŠูŽุฌู’ุนูŽู„ู ู„ูŽู‡ูู…ู ุงู„ุฑู‘ูŽุญู’ู…ูŽูฐู†ู ูˆูุฏู‘ู‹ุง\n(Qur'an, Maryam 19:96)",
"neutral": "May Allah always guide your heart in every situation."
}
# Analyze image emotion using processor and model
def analyze_image_emotion(image):
if image is None:
return "No image provided.", ""
inputs = image_processor(images=image, return_tensors="pt")
with torch.no_grad():
logits = image_model(**inputs).logits
probs = torch.nn.functional.softmax(logits, dim=1)[0]
pred_idx = torch.argmax(probs).item()
label = image_model.config.id2label[pred_idx].lower()
score = probs[pred_idx].item()
islamic = islamic_advice.get(label, "May Allah always guide your heart.")
return f"{label.capitalize()} ({score:.2f})", islamic
# Emotion label to icon mapping (subset)
emotion_icons = {
"admiration": "๐Ÿ˜",
"amusement": "๐Ÿ˜…",
"anger": "๐Ÿ˜ก",
"annoyance": "๐Ÿ˜‘",
"approval": "๐Ÿ‘",
"caring": "๐Ÿ’—",
"confusion": "๐Ÿค”",
"curiosity": "๐Ÿ˜ฎ",
"desire": "๐Ÿคค",
"disappointment": "๐Ÿ˜ž",
"disapproval": "๐Ÿ‘Ž",
"disgust": "๐Ÿคฎ",
"embarrassment": "๐Ÿ˜ณ",
"excitement": "๐ŸŽ‰",
"fear": "๐Ÿ˜ฑ",
"gratitude": "๐Ÿ™",
"grief": "๐Ÿ˜ญ",
"joy": "๐Ÿ˜ƒ",
"love": "โค๏ธ",
"nervousness": "๐Ÿคง",
"optimism": "๐Ÿ˜Š",
"pride": "๐Ÿ˜Ž",
"realization": "๐Ÿคฏ",
"relief": "๐Ÿ˜Œ",
"remorse": "๐Ÿ˜”",
"sadness": "๐Ÿ˜ข",
"surprise": "๐Ÿ˜ฒ",
"neutral": "๐Ÿ˜"
}
# Analyze text emotion
def get_emotions(text, threshold):
inputs = tokenizer(text, return_tensors="pt", truncation=True, padding=True)
with torch.no_grad():
logits = model(**inputs).logits
probs = sigmoid(logits)[0]
top_idx = torch.argmax(probs).item()
top_label = model.config.id2label[top_idx].lower()
top_score = probs[top_idx].item()
islamic = islamic_advice.get(top_label, "May Allah always guide your heart.")
labels = [model.config.id2label[i] for i, p in enumerate(probs) if p > threshold]
icons = [emotion_icons.get(label, '') + ' ' + label.capitalize() + f" ({probs[i]:.2f})" for i, label in enumerate(labels)]
result = ", ".join(icons) if icons else "No strong emotion detected."
return result, islamic
# Combined analysis
def analyze_combined(text, threshold, image):
text_result, text_tip = get_emotions(text, threshold)
image_result, image_tip = analyze_image_emotion(image)
return text_result, text_tip, image_result, image_tip
# Gradio UI
custom_css = """
body {
background: linear-gradient(to right, #f9f9f9, #d4ecff);
font-family: 'Segoe UI', sans-serif;
}
.gr-button {
background-color: #007BFF !important;
color: white !important;
border-radius: 8px !important;
font-weight: bold;
}
.gr-button:hover {
background-color: #0056b3 !important;
}
.gr-textbox {
border-radius: 8px !important;
border: 1px solid #ccc !important;
padding: 10px !important;
}
.output-textbox {
font-size: 1.5rem;
font-weight: bold;
color: #333;
background-color: #f1f9ff;
border-radius: 8px;
padding: 10px;
border: 1px solid #007BFF;
}
"""
demo = gr.Interface(
fn=analyze_combined,
inputs=[
gr.Textbox(lines=5, placeholder="Write a sentence or a full paragraph...", label="Your Text"),
gr.Slider(minimum=0.1, maximum=0.9, value=0.3, step=0.05, label="Threshold"),
gr.Image(type="pil", label="Upload Face Photo")
],
outputs=[
gr.Textbox(label="Detected Text Emotions", elem_classes=["output-textbox"]),
gr.Textbox(label="Quranic/Hadith Advice (Text)", elem_classes=["output-textbox"]),
gr.Textbox(label="Detected Photo Emotion", elem_classes=["output-textbox"]),
gr.Textbox(label="Quranic/Hadith Advice (Image)", elem_classes=["output-textbox"])
],
title="๐Ÿฅฐ Multi-Modal Emotion Detector with Islamic Insight",
description="Analyze emotion from both text and a facial photo. Then receive inspirational Islamic advice based on your mood.",
theme="default",
css=custom_css
)
demo.launch()