/ Модель

Характеристики

Контекст
514 токенов
Параметры
454 млн
Лицензия
MIT
Архитектура
roberta · dense
Базовая модель
roberta-large
Библиотека
transformers
Опубликована
4 ноя 2025

roberta-large-goemotions

Классификация текстаТекст → label3 профессии

Дообученная RoBERTa-Large определяет несколько эмоций и нейтральное состояние в англоязычном тексте.

23скачиваний за 30 дней7лайковвеса обновлены4 ноя 2025

Бенчмарки

Как модель справилась с задачами пользователей ailist и что о ней публикуют открытые лидерборды

Публичные оценки

Из открытых лидербордов. Сравнивайте результаты одного теста при одинаковых условиях — отсутствие оценки не значит, что модель хуже.

В подключённых источниках результатов для этой модели пока нет.

Что умеет модель

Описание составлено по карточке модели и метаданным Hugging Face

Модель разработал Lakshya Kumar: это дообученная RoBERTa-Large для многометочной классификации эмоций в тексте. Она определяет 28 эмоций и нейтральное состояние по датасету GoEmotions, поэтому одному сообщению может соответствовать несколько меток. Модель содержит 454,1 млн параметров, принимает текст и выдаёт оценки и метки эмоций; заявленная длина контекста — 514 токенов.

Для обучения применялись focal loss, отдельная настройка порога для каждой метки и целевая аугментация, чтобы улучшить работу с несбалансированными классами. Модель ориентирована на англоязычный текст, в частности комментарии и короткие сообщения. Она распространяется по лицензии MIT.

Сценарии применения

  • определение эмоций в комментариях и сообщениях
  • выявление нескольких эмоций в одном тексте
  • анализ эмоциональной реакции пользователей
  • оценка тональности с различением конкретных эмоций

Ограничения

Модель обучена на англоязычных комментариях Reddit из GoEmotions, поэтому её точность на других языках и типах текста не подтверждена. Предсказания зависят от порогов меток и могут не отражать эмоциональный контекст или неоднозначность высказывания.

Для каких профессий подходит3

Разделы каталога профессий, в задачах которых используется эта модель

Все профессии

Карточка модели

README от автора на Hugging Face, как он его опубликовал

Открыть на Hugging Face

🧠 RoBERTa-Large GoEmotions (Optimized)

Multi-label Emotion Classification with Focal Loss + Per-label Threshold Optimization

🏷️ Overview

This model fine-tunes RoBERTa-Large on the GoEmotions dataset for multi-label emotion classification, detecting 28 distinct emotions (plus neutral) in text.
Unlike standard models that use fixed thresholds or BCE loss, this version applies focal loss, per-label optimization, and targeted augmentation, leading to a balanced and generalizable model across all emotions.

Each input sentence can evoke multiple emotions simultaneously — for example:

"I can't believe this happened!" → surprise, disappointment


📚 Dataset

GoEmotions (Google Research, 2021)
• ~58k Reddit comments
• 28 emotion labels + neutral
• Multi-label: each text can have multiple active emotions
• Highly imbalanced: e.g., gratitude has >1,000 examples, while grief or relief have <20

This model addresses imbalance through loss design, augmentation, and threshold tuning.


🚀 Quick Start

Installation

pip install torch transformers huggingface_hub numpy

Basic Usage (3 lines!)

