sumittguptaa148 commited on
Commit
a452bfa
·
1 Parent(s): 16bb8d9

Add Gradio application and dependencies for deployment

Browse files
Files changed (3) hide show
  1. README.md +9 -9
  2. app.py +132 -0
  3. requirements.txt +7 -0
README.md CHANGED
@@ -1,14 +1,14 @@
1
  ---
2
- title: DL Gen AI Project
3
- emoji: 👀
4
- colorFrom: yellow
5
- colorTo: pink
6
  sdk: gradio
7
- sdk_version: 6.0.1
8
  app_file: app.py
9
- pinned: false
10
- license: apache-2.0
11
- short_description: DL Gen AI Project 2025
12
  ---
 
13
 
14
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
  ---
2
+ title: Multi-Label Emotion Classifier
3
+ emoji: 🧠
4
+ colorFrom: red
5
+ colorTo: green
6
  sdk: gradio
7
+ sdk_version: 3.48.0 # Use a recent stable version
8
  app_file: app.py
9
+ license: mit
 
 
10
  ---
11
+ # Multi-Label Emotion Classification using RoBERTa-Large
12
 
13
+ This Space deploys the winning model from the DL/GenAI project.
14
+ The model is a fine-tuned RoBERTa-Large transformer utilizing 5-Fold Cross-Validation and dynamic threshold optimization for superior Macro F1-Score.
app.py ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ import numpy as np
4
+ from transformers import AutoTokenizer, AutoModelForSequenceClassification
5
+
6
+ # --- Configuration ---
7
+ # Your Model's Hugging Face Repository ID
8
+ # NOTE: This assumes you successfully pushed the model during the CV loop!
9
+ HF_REPO_ID = "sumittguptaa148/DL-Gen-AI-Project"
10
+ MODEL_NAME = "roberta-large" # The base model name
11
+ MAX_LEN = 256
12
+ LABELS = ['anger', 'fear', 'joy', 'sadness', 'surprise']
13
+
14
+ # Optimized Thresholds from the latest output:
15
+ BEST_THRESHOLDS = {
16
+ 'anger': 0.64,
17
+ 'fear': 0.34,
18
+ 'joy': 0.79,
19
+ 'sadness': 0.78,
20
+ 'surprise': 0.48
21
+ }
22
+
23
+ # --- Load Model and Tokenizer ---
24
+ try:
25
+ # We load AutoModel for a custom architecture, but since we pushed
26
+ # using Trainer, the hub might save it with an AutoModelForSequenceClassification structure
27
+ # Let's try to load the base AutoModel and then load the state dict manually
28
+
29
+ # Load the tokenizer
30
+ tokenizer = AutoTokenizer.from_pretrained(HF_REPO_ID)
31
+
32
+ # Load the model weights and structure.
33
+ # We use AutoModelForSequenceClassification here as Hugging Face Trainer usually
34
+ # saves a classification head that is compatible with this class structure
35
+ # when pushing to the hub.
36
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
37
+ model = AutoModelForSequenceClassification.from_pretrained(HF_REPO_ID, num_labels=len(LABELS))
38
+ model.to(device)
39
+ model.eval()
40
+ print(f"Model and Tokenizer loaded from {HF_REPO_ID}")
41
+
42
+ except Exception as e:
43
+ print(f"Error loading model from Hugging Face Hub: {e}")
44
+ # Fallback/Dummy definitions for deployment setup
45
+ tokenizer = None
46
+ model = None
47
+ device = "cpu"
48
+
49
+
50
+ # --- Prediction Function ---
51
+ def predict_emotion(text):
52
+ if model is None:
53
+ return "Model failed to load. Please check logs."
54
+
55
+ # Tokenize input
56
+ inputs = tokenizer(
57
+ text,
58
+ padding=True,
59
+ truncation=True,
60
+ max_length=MAX_LEN,
61
+ return_tensors="pt"
62
+ )
63
+
64
+ # Move tensors to device
65
+ inputs = {k: v.to(device) for k, v in inputs.items()}
66
+
67
+ with torch.no_grad():
68
+ outputs = model(**inputs)
69
+ logits = outputs.logits.cpu().numpy()
70
+
71
+ # Convert logits to probabilities (sigmoid)
72
+ probs = 1 / (1 + np.exp(-logits))[0]
73
+
74
+ # Apply dynamic thresholds and format output
75
+ results = {}
76
+ for i, label in enumerate(LABELS):
77
+ prob = probs[i]
78
+ threshold = BEST_THRESHOLDS[label]
79
+
80
+ # Classification
81
+ is_present = " Present" if prob >= threshold else " Absent"
82
+
83
+ # Format for display
84
+ results[f"{label.capitalize()} ({is_present})"] = f"{prob:.4f} (Threshold: {threshold:.2f})"
85
+
86
+ return results
87
+
88
+ # --- Gradio Interface ---
89
+ # Output components for Gradio
90
+ output_components = [
91
+ gr.Textbox(label=f"{label.capitalize()} (Classification & Prob)", lines=1) for label in LABELS
92
+ ]
93
+
94
+ # Map output components to keys in the dictionary returned by predict_emotion
95
+ # Gradio expects the output component labels to match the dictionary keys
96
+ output_keys = [f"{label.capitalize()} ({{}})" for label in LABELS] # Placeholder for "Present/Absent" part
97
+
98
+ # Custom function to create the correct output components for Gradio
99
+ def get_output_components():
100
+ # Use Textbox for results
101
+ outputs = []
102
+ for label in LABELS:
103
+ outputs.append(gr.Textbox(label=f"{label.capitalize()} Emotion Result", lines=1))
104
+ return outputs
105
+
106
+
107
+ # Custom wrapper to ensure output matches the order of Gradio components
108
+ def predict_emotion_gradio(text):
109
+ raw_results = predict_emotion(text)
110
+
111
+ # Reorder results to match the output components list
112
+ ordered_results = []
113
+ for label in LABELS:
114
+ # Find the key that starts with the label (e.g., 'Anger (✅ Present)')
115
+ key_match = next(k for k in raw_results if k.startswith(label.capitalize()))
116
+ ordered_results.append(raw_results[key_match])
117
+
118
+ return tuple(ordered_results)
119
+
120
+
121
+ title = "Multi-Label Emotion Classification with RoBERTa-Large"
122
+ description = "A DL/GenAI project classifying text into Anger, Fear, Joy, Sadness, and Surprise. The model uses a fine-tuned RoBERTa-Large with 5-Fold CV and dynamic threshold optimization."
123
+
124
+ gr.Interface(
125
+ fn=predict_emotion_gradio,
126
+ inputs=gr.Textbox(lines=5, placeholder="Enter a sentence or short text here...", label="Input Text"),
127
+ outputs=get_output_components(), # Use the custom function to get ordered components
128
+ title=title,
129
+ description=description,
130
+ allow_flagging="never",
131
+ theme="huggingface"
132
+ ).launch()
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ torch
2
+ pandas
3
+ numpy
4
+ transformers
5
+ datasets
6
+ scikit-learn
7
+ gradio # Front-end framework