--- license: mit language: en library_name: transformers pipeline_tag: text-classification base_model: distilbert/distilbert-base-uncased tags: - emotion-classification - text-classification - distilbert - pytorch --- # Inside Out Emotion Classifier A DistilBERT model fine-tuned to classify a short personal story into five emotions: **anger, disgust, fear, joy and sadness**. It powers a web app that shows the five *Inside Out* characters sized by the predicted probabilities. - **Live demo:** https://inside-out-emotion-classifier.vercel.app - **Code:** https://github.com/tishasetia13/inside-out-emotion-classifier - **API:** https://huggingface.co/spaces/tishasetia13/inside-out-api ## Intended use This model is a portfolio and educational project. It is not a clinical tool and must not be used to assess anyone's mental health. ## Training - **Base model:** `distilbert-base-uncased`, fully fine-tuned (all weights updated) for 3 epochs with PyTorch. - **Data:** the ISEAR dataset of short personal descriptions of emotional events. I kept five of its labels (anger, disgust, fear, joy, sadness), which left 5,395 examples. After cleaning, they were split into stratified train, validation and test sets. - **Input length:** the demo feeds the model chunks of up to 64 tokens. ## Results Evaluated on a held-out test set. The baseline uses the same data and split. | Model | Test accuracy | |---|---| | TF-IDF + logistic regression (baseline) | 66.8% | | This model | **76.4%** | ## How to use ```python import torch from transformers import AutoTokenizer, AutoModelForSequenceClassification repo_id = "tishasetia13/inside-out-emotion-classifier" tokenizer = AutoTokenizer.from_pretrained(repo_id) model = AutoModelForSequenceClassification.from_pretrained(repo_id) model.eval() text = "I opened my results and saw I had topped my class." # Tokenize, keeping the input within the 64-token window used in the demo inputs = tokenizer(text, return_tensors="pt", truncation=True, max_length=64) # Run the model and turn the raw scores into probabilities that sum to 1 with torch.no_grad(): logits = model(**inputs).logits probs = torch.softmax(logits, dim=-1)[0] # Print each emotion with its probability for i, p in enumerate(probs): print(model.config.id2label[i], f"{p.item() * 100:.1f}%") ``` For stories longer than 64 tokens, the live demo splits the text into chunks at sentence boundaries, classifies each chunk, and averages the probabilities. The implementation is in `predict.py` in the GitHub repository. ## Limitations - **No neutral class.** Calm or factual text is forced into one of the five emotions, often joy. - **Five emotions only.** ISEAR also contains shame and guilt, which were left out. - **Mixed feelings are flattened.** The model tends to return one dominant emotion with very high confidence, even when a story contains two. - **High confidence is not correctness.** The scores are model probabilities, not a measure of accuracy. - **Narrow training data.** The model was trained on short ISEAR stories, so informal text, slang and other languages are outside what it learned.