import torch
import torch.nn as nn
from transformers import RobertaTokenizer, RobertaModel
from huggingface_hub import hf_hub_download
import json
import numpy as np
# Step 1: Define the model architecture
class RobertaForMultiLabelClassification(nn.Module):
    def __init__(self, model_name, num_labels, dropout_rate=0.3, use_mean_pooling=True):
        super().__init__()
        self.roberta = RobertaModel.from_pretrained(model_name)
        self.use_mean_pooling = use_mean_pooling
        hidden_size = self.roberta.config.hidden_size
        self.dropout1 = nn.Dropout(dropout_rate)
        self.fc1 = nn.Linear(hidden_size, hidden_size // 2)
        self.relu = nn.ReLU()
        self.dropout2 = nn.Dropout(dropout_rate)
        self.fc2 = nn.Linear(hidden_size // 2, num_labels)
    def mean_pooling(self, token_embeddings, attention_mask):
        input_mask_expanded = attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float()
        sum_embeddings = torch.sum(token_embeddings * input_mask_expanded, 1)
        sum_mask = torch.clamp(input_mask_expanded.sum(1), min=1e-9)
        return sum_embeddings / sum_mask
    def forward(self, input_ids, attention_mask):
        outputs = self.roberta(input_ids, attention_mask=attention_mask)
        if self.use_mean_pooling:
            pooled_output = self.mean_pooling(outputs.last_hidden_state, attention_mask)
        else:
            pooled_output = outputs.pooler_output
        x = self.dropout1(pooled_output)
        x = self.fc1(x)
        x = self.relu(x)
        x = self.dropout2(x)
        logits = self.fc2(x)
        return logits
# Step 2: Load model
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model_name = "Lakssssshya/roberta-large-goemotions"
tokenizer = RobertaTokenizer.from_pretrained(model_name)
# Load config
config_path = hf_hub_download(repo_id=model_name, filename="config.json")
with open(config_path, 'r') as f:
    config = json.load(f)
model = RobertaForMultiLabelClassification(
    model_name='roberta-large',
    num_labels=config['num_labels'],
    dropout_rate=config.get('dropout_rate', 0.3),
    use_mean_pooling=config.get('use_mean_pooling', True)
)
# Load weights
weights_path = hf_hub_download(repo_id=model_name, filename="pytorch_model.bin")
state_dict = torch.load(weights_path, map_location=device)
model.load_state_dict(state_dict)
model.to(device)
model.eval()
# Load thresholds
thresholds_path = hf_hub_download(repo_id=model_name, filename="optimal_thresholds.json")
with open(thresholds_path, 'r') as f:
    thresholds = np.array(json.load(f))
# Emotion labels
emotion_labels = [
    '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'
]
# Step 3: Predict
def predict_emotions(text):
    inputs = tokenizer(text, return_tensors='pt', truncation=True, max_length=128, padding=True)
    inputs = {k: v.to(device) for k, v in inputs.items()}
    
    with torch.no_grad():
        logits = model(input_ids=inputs['input_ids'], attention_mask=inputs['attention_mask'])
        probs = torch.sigmoid(logits).cpu().numpy()[0]
    
    # Apply optimized thresholds
    predictions = (probs > thresholds).astype(int)
    
    # Get predicted emotions
    predicted_emotions = [emotion_labels[i] for i in range(len(predictions)) if predictions[i] == 1]
    
    # Get top emotions with scores
    top_indices = np.argsort(probs)[::-1][:5]
    top_emotions = [(emotion_labels[idx], float(probs[idx])) for idx in top_indices]
    
    return {
        'predicted_emotions': predicted_emotions,
        'top_emotions': top_emotions
    }
# Example usage
text = "I'm so proud and excited about this achievement!"
result = predict_emotions(text)
print(f"Text: {text}")
print(f"Predicted emotions: {result['predicted_emotions']}")
print(f"Top 5 emotions: {result['top_emotions']}")

Easy-to-Use Wrapper Class

For convenience, use this wrapper class:

class EmotionPredictor:
    def __init__(self, model_name="Lakssssshya/roberta-large-goemotions"):
        self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
        self.tokenizer = RobertaTokenizer.from_pretrained(model_name)
        
        # Load config and model
        config_path = hf_hub_download(repo_id=model_name, filename="config.json")
        with open(config_path, 'r') as f:
            config = json.load(f)
        
        self.model = RobertaForMultiLabelClassification(
            model_name='roberta-large',
            num_labels=config['num_labels'],
            dropout_rate=config.get('dropout_rate', 0.3),
            use_mean_pooling=config.get('use_mean_pooling', True)
        )
        
        weights_path = hf_hub_download(repo_id=model_name, filename="pytorch_model.bin")
        state_dict = torch.load(weights_path, map_location=self.device)
        self.model.load_state_dict(state_dict)
        self.model.to(self.device)
        self.model.eval()
        
        # Load thresholds
        thresholds_path = hf_hub_download(repo_id=model_name, filename="optimal_thresholds.json")
        with open(thresholds_path, 'r') as f:
            self.thresholds = np.array(json.load(f))
        
        self.emotion_labels = [
            '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'
        ]
    
    def predict(self, text, top_k=5):
        inputs = self.tokenizer(text, return_tensors='pt', truncation=True, max_length=128, padding=True)
        inputs = {k: v.to(self.device) for k, v in inputs.items()}
        
        with torch.no_grad():
            logits = self.model(input_ids=inputs['input_ids'], attention_mask=inputs['attention_mask'])
            probs = torch.sigmoid(logits).cpu().numpy()[0]
        
        predictions = (probs > self.thresholds).astype(int)
        predicted_emotions = [self.emotion_labels[i] for i in range(len(predictions)) if predictions[i] == 1]
        
        top_indices = np.argsort(probs)[::-1][:top_k]
        top_emotions = [
            {'emotion': self.emotion_labels[idx], 'score': float(probs[idx])}
            for idx in top_indices
        ]
        
        return {'text': text, 'emotions': predicted_emotions, 'top_emotions': top_emotions}
# Simple usage
predictor = EmotionPredictor()
result = predictor.predict("I'm so happy and excited!")
print(result)

📝 Example Predictions

Example 1: Pride and Achievement

text = "I'm so proud and excited about this achievement!"
result = predictor.predict(text)
# Output: {'emotions': ['pride', 'excitement', 'joy'], 'top_emotions': [{'emotion': 'pride', 'score': 0.867}, {'emotion': 'excitement', 'score': 0.712}, ...]}

Example 2: Regret

text = "I really regret saying that earlier."
result = predictor.predict(text)
# Output: {'emotions': ['remorse', 'sadness'], 'top_emotions': [{'emotion': 'remorse', 'score': 0.758}, ...]}

Example 3: Mixed Emotions

text = "I feel anxious but hopeful about the future."
result = predictor.predict(text)
# Output: {'emotions': ['nervousness', 'optimism'], 'top_emotions': [{'emotion': 'nervousness', 'score': 0.710}, {'emotion': 'optimism', 'score': 0.645}, ...]}

Example 4: Surprise

text = "I can't believe this happened!"
result = predictor.predict(text)
# Output: {'emotions': ['surprise', 'realization'], 'top_emotions': [{'emotion': 'surprise', 'score': 0.747}, ...]}

Example 5: Gratitude

text = "Thank you so much for all your help and support!"
result = predictor.predict(text)
# Output: {'emotions': ['gratitude', 'admiration'], 'top_emotions': [{'emotion': 'gratitude', 'score': 0.923}, ...]}

Example 6: Multiple Strong Emotions

text = "This is absolutely disgusting and infuriating!"
result = predictor.predict(text)
# Output: {'emotions': ['disgust', 'anger', 'annoyance'], 'top_emotions': [{'emotion': 'disgust', 'score': 0.834}, {'emotion': 'anger', 'score': 0.789}, ...]}

⚙️ Training Details

ParameterValue
Base modelroberta-large
TaskMulti-label classification
Epochs5 (first 2 frozen encoder)
Learning rate2.6e-5 (Optuna-tuned)
OptimizerAdamW
Weight decay0.01
Warmup ratio0.1
LossFocal Loss (α=0.38, γ=2.8)
Gradient accumulation16
SchedulerLinear decay
Mixed precision✅ FP16
PoolingMean pooling
Dropout0.41
Batch size2 × 16 (accumulated)
Early stoppingPatience = 3
Threshold range[0.05, 0.95] optimized per label

Thresholds are optimized individually to maximize per-label F1 and saved in optimal_thresholds.json.


📊 Evaluation Metrics (Test Split)

Metric TypePrecisionRecallF1
Macro (unweighted)0.4970.5760.519
Weighted by label frequency0.5050.5850.528

This model achieves a balanced macro-F1 above 0.52, maintaining strong recall even for underrepresented emotions.


🔍 Per-Label Performance (Best performance on Val Split)

labelaccuracyprecisionrecallf1mccsupportthreshold
AVG0.9620.5410.5920.5510.53863800.645
admiration0.950.7180.7320.7250.6974880.616
amusement0.9750.7270.8880.7990.7913030.652
anger0.960.4530.5440.4940.4761950.648
annoyance0.9110.3260.5580.4120.3833030.568
approval0.8850.3070.4560.3670.3143970.543
caring0.9710.4810.5820.5270.5141530.618
confusion0.9730.5210.4010.4540.4441520.653
curiosity0.9470.4520.710.5530.5412480.601
desire0.9890.6420.5580.5970.593770.729
disappointment0.960.3370.3440.340.321630.605
disapproval0.9080.3290.6780.4430.4312920.545
disgust0.9840.5490.4640.5030.496970.697
embarrassment0.9920.4170.7140.5260.542350.674
excitement0.9770.3570.3650.3610.349960.676
fear0.9910.7240.70.7120.707900.681
gratitude0.9890.960.8770.9170.9123580.685
grief0.9980.5450.4620.50.501130.774
joy0.9740.5940.5870.5910.5771720.642
love0.9790.7180.8890.7940.7882520.648
nervousness0.9950.3910.4290.4090.407210.7
optimism0.9730.690.5550.6150.6062090.669
pride0.9990.8890.5330.6670.688150.694
realization0.9760.4750.2280.3090.3191270.658
relief0.9920.2170.5560.3120.344180.594
remorse0.9920.6480.8380.7310.733680.728
sadness0.9760.5430.5730.5580.5461430.65
surprise0.9780.5280.5890.5570.5461290.664
neutral0.7530.5930.7670.6690.48717660.446

🔍 Per-Label Performance (Test Split)

LabelAccuracyPrecisionRecallF1MCCSupportThreshold
AVG0.9610.4970.5760.5190.50663290.645
admiration0.9400.6760.6900.6830.6505040.616
amusement0.9800.7400.9050.8140.8082640.652
anger0.9590.4550.5560.5000.4821980.648
annoyance0.9050.3150.5190.3920.3563200.568
approval0.9000.3310.5380.4100.3713510.543
caring0.9670.3740.4960.4270.4141350.618
confusion0.9710.4870.4770.4820.4671530.653
curiosity0.9450.4830.7150.5770.5612840.601
desire0.9870.6470.3980.4930.501830.729
disappointment0.9620.3130.3110.3120.2931510.605
disapproval0.8990.2840.6970.4030.4022670.545
disgust0.9780.5310.4230.4710.4631230.697
embarrassment0.9890.2880.4590.3540.358370.674
excitement0.9770.4000.4470.4220.4111030.676
fear0.9880.5640.7950.6600.664780.681
gratitude0.9890.9390.8810.9090.9043520.685
grief0.9990.4290.5000.4620.46260.774
joy0.9740.5570.6400.5950.5841610.642
love0.9790.7310.8320.7780.7692380.648
nervousness0.9940.3330.3480.3400.338230.700
optimism0.9750.6860.5160.5890.5831860.669
pride0.9970.5380.4380.4830.484160.694
realization0.9700.3800.2070.2680.2661450.658
relief0.9930.1710.6360.2690.327110.594
remorse0.9910.5400.8390.6570.669560.728
sadness0.9750.5800.5320.5550.5431560.650
surprise0.9770.5530.5530.5530.5411410.664
neutral0.7530.5950.7760.6740.49117870.446

🥇 Why This Model Outperforms Other GoEmotions Models

Most GoEmotions models on Hugging Face use BCE loss and a fixed 0.5 threshold.
While effective for frequent emotions, they perform poorly on rare ones.

This model overcomes those limits via:

1️⃣ Adaptive per-label thresholds — Each label has a unique optimized decision boundary, maximizing per-label F1 and balancing recall/precision.
2️⃣ Focal Loss — Down-weights easy examples and boosts hard ones, enhancing minority class generalization.
3️⃣ Mean Pooling — Captures richer emotional nuance than CLS-based pooling.
4️⃣ Targeted Augmentation — Paraphrasing and synonym replacement to strengthen rare emotion classes.
5️⃣ Gradual Unfreezing — Stabilizes fine-tuning by freezing encoder early epochs.
6️⃣ Balanced Macro Metrics — Consistent fairness across all emotion classes.


🧾 Model Details

DetailDescription
ArchitectureRoBERTa-Large + Mean Pooling + 2-layer MLP
Task TypeMulti-label emotion classification
Input LengthUp to 128 tokens
Output28 sigmoid probabilities
FrameworkPyTorch / Hugging Face Transformers
Mixed PrecisionSupported (FP16)
LicenseMIT
DeveloperLakshya Kumar

🎯 Intended Use

  • Emotion detection in conversational AI systems
  • Social media sentiment analysis
  • Affective computing research
  • Psychological and HCI studies

⚠️ Limitations

  • Trained on Reddit; may not generalize to formal or non-English domains.
  • Rare emotions (e.g. grief, relief) have low support.
  • Detects linguistic cues, not true emotional state.

📎 Citation

@misc{lakshya2025robertalargegoemotions,
  title={RoBERTa-Large GoEmotions (Optimized Thresholds and Focal Loss)},
  author={Lakshya Kumar},
  year={2025},
  publisher={Hugging Face},
  howpublished={\url{https://huggingface.co/Lakssssshya/roberta-large-goemotions}}
}

🙏 Acknowledgments

  • Google Research for the GoEmotions dataset
  • Hugging Face for the transformers library
  • Meta AI for RoBERTa architecture

📧 Contact

For questions or collaborations:


⭐ If you find this model useful, please give it a star and share it with others!

Как запустить

На своей GPU в ailist. Цена — по текущим предложениям провайдеров

GPU в ailist

Универсальный рантайм · transformers · text-classification

Можно запустить

Подбираем GPU…

Класс архитектуры
RobertaForMultiLabelClassification
Ревизия весов
e83088c

0 моделей