Classificateur de texte avec plusieurs sorties et plusieurs pertes dans Keras
Dans cet article, nous allons passer en revue la définition d’un classificateur multi-étiquettes, les pertes multiples, le prétraitement de texte et une explication étape par étape sur la façon de construire un RNN-LSTM multi-sortie dans Keras.
L’ensemble de données sur lequel nous travaillerons consiste en des messages de catastrophe naturelle classés en 36 classes différentes. L’ensemble de données a été fourni par Figure huit. Exemple de messages d’entrée:
['Weather update - a cold front from Cuba that could pass over Haiti',
'Is the Hurricane over or is it not over',
'Looking for someone but no name',
'UN reports Leogane 80-90 destroyed. Only Hospital St. Croix functioning. Needs supplies desperately.',
'says: west side of Haiti, rest of the country today and tonight']
Avant d’expliquer de quoi il s’agit, examinons d’abord la définition d’un type de classification plus courant: multiclasse. Dans une multiclasse, les classes s’excluent mutuellement, c’est-à-dire que vous ne pouvez classer qu’une classe à la fois. Par exemple, si vous avez les classes: {Voiture, Personne, Moto}, votre modèle devra afficher: Voiture OU Personne OU Moto. Pour ce type de problème, une fonction Softmax est utilisée pour la classification:
Pour la classification multi-étiquettes, un échantillon de données peut appartenir à plusieurs classes. A partir de l’exemple ci-dessus, votre modèle peut classer, pour le même échantillon, les classes: Voiture ET Personne (en imaginant que chaque échantillon est une image pouvant contenir ces 3 classes).
Dans l’ensemble de données étudié, il existe 36 classes différentes, dont 35 d’entre elles ont un sortie binaire: 0 ou 1; et 1 d’entre eux a 3 classes possibles (un cas multiclasse): 0, 1 ou 2.
L’utilisation de plusieurs fonctions de perte dans le même modèle signifie que vous effectuez différentes tâches et partagez une partie de votre modèle entre ces tâches. Parfois, vous pensez peut-être qu’il vaut mieux construire des modèles différents pour chaque type de sortie, mais dans certaines situations, le partage de certaines couches de votre réseau neuronal aide les modèles à mieux se généraliser.
Comment Keras gère-t-il les pertes multiples?
Du Documentation Keras, « … La valeur de perte qui sera minimisée par le modèle sera alors la somme pondérée de toutes les pertes individuelles, pondérée par le loss_weights
coefficients.« . Par conséquent, la perte finale est une somme pondérée de chaque perte, transmise au loss
paramètre.
Dans le cas étudié, deux pertes différentes seront utilisées:
- Pour le classes binaires, la métrique utilisée sera la
binary_accuracy
avec le correspondantbinary_crossentropy
perte. Puisqu’il n’y a que deux classes possibles pour chaque sortie (0 ou 1), lesigmoid
sera utilisée comme fonction d’activation. - Pour le multiclasse production, la métrique utilisée sera la
sparse_categorical_accuracy
avec le correspondantsparse_categorical_crossentropy
perte. Pour cette sortie, il existe 3 classes possibles: 0, 1 et 2, de cette façon lesoftmax
la fonction d’activation sera utilisée. Différemment du classiquecategorical_crossentropy
perte, le premier ne nécessite pas la sortie Oui être codé à chaud. Par conséquent, au lieu de transformer la sortie en: [1, 0, 0], [0, 1, 0] et [0, 0, 1], nous pouvons le laisser sous forme d’entiers: [0], [1] et [2]. Il est important de souligner que les deux pertes partagent la même équation:
Comme pour tout autre problème de PNL, avant d’appliquer les données d’entrée de texte dans le modèle, nous devons le prétraiter. Dans cet ensemble de données, les signes de ponctuation, les liens URL et les mentions «@» ont été supprimés. Même si la mention «@» ajoute des informations au message, elle n’ajoute pas de valeur au modèle de classification. Hashtags (‘#’) peut contenir des informations utiles car elles sont généralement liées à des événements. Par conséquent, ils ont été conservés, supprimant uniquement le caractère «#».
Mots d’arrêt (mots les plus courants dans une langue) la suppression et la lemmatisation ont également été appliquées à l’ensemble de données.
Les exemples de texte sont formatés en tenseurs qui peuvent être introduits dans un réseau de neurones à l’aide des utilitaires Keras:
La procédure ci-dessus comprend principalement 3 étapes:
- Tout d’abord, une instance de Tokenizer est installée (
fit_on_texts
) au corpus créant un index de vocabulaire basé sur la fréquence des mots. Chaque mot est mappé à un index, donc chaque mot obtient une valeur entière unique, un entier inférieur signifie des mots plus fréquents. La taille des mots à conserver est définie par lenum_words
paramètre, c’est-à-dire la taille du vocabulaire. Seuls les mots les plus courants seront conservés. Dans notre jeu de données, les mots ont été mappés comme suit:
print(tokenizer.word_index){'water': 1, 'people': 2, 'food': 3, 'need': 4, 'help': 5, 'please': 6, 'earthquake': 7, 'would': 8, 'area': 9, 'like': 10, 'said': 11, 'country': 12,...}
- Les phrases de l’entrée sont ensuite mappées en nombres entiers à l’aide du
tokenizer.texts_to_sequences
méthode. De notre exemple:
'weather update cold front cuba could pa haiti'
est mappé à:
[138, 1480, 335, 863, 2709, 80, 411, 18]
- Enfin, pour créer des plongements, toutes nos phrases doivent être de même longueur. Par conséquent, nous utilisons le
pad_sequences
pour remplir chaque phrase avec zéro.
Pour construire ce modèle, nous utiliserons API fonctionnelle Keras et non API séquentielle puisque le premier nous permet de construire des modèles plus complexes, comme des problèmes de sorties et d’entrées multiples.
Pour résumer ce que nous avons jusqu’à présent:
- chaque échantillon d’entrée est un vecteur d’entiers de taille MAXLEN (50)
- chaque échantillon sera classé en 36 classes différentes dont 35 d’entre elles ont un sortie binaire: 0 ou 1; et 1 d’entre eux a 3 classes possibles (un cas multiclasse): 0, 1 ou 2.
Architecture du modèle
Dans cette section, nous allons former nos propres incorporations à l’aide de Keras Embedding Layer.
La couche Embedding prend en entrée:
- input_dim: la taille du vocabulaire que nous avons choisie
- output_dim: la taille de l’incorporation. Dans notre cas, il était réglé sur 50d.
- longueur_entrée: Longueur des séquences d’entrée. Dans notre cas: MAXLEN
Une couche convolutionnelle a été ajoutée avant le LSTM afin d’accélérer le temps d’entraînement. CNN est plus susceptible d’extraire des éléments locaux et profonds des phrases. Vous pouvez en savoir plus sur la combinaison CNN et RNN dans Cet article.
Couche de sortie
La majorité des classes de sortie sont binaires, mais l’une d’entre elles est une sortie multiclasse. Comme expliqué dans la section Pertes multiples, les pertes utilisées sont: binary_crossentropy
et sparse_categorical_crossentropy
.
Étant donné que l’ensemble de données est fortement déséquilibré, class_weight
paramètre a été ajouté afin de réduire les distributions déséquilibrées. UNE Couche dense sera créé pour chaque sortie. Les sorties seront stockées dans un tableau, tandis que les métriques et les pertes, pour chaque sortie, seront stockées dans les dictionnaires correspondants.
Le code ci-dessus parcourt chacune des colonnes binaires de sortie et crée une couche dense, enregistrant la métrique et la perte correspondantes dans un dictionnaire.
Le code ci-dessous applique le même processus à la colonne de sortie multiclasse unique.
Pour chaque sortie, nous définissons ensuite le poids de chaque classe dans un format de dictionnaire:
Nous pouvons alors instancier une classe Model et former notre modèle:
Le modèle suit le format:
Apparemment, Keras a un question ouverte avec class_weights
et binary_crossentropy
pour les sorties multi-étiquettes. La solution proposée ci-dessus, en ajoutant une couche dense par sortie, est une solution valable.
Dans cet article, nous avons construit un classificateur de texte RNN à l’aide de l’API fonctionnelle Keras avec plusieurs sorties et pertes. Nous avons parcouru une explication sur les pertes multiples et également la différence entre un problème de classification multi-étiquettes et multi-classes.
Vous pouvez vérifier le code complet, avec une analyse supplémentaire, dans Ici! Dans ce post, nous avons formé nos propres plongements, dans le GitHub Repo, vous pouvez vérifier le même modèle recyclé en utilisant Vecteurs GloVe pré-formés.