logasanjeev commited on
Commit
b5fc4a7
Β·
verified Β·
1 Parent(s): 4df5a3d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +78 -226
app.py CHANGED
@@ -1,7 +1,6 @@
1
  import gradio as gr
2
  import pandas as pd
3
  import plotly.express as px
4
- import plotly.graph_objects as go
5
  import shutil
6
  import os
7
  import torch
@@ -26,10 +25,10 @@ _, _ = predict_emotions("dummy text")
26
  emotion_labels = inference_module.EMOTION_LABELS
27
  default_thresholds = inference_module.THRESHOLDS
28
 
29
- # Prediction function with export capability
30
- def predict_emotions_with_details(text, confidence_threshold=0.0, chart_type="bar"):
31
  if not text.strip():
32
- return "Please enter some text.", "", "", None, None, False
33
 
34
  predictions_str, processed_text = predict_emotions(text)
35
 
@@ -40,7 +39,7 @@ def predict_emotions_with_details(text, confidence_threshold=0.0, chart_type="ba
40
  emotion, confidence = line.split(": ")
41
  predictions.append((emotion, float(confidence)))
42
 
43
- # Get raw logits for all emotions
44
  encodings = inference_module.TOKENIZER(
45
  processed_text,
46
  padding='max_length',
@@ -55,12 +54,6 @@ def predict_emotions_with_details(text, confidence_threshold=0.0, chart_type="ba
55
  outputs = inference_module.MODEL(input_ids, attention_mask=attention_mask)
56
  logits = torch.sigmoid(outputs.logits).cpu().numpy()[0]
57
 
58
- # All emotions for top 5
59
- all_emotions = [(emotion_labels[i], round(logit, 4)) for i, logit in enumerate(logits)]
60
- all_emotions.sort(key=lambda x: x[1], reverse=True)
61
- top_5_emotions = all_emotions[:5]
62
- top_5_output = "\n".join([f"{emotion}: {confidence:.4f}" for emotion, confidence in top_5_emotions])
63
-
64
  # Filter predictions based on threshold
65
  filtered_predictions = []
66
  for emotion, confidence in predictions:
@@ -74,143 +67,73 @@ def predict_emotions_with_details(text, confidence_threshold=0.0, chart_type="ba
74
  else:
75
  thresholded_output = "\n".join([f"{emotion}: {confidence:.4f}" for emotion, confidence in filtered_predictions])
76
 
77
- # Create visualization
78
  fig = None
79
- df_export = None
80
  if filtered_predictions:
81
  df = pd.DataFrame(filtered_predictions, columns=["Emotion", "Confidence"])
82
- df_export = df.copy()
83
-
84
- if chart_type == "bar":
85
- fig = px.bar(
86
- df,
87
- x="Emotion",
88
- y="Confidence",
89
- color="Emotion",
90
- text="Confidence",
91
- title="Emotion Confidence Levels (Above Threshold)",
92
- height=400,
93
- color_discrete_sequence=px.colors.qualitative.Plotly
94
- )
95
- fig.update_traces(texttemplate='%{text:.2f}', textposition='auto')
96
- fig.update_layout(showlegend=False, margin=dict(t=40, b=40), xaxis_title="", yaxis_title="Confidence")
97
- else: # pie chart
98
- fig = px.pie(
99
- df,
100
- names="Emotion",
101
- values="Confidence",
102
- title="Emotion Confidence Distribution (Above Threshold)",
103
- height=400,
104
- color_discrete_sequence=px.colors.qualitative.Plotly
105
- )
106
- fig.update_traces(textinfo='percent+label', pull=[0.1] + [0] * (len(df) - 1))
107
- fig.update_layout(margin=dict(t=40, b=40))
108
 
109
- return processed_text, thresholded_output, top_5_output, fig, df_export, True
110
 
111
- # Custom CSS for enhanced styling
112
  custom_css = """
113
  body {
114
- font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
115
- background-color: #f5f7fa;
116
  }
117
  .gr-panel {
118
- border-radius: 16px;
119
- box-shadow: 0 6px 20px rgba(0,0,0,0.08);
120
  background: white;
121
- padding: 20px;
122
- margin-bottom: 20px;
123
  }
124
  .gr-button {
125
- border-radius: 8px;
126
- padding: 12px 24px;
127
- font-weight: 600;
128
- transition: all 0.3s ease;
129
- }
130
- .gr-button-primary {
131
  background: #4a90e2;
132
  color: white;
 
133
  }
134
- .gr-button-primary:hover {
135
  background: #357abd;
136
  }
137
- .gr-button-secondary {
138
- background: #e4e7eb;
139
- color: #333;
140
- }
141
- .gr-button-secondary:hover {
142
- background: #d1d5db;
143
- }
144
  #title {
145
- font-size: 2.8em;
146
- font-weight: 700;
147
- color: #1a3c6e;
148
  text-align: center;
149
  margin-bottom: 10px;
150
  }
151
  #description {
152
- font-size: 1.2em;
153
- color: #555;
154
- text-align: center;
155
- max-width: 800px;
156
- margin: 0 auto 30px auto;
157
- }
158
- #theme-toggle {
159
- position: fixed;
160
- top: 20px;
161
- right: 20px;
162
- background: none;
163
- border: none;
164
- font-size: 1.5em;
165
- cursor: pointer;
166
- transition: transform 0.3s;
167
- }
168
- #theme-toggle:hover {
169
- transform: scale(1.2);
170
- }
171
- .dark-mode {
172
- background: #1e2a44;
173
- color: #e0e0e0;
174
- }
175
- .dark-mode .gr-panel {
176
- background: #2a3a5a;
177
- box-shadow: 0 6px 20px rgba(0,0,0,0.2);
178
- }
179
- .dark-mode #title {
180
- color: #66b3ff;
181
- }
182
- .dark-mode #description {
183
- color: #b0b0b0;
184
- }
185
- .dark-mode .gr-button-secondary {
186
- background: #3a4a6a;
187
- color: #e0e0e0;
188
- }
189
- .dark-mode .gr-button-secondary:hover {
190
- background: #4a5a7a;
191
- }
192
- #loading {
193
- font-style: italic;
194
- color: #888;
195
  text-align: center;
196
- display: none;
197
- }
198
- #loading.visible {
199
- display: block;
200
  }
201
  #examples-title {
202
- font-size: 1.5em;
203
- font-weight: 600;
204
- color: #1a3c6e;
205
  margin-bottom: 10px;
206
  }
207
- .dark-mode #examples-title {
208
- color: #66b3ff;
209
- }
210
  footer {
211
  text-align: center;
212
- margin-top: 40px;
213
- padding: 20px;
214
  font-size: 0.9em;
215
  color: #666;
216
  }
@@ -221,148 +144,77 @@ footer a {
221
  footer a:hover {
222
  text-decoration: underline;
223
  }
224
- .dark-mode footer {
225
- color: #b0b0b0;
226
- }
227
- """
228
-
229
- # JavaScript for theme toggle
230
- theme_js = """
231
- function toggleTheme() {
232
- document.body.classList.toggle('dark-mode');
233
- const toggleBtn = document.getElementById('theme-toggle');
234
- toggleBtn.innerHTML = document.body.classList.contains('dark-mode') ? 'β˜€οΈ' : 'πŸŒ™';
235
- }
236
- function showLoading() {
237
- document.getElementById('loading').classList.add('visible');
238
- }
239
- function hideLoading() {
240
- document.getElementById('loading').classList.remove('visible');
241
- }
242
  """
243
 
244
- # Gradio Blocks UI
245
  with gr.Blocks(css=custom_css) as demo:
246
- # Theme toggle button
247
- gr.HTML(
248
- """
249
- <button id='theme-toggle' onclick='toggleTheme()'>πŸŒ™</button>
250
- <script>{}</script>
251
- """.format(theme_js)
252
- )
253
-
254
  # Header
255
  gr.Markdown("<div id='title'>GoEmotions BERT Classifier</div>", elem_id="title")
256
  gr.Markdown(
257
  """
258
  <div id='description'>
259
- Predict emotions from text using a fine-tuned BERT-base model on the GoEmotions dataset.
260
- Detect 28 emotions with optimized thresholds (Micro F1: 0.6006).
261
- View preprocessed text, top 5 emotions, and thresholded predictions with interactive visualizations!
262
  </div>
263
  """,
264
  elem_id="description"
265
  )
266
 
267
- # Main content
268
- with gr.Row():
269
- with gr.Column(scale=1):
270
- # Input Section
271
- with gr.Group():
272
- gr.Markdown("### Input Text")
273
- text_input = gr.Textbox(
274
- label="Enter Your Text",
275
- placeholder="Type something like 'I’m just chilling today'...",
276
- lines=3,
277
- show_label=False
278
- )
279
- confidence_slider = gr.Slider(
280
- minimum=0.0,
281
- maximum=0.9,
282
- value=0.0,
283
- step=0.05,
284
- label="Minimum Confidence Threshold",
285
- info="Filter predictions below this confidence level (default thresholds still apply)"
286
- )
287
- chart_type = gr.Radio(
288
- choices=["bar", "pie"],
289
- value="bar",
290
- label="Chart Type",
291
- info="Choose how to visualize the emotion confidences"
292
- )
293
- with gr.Row():
294
- submit_btn = gr.Button("Predict Emotions", variant="primary")
295
- reset_btn = gr.Button("Reset", variant="secondary")
296
-
297
- # Loading indicator
298
- loading_indicator = gr.HTML("<div id='loading'>Predicting emotions, please wait...</div>")
299
 
300
  # Output Section
301
- with gr.Row():
302
- with gr.Column(scale=1):
303
- with gr.Group():
304
- gr.Markdown("### Results")
305
- processed_text_output = gr.Textbox(label="Preprocessed Text", lines=2, interactive=False)
306
- thresholded_output = gr.Textbox(label="Predicted Emotions (Above Threshold)", lines=5, interactive=False)
307
- top_5_output = gr.Textbox(label="Top 5 Emotions (Regardless of Threshold)", lines=5, interactive=False)
308
- output_plot = gr.Plot(label="Emotion Confidence Visualization (Above Threshold)")
309
-
310
- # Export predictions
311
- export_btn = gr.File(label="Download Predictions as CSV", visible=False)
312
 
313
  # Example carousel
314
  with gr.Group():
315
- gr.Markdown("<div id='examples-title'>Example Texts</div>", elem_id="examples-title")
316
  examples = gr.Examples(
317
  examples=[
318
- ["I’m just chilling today.", "Neutral Example"],
319
- ["Thank you for saving my life!", "Gratitude Example"],
320
- ["I’m nervous about my exam tomorrow.", "Nervousness Example"],
321
- ["I love my new puppy so much!", "Love Example"],
322
- ["I’m so relieved the storm passed.", "Relief Example"]
323
  ],
324
  inputs=[text_input],
325
- label="",
326
- examples_per_page=3
327
  )
328
 
329
  # Footer
330
  gr.HTML(
331
  """
332
  <footer>
333
- Built with ❀️ by logasanjeev |
334
  <a href="https://huggingface.co/logasanjeev/goemotions-bert">Model Card</a> |
335
- <a href="https://www.kaggle.com/code/ravindranlogasanjeev/evaluation-logasanjeev-goemotions-bert/notebook">Kaggle Notebook</a> |
336
- <a href="https://github.com/logasanjeev">GitHub</a>
337
  </footer>
338
  """
339
  )
340
 
341
- # State to manage loading visibility
342
- loading_state = gr.State(value=False)
343
-
344
- # Bind predictions with loading spinner
345
- def start_loading():
346
- return True
347
-
348
- def stop_loading(processed_text, thresholded_output, top_5_output, fig, df_export, loading_state):
349
- return processed_text, thresholded_output, top_5_output, fig, df_export, False
350
-
351
  submit_btn.click(
352
- fn=start_loading,
353
- inputs=[],
354
- outputs=[loading_state]
355
- ).then(
356
  fn=predict_emotions_with_details,
357
- inputs=[text_input, confidence_slider, chart_type],
358
- outputs=[processed_text_output, thresholded_output, top_5_output, output_plot, export_btn, loading_state]
359
- )
360
-
361
- # Reset functionality
362
- reset_btn.click(
363
- fn=lambda: ("", "", "", None, None, False),
364
- inputs=[],
365
- outputs=[text_input, processed_text_output, thresholded_output, top_5_output, output_plot, export_btn, loading_state]
366
  )
367
 
368
  # Launch
 
1
  import gradio as gr
2
  import pandas as pd
3
  import plotly.express as px
 
4
  import shutil
5
  import os
6
  import torch
 
25
  emotion_labels = inference_module.EMOTION_LABELS
26
  default_thresholds = inference_module.THRESHOLDS
27
 
28
+ # Prediction function (simplified, no export)
29
+ def predict_emotions_with_details(text, confidence_threshold=0.0):
30
  if not text.strip():
31
+ return "Please enter some text.", "", None
32
 
33
  predictions_str, processed_text = predict_emotions(text)
34
 
 
39
  emotion, confidence = line.split(": ")
40
  predictions.append((emotion, float(confidence)))
41
 
42
+ # Get raw logits for top 5 (though not displayed in this simplified version)
43
  encodings = inference_module.TOKENIZER(
44
  processed_text,
45
  padding='max_length',
 
54
  outputs = inference_module.MODEL(input_ids, attention_mask=attention_mask)
55
  logits = torch.sigmoid(outputs.logits).cpu().numpy()[0]
56
 
 
 
 
 
 
 
57
  # Filter predictions based on threshold
58
  filtered_predictions = []
59
  for emotion, confidence in predictions:
 
67
  else:
68
  thresholded_output = "\n".join([f"{emotion}: {confidence:.4f}" for emotion, confidence in filtered_predictions])
69
 
70
+ # Create bar chart
71
  fig = None
 
72
  if filtered_predictions:
73
  df = pd.DataFrame(filtered_predictions, columns=["Emotion", "Confidence"])
74
+ fig = px.bar(
75
+ df,
76
+ x="Emotion",
77
+ y="Confidence",
78
+ color="Emotion",
79
+ text="Confidence",
80
+ title="Emotion Confidence Levels",
81
+ height=300,
82
+ color_discrete_sequence=px.colors.qualitative.Pastel
83
+ )
84
+ fig.update_traces(texttemplate='%{text:.2f}', textposition='auto')
85
+ fig.update_layout(showlegend=False, margin=dict(t=40, b=40), xaxis_title="", yaxis_title="Confidence")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
 
87
+ return processed_text, thresholded_output, fig
88
 
89
+ # Simplified CSS
90
  custom_css = """
91
  body {
92
+ font-family: 'Arial', sans-serif;
93
+ background-color: #f9f9f9;
94
  }
95
  .gr-panel {
96
+ border-radius: 8px;
97
+ box-shadow: 0 2px 10px rgba(0,0,0,0.05);
98
  background: white;
99
+ padding: 15px;
100
+ margin-bottom: 15px;
101
  }
102
  .gr-button {
103
+ border-radius: 6px;
104
+ padding: 10px 20px;
105
+ font-weight: 500;
 
 
 
106
  background: #4a90e2;
107
  color: white;
108
+ transition: background 0.3s ease;
109
  }
110
+ .gr-button:hover {
111
  background: #357abd;
112
  }
 
 
 
 
 
 
 
113
  #title {
114
+ font-size: 2.2em;
115
+ font-weight: 600;
116
+ color: #333;
117
  text-align: center;
118
  margin-bottom: 10px;
119
  }
120
  #description {
121
+ font-size: 1.1em;
122
+ color: #666;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  text-align: center;
124
+ max-width: 600px;
125
+ margin: 0 auto 20px auto;
 
 
126
  }
127
  #examples-title {
128
+ font-size: 1.3em;
129
+ font-weight: 500;
130
+ color: #333;
131
  margin-bottom: 10px;
132
  }
 
 
 
133
  footer {
134
  text-align: center;
135
+ margin-top: 30px;
136
+ padding: 15px;
137
  font-size: 0.9em;
138
  color: #666;
139
  }
 
144
  footer a:hover {
145
  text-decoration: underline;
146
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  """
148
 
149
+ # Gradio Blocks UI (Simplified)
150
  with gr.Blocks(css=custom_css) as demo:
 
 
 
 
 
 
 
 
151
  # Header
152
  gr.Markdown("<div id='title'>GoEmotions BERT Classifier</div>", elem_id="title")
153
  gr.Markdown(
154
  """
155
  <div id='description'>
156
+ Predict emotions from text using a fine-tuned BERT model.
157
+ Enter your text below to see the detected emotions and their confidence scores.
 
158
  </div>
159
  """,
160
  elem_id="description"
161
  )
162
 
163
+ # Input Section
164
+ with gr.Group():
165
+ text_input = gr.Textbox(
166
+ label="Enter Your Text",
167
+ placeholder="Type something like 'I’m just chilling today'...",
168
+ lines=2,
169
+ show_label=False
170
+ )
171
+ confidence_slider = gr.Slider(
172
+ minimum=0.0,
173
+ maximum=0.9,
174
+ value=0.0,
175
+ step=0.05,
176
+ label="Minimum Confidence Threshold",
177
+ info="Filter predictions below this confidence level (default thresholds still apply)"
178
+ )
179
+ submit_btn = gr.Button("Predict Emotions")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
 
181
  # Output Section
182
+ with gr.Group():
183
+ processed_text_output = gr.Textbox(label="Preprocessed Text", lines=1, interactive=False)
184
+ thresholded_output = gr.Textbox(label="Predicted Emotions", lines=3, interactive=False)
185
+ output_plot = gr.Plot(label="Emotion Confidence Chart")
 
 
 
 
 
 
 
186
 
187
  # Example carousel
188
  with gr.Group():
189
+ gr.Markdown("<div id='examples-title'>Try These Examples</div>", elem_id="examples-title")
190
  examples = gr.Examples(
191
  examples=[
192
+ ["I’m thrilled to win this award! πŸ˜„", "Joy Example"],
193
+ ["This is so frustrating, nothing works. 😣", "Annoyance Example"],
194
+ ["I feel so sorry for what happened. 😒", "Sadness Example"],
195
+ ["What a beautiful day to be alive! 🌞", "Admiration Example"],
196
+ ["Feeling nervous about the exam tomorrow πŸ˜“ u/student r/study", "Nervousness Example"]
197
  ],
198
  inputs=[text_input],
199
+ label=""
 
200
  )
201
 
202
  # Footer
203
  gr.HTML(
204
  """
205
  <footer>
206
+ Built by logasanjeev |
207
  <a href="https://huggingface.co/logasanjeev/goemotions-bert">Model Card</a> |
208
+ <a href="https://www.kaggle.com/code/ravindranlogasanjeev/evaluation-logasanjeev-goemotions-bert/notebook">Kaggle Notebook</a>
 
209
  </footer>
210
  """
211
  )
212
 
213
+ # Bind predictions
 
 
 
 
 
 
 
 
 
214
  submit_btn.click(
 
 
 
 
215
  fn=predict_emotions_with_details,
216
+ inputs=[text_input, confidence_slider],
217
+ outputs=[processed_text_output, thresholded_output, output_plot]
 
 
 
 
 
 
 
218
  )
219
 
220
  # Launch