Ismail Ben Alla

Text Classification

Détection d’émotions avec des RNN, LSTM et GRU

TAL · nov. 2024 · En cours

Douze modèles récurrents qui lisent une phrase et nomment son émotion, reconstruits à partir de deux notebooks cassés en un seul package testé.

Construit avecPyTorchGloVeNLTKPandasMatplotlibpytest

Text Classification — vue d’ensemble

Présentation

Ce projet a commencé comme deux notebooks Colab qui classaient des phrases anglaises en six émotions avec des modèles RNN, LSTM et GRU. Les notebooks atteignaient 50 à 81,5 % de précision en test et je ne faisais pas confiance à ces chiffres. Je les ai reconstruits sous forme de package Python avec une seule recette d’entraînement partagée et j’ai compris pourquoi : les cellules from scratch n’étaient pas récurrentes, le padding fuyait dans la prédiction, l’équation du GRU était fausse et l’évaluation était optimiste.

Le package conserve les idées des notebooks : trois types de cellules, chacune construite deux fois (avec nn.RNN / nn.LSTM / nn.GRU et from scratch), alimentées soit par une table d’embedding apprise sur du texte lemmatisé, soit par des vecteurs GloVe 100-d gelés sur du texte brut. Cela fait 12 modèles, tous à deux couches et bidirectionnels avec la même tête MLP, entraînés jusqu’à 8 époques sur CPU avec arrêt précoce sur la précision de validation, sur le jeu de données dair-ai/emotion (16 000 entraînement / 2 000 validation / 2 000 test).

Chaque modèle atteint désormais 91 à 92 % de précision en test avec un F1 macro de 0,87 à 0,88 ; le meilleur est glove-lstm-scratch à 92,3 %. Les cellules from scratch coïncident numériquement avec celles de PyTorch, ce que les tests prouvent en y copiant les poids de PyTorch. Les erreurs restantes concernent les classes proches : love pris pour joy, surprise pris pour fear.

La question

Pourquoi mes notebooks d’origine allaient-ils de 50 % à 81,5 % de précision sur la même tâche, et le type de cellule et l’embedding comptent-ils encore une fois le pipeline corrigé ?

Fonctionnalités clés

Comment ça marche

  1. Nettoyer le texte

    Passage en minuscules et conservation des lettres, chiffres et ponctuation de base ; les runs one-hot retirent aussi les mots rares et les stop words (en gardant les négations) et lemmatisent avec NLTK, tandis que les runs GloVe utilisent les mots bruts.

  2. Plonger

    Les identifiants de tokens indexent une table apprise de 3 100 x 100, ou des vecteurs GloVe gelés avec une ligne nulle pour le padding et le vecteur moyen pour les mots inconnus.

  3. Lire la phrase

    Un RNN, LSTM ou GRU bidirectionnel à deux couches parcourt les tokens ; l’état au dernier token réel de chaque direction est le résumé de la phrase.

  4. Classer

    Dropout, une tête Linear-ReLU-Linear et un softmax à six sorties, entraînés avec une entropie croisée à label smoothing.

  5. Vérifier avant de croire

    Surapprendre un batch réel, comparer avec un modèle aveugle, vérifier que les gradients atteignent chaque tenseur, puis entraîner jusqu’à 8 époques et garder la meilleure époque de validation.

Exemples

Précision en test des 12 modèles dans les notebooks d’origine (gris) et dans le package corrigé (bleu) : de 50 à 81,5 % jusqu’à 91 à 92 %.
Précision en test des 12 modèles dans les notebooks d’origine (gris) et dans le package corrigé (bleu) : de 50 à 81,5 % jusqu’à 91 à 92 %.
Test de surapprentissage : chaque modèle mémorise un batch de 64 phrases réelles, faisant passer la perte de ln 6 à environ zéro. Le pic du RNN scratch one-hot autour du pas 65 est l’instabilité connue des RNN ReLU classiques ; il se résorbe de lui-même.
Test de surapprentissage : chaque modèle mémorise un batch de 64 phrases réelles, faisant passer la perte de ln 6 à environ zéro. Le pic du RNN scratch one-hot autour du pas 65 est l’instabilité connue des RNN ReLU classiques ; il se résorbe de lui-même.
Précision de validation par époque. Les lignes pleines sont les cellules nn.* et les lignes en pointillé les cellules from scratch ; GloVe démarre plus lentement que la table apprise et la rattrape à l’époque 5.
Précision de validation par époque. Les lignes pleines sont les cellules nn.* et les lignes en pointillé les cellules from scratch ; GloVe démarre plus lentement que la table apprise et la rattrape à l’époque 5.
Matrice de confusion en test de glove-lstm-scratch, le meilleur modèle (92,3 %) : les erreurs sont love prédit comme joy (32 sur 159) et surprise et fear confondus l’un avec l’autre.
Matrice de confusion en test de glove-lstm-scratch, le meilleur modèle (92,3 %) : les erreurs sont love prédit comme joy (32 sur 159) et surprise et fear confondus l’un avec l’autre.

Entrée

textcls-predict --checkpoint checkpoints/glove-lstm-scratch/best.pt "i didnt feel humiliated" "i feel amazing today, everything went right"

Sortie

sadness 0.98 (anger 0.01, fear 0.00) <- i didnt feel humiliated surprise 0.88 (joy 0.10, fear 0.01) <- i feel amazing today, everything went right

Sortie réelle du meilleur modèle. La deuxième ligne est une erreur (ce devrait être joy) : dans le jeu d’entraînement, « amazing » est étiqueté surprise 39 fois sur 121, dix fois le taux de base de cette classe.

Stack technique

Ce que j’ai appris

Limites

Mots-clés

classification de texte · détection d’émotions · analyse de sentiments · RNN · LSTM · GRU · réseaux de neurones récurrents · from scratch · RNN bidirectionnel · GloVe · embeddings de mots · embedding one-hot · NLP · dair-ai/emotion · F1 macro · matrice de confusion · PyTorch · NLTK · test de surapprentissage · vérifications de cohérence