--- license: apache-2.0 base_model: FacebookAI/roberta-large datasets: - google-research-datasets/go_emotions language: - en tags: - goemotions - emotion-classification - multi-label-classification - roberta - focal-loss - threshold-optimization metrics: - f1 pipeline_tag: text-classification library_name: transformers --- # GoEmotions RoBERTa Large Focal SOTA RoBERTa-large multi-label classifier fine-tuned on the public GoEmotions `simplified` split. The model predicts 28 labels: 27 fine-grained emotions plus `neutral`. ## Results The selected policy is coordinate threshold search optimized on validation macro-F1. | Split | Macro F1 | Micro F1 | Samples F1 | Hamming Loss | | --- | ---: | ---: | ---: | ---: | | Validation | 0.565864 | 0.596637 | 0.605125 | 0.034424 | | Test | 0.533020 | 0.576651 | 0.585942 | 0.035820 | The per-label threshold candidate reached test macro-F1 `0.534994`, but the validation-selected policy is the coordinate threshold policy above. ## Training - Base model: `FacebookAI/roberta-large` - Dataset: `google-research-datasets/go_emotions`, `simplified` - Loss: focal loss, alpha `0.38`, gamma `2.8` - Epochs: `4` - Learning rate: `1e-5` - Batch: `2`, gradient accumulation `16` - Mixed precision: disabled for stability on Kaggle T4 - Seed: `42` Training provenance: Kaggle kernel `kevin250304/goemotions-roberta-large-focal-sweep`. ## Usage ```python import json import numpy as np import torch from transformers import AutoModelForSequenceClassification, AutoTokenizer repo_id = "AliceYin/goemotions-roberta-large-focal-sota" tokenizer = AutoTokenizer.from_pretrained(repo_id) model = AutoModelForSequenceClassification.from_pretrained(repo_id) labels = json.load(open("labels.json"))["label_names"] thresholds = json.load(open("thresholds.json"))["coordinate"] threshold_array = np.array([thresholds[label] for label in labels]) text = "I can't believe this worked so well." inputs = tokenizer(text, return_tensors="pt", truncation=True, max_length=128) with torch.no_grad(): probs = torch.sigmoid(model(**inputs).logits).cpu().numpy()[0] predicted = [ label for label, prob, threshold in zip(labels, probs, threshold_array) if prob >= threshold ] print(predicted) ``` For remote loading of thresholds and labels, download `labels.json` and `thresholds.json` from this repository alongside the model files. ## Files - `model.safetensors`: fine-tuned RoBERTa-large weights - `config.json`, `tokenizer.json`, `tokenizer_config.json`: Transformers files - `thresholds.json`: fixed, global, per-label, and coordinate thresholds - `labels.json`: label names and neutral index - `metrics.json`: full validation/test metrics - `kaggle-run.log`: training log ## Limitations This model is trained on Reddit comments and inherits the dataset's domain, annotation, and class imbalance limitations. Validate before using in high-stakes settings.