logasanjeev commited on
Commit
65303d3
·
verified ·
1 Parent(s): 273c895

Upload README.markdown

Browse files
Files changed (1) hide show
  1. README.markdown +484 -0
README.markdown ADDED
@@ -0,0 +1,484 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ language: en
3
+ license: mit
4
+ pipeline_tag: text-classification
5
+ tags:
6
+ - text-classification
7
+ - transformers
8
+ - pytorch
9
+ - onnx
10
+ - Tensorflow
11
+ - multi-label-classification
12
+ - multi-class-classification
13
+ - emotion
14
+ - bert
15
+ - go_emotions
16
+ - emotion-classification
17
+ datasets:
18
+ - google-research-datasets/go_emotions
19
+ metrics:
20
+ - f1
21
+ - precision
22
+ - recall
23
+ widget:
24
+ - text: I’m just chilling today.
25
+ example_title: Neutral Example
26
+ - text: Thank you for saving my life!
27
+ example_title: Gratitude Example
28
+ - text: I’m nervous about my exam tomorrow.
29
+ example_title: Nervousness Example
30
+ - text: I love my new puppy so much!
31
+ example_title: Love Example
32
+ - text: I’m so relieved the storm passed.
33
+ example_title: Relief Example
34
+ base_model:
35
+ - google-bert/bert-base-uncased
36
+ model-index:
37
+ - name: GoEmotions BERT Classifier
38
+ results:
39
+ - task:
40
+ type: multi-label-classification
41
+ dataset:
42
+ name: GoEmotions
43
+ type: google-research-datasets/go_emotions
44
+ metrics:
45
+ - name: Micro F1 (Optimized Thresholds)
46
+ type: micro-f1
47
+ value: 0.6006
48
+ - name: Macro F1
49
+ type: macro-f1
50
+ value: 0.5390
51
+ - name: Precision
52
+ type: precision
53
+ value: 0.5371
54
+ - name: Recall
55
+ type: recall
56
+ value: 0.6812
57
+ - name: Hamming Loss
58
+ type: hamming-loss
59
+ value: 0.0377
60
+ - name: Avg Positive Predictions
61
+ type: avg-positive-predictions
62
+ value: 1.4789
63
+ - task:
64
+ type: multi-label-classification
65
+ dataset:
66
+ name: GoEmotions
67
+ type: google-research-datasets/go_emotions
68
+ metrics:
69
+ - name: F1 (admiration)
70
+ type: f1
71
+ value: 0.6987
72
+ - name: F1 (amusement)
73
+ type: f1
74
+ value: 0.8071
75
+ - name: F1 (anger)
76
+ type: f1
77
+ value: 0.5030
78
+ - name: F1 (annoyance)
79
+ type: f1
80
+ value: 0.3892
81
+ - name: F1 (approval)
82
+ type: f1
83
+ value: 0.3915
84
+ - name: F1 (caring)
85
+ type: f1
86
+ value: 0.4473
87
+ - name: F1 (confusion)
88
+ type: f1
89
+ value: 0.4714
90
+ - name: F1 (curiosity)
91
+ type: f1
92
+ value: 0.5781
93
+ - name: F1 (desire)
94
+ type: f1
95
+ value: 0.5229
96
+ - name: F1 (disappointment)
97
+ type: f1
98
+ value: 0.3333
99
+ - name: F1 (disapproval)
100
+ type: f1
101
+ value: 0.4323
102
+ - name: F1 (disgust)
103
+ type: f1
104
+ value: 0.4926
105
+ - name: F1 (embarrassment)
106
+ type: f1
107
+ value: 0.4912
108
+ - name: F1 (excitement)
109
+ type: f1
110
+ value: 0.4571
111
+ - name: F1 (fear)
112
+ type: f1
113
+ value: 0.5860
114
+ - name: F1 (gratitude)
115
+ type: f1
116
+ value: 0.9102
117
+ - name: F1 (grief)
118
+ type: f1
119
+ value: 0.3333
120
+ - name: F1 (joy)
121
+ type: f1
122
+ value: 0.6135
123
+ - name: F1 (love)
124
+ type: f1
125
+ value: 0.8065
126
+ - name: F1 (nervousness)
127
+ type: f1
128
+ value: 0.4348
129
+ - name: F1 (optimism)
130
+ type: f1
131
+ value: 0.5564
132
+ - name: F1 (pride)
133
+ type: f1
134
+ value: 0.5217
135
+ - name: F1 (realization)
136
+ type: f1
137
+ value: 0.2513
138
+ - name: F1 (relief)
139
+ type: f1
140
+ value: 0.5833
141
+ - name: F1 (remorse)
142
+ type: f1
143
+ value: 0.6800
144
+ - name: F1 (sadness)
145
+ type: f1
146
+ value: 0.5570
147
+ - name: F1 (surprise)
148
+ type: f1
149
+ value: 0.5562
150
+ - name: F1 (neutral)
151
+ type: f1
152
+ value: 0.6867
153
+ source:
154
+ name: Kaggle Evaluation Notebook
155
+ url: https://www.kaggle.com/code/ravindranlogasanjeev/evaluation-logasanjeev-goemotions-bert/notebook
156
+ ---
157
+
158
+ # GoEmotions BERT Classifier
159
+
160
+ Fine-tuned [BERT-base-uncased](https://huggingface.co/bert-base-uncased) on [GoEmotions](https://huggingface.co/datasets/go_emotions) for multi-label classification (28 emotions). This updated version includes improved Macro F1, ONNX support for efficient inference, and visualizations for better interpretability.
161
+
162
+ ## Model Details
163
+
164
+ - **Architecture**: BERT-base-uncased (110M parameters)
165
+ - **Training Data**: [GoEmotions](https://huggingface.co/datasets/google-research-datasets/go_emotions) (58k Reddit comments, 28 emotions)
166
+ - **Loss Function**: Focal Loss (alpha=1, gamma=2)
167
+ - **Optimizer**: AdamW (lr=2e-5, weight_decay=0.01)
168
+ - **Epochs**: 5
169
+ - **Batch Size**: 16
170
+ - **Max Length**: 128
171
+ - **Hardware**: Kaggle P100 GPU (16GB)
172
+
173
+ ## Try It Out
174
+
175
+ For accurate predictions with optimized thresholds, use the [Gradio demo](https://logasanjeev-goemotions-bert-demo.hf.space). The demo now includes preprocessed text and the top 5 predicted emotions, in addition to thresholded predictions. Example predictions:
176
+
177
+ - **Input**: "I’m thrilled to win this award! 😄"
178
+ - **Output**: `excitement: 0.5836, joy: 0.5290`
179
+ - **Input**: "This is so frustrating, nothing works. 😣"
180
+ - **Output**: `annoyance: 0.6147, anger: 0.4669`
181
+ - **Input**: "I feel so sorry for what happened. 😢"
182
+ - **Output**: `sadness: 0.5321, remorse: 0.9107`
183
+
184
+ ## Performance
185
+
186
+ - **Micro F1**: 0.6006 (optimized thresholds)
187
+ - **Macro F1**: 0.5390
188
+ - **Precision**: 0.5371
189
+ - **Recall**: 0.6812
190
+ - **Hamming Loss**: 0.0377
191
+ - **Avg Positive Predictions**: 1.4789
192
+
193
+ For a detailed evaluation, including class-wise accuracy, precision, recall, F1, MCC, support, and thresholds, along with visualizations, check out the [Kaggle notebook](https://www.kaggle.com/code/ravindranlogasanjeev/evaluation-logasanjeev-goemotions-bert/notebook).
194
+
195
+ ### Class-Wise Performance
196
+
197
+ The following table shows per-class metrics on the test set using optimized thresholds (see `optimized_thresholds.json`):
198
+
199
+ | Emotion | Accuracy | Precision | Recall | F1 Score | MCC | Support | Threshold |
200
+ |---------------|----------|-----------|--------|----------|--------|---------|-----------|
201
+ | admiration | 0.9410 | 0.6649 | 0.7361 | 0.6987 | 0.6672 | 504 | 0.4500 |
202
+ | amusement | 0.9801 | 0.7635 | 0.8561 | 0.8071 | 0.7981 | 264 | 0.4500 |
203
+ | anger | 0.9694 | 0.6176 | 0.4242 | 0.5030 | 0.4970 | 198 | 0.4500 |
204
+ | annoyance | 0.9121 | 0.3297 | 0.4750 | 0.3892 | 0.3502 | 320 | 0.3500 |
205
+ | approval | 0.8843 | 0.2966 | 0.5755 | 0.3915 | 0.3572 | 351 | 0.3500 |
206
+ | caring | 0.9759 | 0.5196 | 0.3926 | 0.4473 | 0.4396 | 135 | 0.4500 |
207
+ | confusion | 0.9711 | 0.4861 | 0.4575 | 0.4714 | 0.4567 | 153 | 0.4500 |
208
+ | curiosity | 0.9368 | 0.4442 | 0.8275 | 0.5781 | 0.5783 | 284 | 0.4000 |
209
+ | desire | 0.9865 | 0.5714 | 0.4819 | 0.5229 | 0.5180 | 83 | 0.4000 |
210
+ | disappointment| 0.9565 | 0.2906 | 0.3907 | 0.3333 | 0.3150 | 151 | 0.3500 |
211
+ | disapproval | 0.9235 | 0.3405 | 0.5918 | 0.4323 | 0.4118 | 267 | 0.3500 |
212
+ | disgust | 0.9810 | 0.6250 | 0.4065 | 0.4926 | 0.4950 | 123 | 0.5500 |
213
+ | embarrassment | 0.9947 | 0.7000 | 0.3784 | 0.4912 | 0.5123 | 37 | 0.5000 |
214
+ | excitement | 0.9790 | 0.4486 | 0.4660 | 0.4571 | 0.4465 | 103 | 0.4000 |
215
+ | fear | 0.9836 | 0.4599 | 0.8077 | 0.5860 | 0.6023 | 78 | 0.3000 |
216
+ | gratitude | 0.9888 | 0.9450 | 0.8778 | 0.9102 | 0.9049 | 352 | 0.5500 |
217
+ | grief | 0.9985 | 0.3333 | 0.3333 | 0.3333 | 0.3326 | 6 | 0.3000 |
218
+ | joy | 0.9768 | 0.6061 | 0.6211 | 0.6135 | 0.6016 | 161 | 0.4500 |
219
+ | love | 0.9825 | 0.7826 | 0.8319 | 0.8065 | 0.7978 | 238 | 0.5000 |
220
+ | nervousness | 0.9952 | 0.4348 | 0.4348 | 0.4348 | 0.4324 | 23 | 0.4000 |
221
+ | optimism | 0.9689 | 0.5436 | 0.5699 | 0.5564 | 0.5405 | 186 | 0.4000 |
222
+ | pride | 0.9980 | 0.8571 | 0.3750 | 0.5217 | 0.5662 | 16 | 0.4000 |
223
+ | realization | 0.9737 | 0.5217 | 0.1655 | 0.2513 | 0.2838 | 145 | 0.4500 |
224
+ | relief | 0.9982 | 0.5385 | 0.6364 | 0.5833 | 0.5845 | 11 | 0.3000 |
225
+ | remorse | 0.9912 | 0.5426 | 0.9107 | 0.6800 | 0.6992 | 56 | 0.3500 |
226
+ | sadness | 0.9757 | 0.5845 | 0.5321 | 0.5570 | 0.5452 | 156 | 0.4500 |
227
+ | surprise | 0.9724 | 0.4772 | 0.6667 | 0.5562 | 0.5504 | 141 | 0.3500 |
228
+ | neutral | 0.7485 | 0.5821 | 0.8372 | 0.6867 | 0.5102 | 1787 | 0.4000 |
229
+
230
+ ### Visualizations
231
+
232
+ #### Class-Wise F1 Scores
233
+ ![Class-Wise F1 Scores](class_wise_f1_plot.png)
234
+
235
+ #### Confusion Matrix Heatmap
236
+ ![Multi-Label Confusion Matrix Heatmap](confusion_matrix_heatmap.png)
237
+
238
+ #### Training Curves
239
+ ![Training and Validation Loss and Micro F1](training_curves_plot.png)
240
+
241
+ ## Training Insights
242
+
243
+ The model was trained for 5 epochs with Focal Loss to handle class imbalance. Training and validation curves show consistent improvement:
244
+ - Training Loss decreased from 0.0429 to 0.0134.
245
+ - Validation Micro F1 peaked at 0.5874 (epoch 5).
246
+ - See the training curves plot above for details.
247
+
248
+ ## Usage
249
+
250
+ ### Quick Inference with inference.py (Recommended for PyTorch)
251
+
252
+ The easiest way to use the model with PyTorch is to programmatically fetch and use `inference.py` from the repository. The script handles all preprocessing, model loading, and inference for you.
253
+
254
+ #### Programmatic Download and Inference
255
+ Run the following Python script to download `inference.py` and make predictions:
256
+
257
+ ```python
258
+ # Install required dependencies
259
+ !pip install transformers torch huggingface_hub emoji -q
260
+
261
+ import shutil
262
+ import os
263
+ from huggingface_hub import hf_hub_download
264
+ from importlib import import_module
265
+
266
+ # Download inference.py
267
+ repo_id = "logasanjeev/goemotions-bert"
268
+ local_file = hf_hub_download(repo_id=repo_id, filename="inference.py")
269
+
270
+ # Copy the file to the current working directory
271
+ current_dir = os.getcwd()
272
+ destination = os.path.join(current_dir, "inference.py")
273
+ shutil.copy(local_file, destination)
274
+
275
+ # Import and use the predict_emotions function
276
+ inference_module = import_module("inference")
277
+ predict_emotions = inference_module.predict_emotions
278
+
279
+ # Make predictions
280
+ text = "I’m thrilled to win this award! 😄"
281
+ result, processed = predict_emotions(text)
282
+ print(f"Input: {text}")
283
+ print(f"Processed: {processed}")
284
+ print("Predicted Emotions:")
285
+ print(result)
286
+ ```
287
+
288
+ #### Expected Output:
289
+ ```
290
+ Input: I’m thrilled to win this award! 😄
291
+ Processed: i’m thrilled to win this award ! grinning_face_with_smiling_eyes
292
+ Predicted Emotions:
293
+ excitement: 0.5836
294
+ joy: 0.5290
295
+ ```
296
+
297
+ #### Alternative: Manual Download
298
+ If you prefer to download `inference.py` manually:
299
+ 1. Install the required dependencies:
300
+ ```bash
301
+ pip install transformers torch huggingface_hub emoji
302
+ ```
303
+ 2. Download `inference.py` from the repository.
304
+ 3. Use it in Python or via the command line.
305
+
306
+ **Python Example:**
307
+ ```python
308
+ from inference import predict_emotions
309
+
310
+ result, processed = predict_emotions("I’m thrilled to win this award! 😄")
311
+ print(f"Input: I’m thrilled to win this award! 😄")
312
+ print(f"Processed: {processed}")
313
+ print("Predicted Emotions:")
314
+ print(result)
315
+ ```
316
+
317
+ **Command-Line Example:**
318
+ ```bash
319
+ python inference.py "I’m thrilled to win this award! 😄"
320
+ ```
321
+
322
+ ### Quick Inference with onnx_inference.py (Recommended for ONNX)
323
+
324
+ For faster and more efficient inference using ONNX, you can use `onnx_inference.py`. This script leverages ONNX Runtime for inference, which is typically more lightweight than PyTorch.
325
+
326
+ #### Programmatic Download and Inference
327
+ Run the following Python script to download `onnx_inference.py` and make predictions:
328
+
329
+ ```python
330
+ # Install required dependencies
331
+ !pip install transformers onnxruntime huggingface_hub emoji numpy -q
332
+
333
+ import shutil
334
+ import os
335
+ from huggingface_hub import hf_hub_download
336
+ from importlib import import_module
337
+
338
+ # Download onnx_inference.py
339
+ repo_id = "logasanjeev/goemotions-bert"
340
+ local_file = hf_hub_download(repo_id=repo_id, filename="onnx_inference.py")
341
+
342
+ # Copy the file to the current working directory
343
+ current_dir = os.getcwd()
344
+ destination = os.path.join(current_dir, "onnx_inference.py")
345
+ shutil.copy(local_file, destination)
346
+
347
+ # Import and use the predict_emotions function
348
+ onnx_inference_module = import_module("onnx_inference")
349
+ predict_emotions = onnx_inference_module.predict_emotions
350
+
351
+ # Make predictions
352
+ text = "I’m thrilled to win this award! 😄"
353
+ result, processed = predict_emotions(text)
354
+ print(f"Input: {text}")
355
+ print(f"Processed: {processed}")
356
+ print("Predicted Emotions:")
357
+ print(result)
358
+ ```
359
+
360
+ #### Expected Output:
361
+ ```
362
+ Input: I’m thrilled to win this award! 😄
363
+ Processed: i’m thrilled to win this award ! grinning_face_with_smiling_eyes
364
+ Predicted Emotions:
365
+ excitement: 0.5836
366
+ joy: 0.5290
367
+ ```
368
+
369
+ #### Alternative: Manual Download
370
+ If you prefer to download `onnx_inference.py` manually:
371
+ 1. Install the required dependencies:
372
+ ```bash
373
+ pip install transformers onnxruntime huggingface_hub emoji numpy
374
+ ```
375
+ 2. Download `onnx_inference.py` from the repository.
376
+ 3. Use it in Python or via the command line.
377
+
378
+ **Python Example:**
379
+ ```python
380
+ from onnx_inference import predict_emotions
381
+
382
+ result, processed = predict_emotions("I’m thrilled to win this award! 😄")
383
+ print(f"Input: I’m thrilled to win this award! 😄")
384
+ print(f"Processed: {processed}")
385
+ print("Predicted Emotions:")
386
+ print(result)
387
+ ```
388
+
389
+ **Command-Line Example:**
390
+ ```bash
391
+ python onnx_inference.py "I’m thrilled to win this award! 😄"
392
+ ```
393
+
394
+ ### Preprocessing
395
+ Before inference, preprocess text to match training conditions:
396
+ - Replace user mentions (`u/username`) with `[USER]`.
397
+ - Replace subreddits (`r/subreddit`) with `[SUBREDDIT]`.
398
+ - Replace URLs with `[URL]`.
399
+ - Convert emojis to text using `emoji.demojize` (e.g., 😊 → `smiling_face_with_smiling_eyes`).
400
+ - Lowercase the text.
401
+
402
+ ### PyTorch Inference
403
+ ```python
404
+ from transformers import BertForSequenceClassification, BertTokenizer
405
+ import torch
406
+ import json
407
+ import requests
408
+ import re
409
+ import emoji
410
+
411
+ # Preprocessing function
412
+ def preprocess_text(text):
413
+ text = re.sub(r'u/\w+', '[USER]', text)
414
+ text = re.sub(r'r/\w+', '[SUBREDDIT]', text)
415
+ text = re.sub(r'http[s]?://\S+', '[URL]', text)
416
+ text = emoji.demojize(text, delimiters=(" ", " "))
417
+ text = text.lower()
418
+ return text
419
+
420
+ # Load model and tokenizer
421
+ repo_id = "logasanjeev/goemotions-bert"
422
+ model = BertForSequenceClassification.from_pretrained(repo_id)
423
+ tokenizer = BertTokenizer.from_pretrained(repo_id)
424
+
425
+ # Load thresholds and labels
426
+ thresholds_url = f"https://huggingface.co/{repo_id}/raw/main/optimized_thresholds.json"
427
+ thresholds_data = json.loads(requests.get(thresholds_url).text)
428
+ emotion_labels = thresholds_data["emotion_labels"]
429
+ thresholds = thresholds_data["thresholds"]
430
+
431
+ # Predict
432
+ text = "I’m just chilling today."
433
+ processed_text = preprocess_text(text)
434
+ encodings = tokenizer(processed_text, padding='max_length', truncation=True, max_length=128, return_tensors='pt')
435
+ with torch.no_grad():
436
+ logits = torch.sigmoid(model(**encodings).logits).numpy()[0]
437
+ predictions = [(emotion_labels[i], round(logit, 4)) for i, (logit, thresh) in enumerate(zip(logits, thresholds)) if logit >= thresh]
438
+ predictions = sorted(predictions, key=lambda x: x[1], reverse=True)
439
+ print(predictions)
440
+ # Output: [('neutral', 0.8147)]
441
+ ```
442
+
443
+ ### ONNX Inference
444
+ For a simplified ONNX inference experience, use `onnx_inference.py` as shown above. Alternatively, you can use the manual approach below:
445
+
446
+ ```python
447
+ import onnxruntime as ort
448
+ import numpy as np
449
+
450
+ # Download ONNX model
451
+ onnx_url = f"https://huggingface.co/{repo_id}/raw/main/model.onnx"
452
+ with open("model.onnx", "wb") as f:
453
+ f.write(requests.get(onnx_url).content)
454
+
455
+ # Preprocess and predict
456
+ text = "I’m thrilled to win this award! 😄"
457
+ processed_text = preprocess_text(text)
458
+ encodings = tokenizer(processed_text, padding='max_length', truncation=True, max_length=128, return_tensors='np')
459
+ session = ort.InferenceSession("model.onnx")
460
+ inputs = {
461
+ 'input_ids': encodings['input_ids'].astype(np.int64),
462
+ 'attention_mask': encodings['attention_mask'].astype(np.int64)
463
+ }
464
+ logits = session.run(None, inputs)[0][0]
465
+ logits = 1 / (1 + np.exp(-logits)) # Sigmoid
466
+ predictions = [(emotion_labels[i], round(logit, 4)) for i, (logit, thresh) in enumerate(zip(logits, thresholds)) if logit >= thresh]
467
+ predictions = sorted(predictions, key=lambda x: x[1], reverse=True)
468
+ print(predictions)
469
+ # Output: [('excitement', 0.5836), ('joy', 0.5290)]
470
+ ```
471
+
472
+ ## License
473
+
474
+ This model is licensed under the MIT License. See [LICENSE](LICENSE) for details.
475
+
476
+ ## Usage Notes
477
+
478
+ - The model performs best on Reddit-style comments with similar preprocessing.
479
+ - Rare emotions (e.g., `grief`, support=6) have lower F1 scores due to limited data.
480
+ - ONNX inference requires `onnxruntime` and compatible hardware (opset 14).
481
+
482
+ ## Inference Providers
483
+
484
+ This model isn't deployed by any Inference Provider. 🙋 Ask for provider support