87 votes

Comment Keras gère-t-il la classification multi-label ?

Je ne sais pas comment interpréter le comportement par défaut de Keras dans la situation suivante :

Mon Y (vérité terrain) a été mis en place en utilisant la méthode de scikit-learn. MultilabelBinarizer ().

Par conséquent, pour donner un exemple au hasard, une ligne de mon fichier y est codée comme telle : [0,0,0,1,0,1,0,0,0,0,1] .

J'ai donc 11 classes qui peuvent être prédites, et plus d'une peut être vraie ; d'où la nature multi-label du problème. Il y a trois étiquettes pour cet échantillon particulier.

J'entraîne le modèle comme je le ferais pour un problème non multilabel (comme d'habitude) et je n'obtiens aucune erreur.

from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation
from keras.optimizers import SGD

model = Sequential()
model.add(Dense(5000, activation='relu', input_dim=X_train.shape[1]))
model.add(Dropout(0.1))
model.add(Dense(600, activation='relu'))
model.add(Dropout(0.1))
model.add(Dense(y_train.shape[1], activation='softmax'))

sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy',
              optimizer=sgd,
              metrics=['accuracy',])

model.fit(X_train, y_train,epochs=5,batch_size=2000)

score = model.evaluate(X_test, y_test, batch_size=2000)
score

Que fait Keras lorsqu'il rencontre mon y_train et voit qu'il est codé en "multi" one-hot, ce qui signifie qu'il y a plus d'un "un" dans chaque ligne de y_train ? En gros, est-ce que Keras effectue automatiquement la classification multi-label ? Y a-t-il des différences dans l'interprétation des mesures de notation ?

135voto

frankyjuang Points 1952

En bref

N'utilisez pas softmax .

Utilisez sigmoid pour l'activation de votre couche de sortie.

Utilisez binary_crossentropy pour la fonction de perte.

Utilisez predict pour l'évaluation.

Pourquoi

Sur softmax lorsqu'on augmente le score d'une étiquette, tous les autres sont diminués (c'est une distribution de probabilité). Ce n'est pas ce que vous voulez lorsque vous avez plusieurs étiquettes.

Code complet

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Activation
from tensorflow.keras.optimizers import SGD

model = Sequential()
model.add(Dense(5000, activation='relu', input_dim=X_train.shape[1]))
model.add(Dropout(0.1))
model.add(Dense(600, activation='relu'))
model.add(Dropout(0.1))
model.add(Dense(y_train.shape[1], activation='sigmoid'))

sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='binary_crossentropy',
              optimizer=sgd)

model.fit(X_train, y_train, epochs=5, batch_size=2000)

preds = model.predict(X_test)
preds[preds>=0.5] = 1
preds[preds<0.5] = 0
# score = compare preds and y_test

3 votes

Merci, vous me dites donc de décomposer mon problème multi-label en plusieurs problèmes de classification binaire ? Comment Keras sait-il que je lui donne une tâche de classification multi-label ?

7 votes

Oui, c'est ça. Keras n'a pas vraiment besoin de savoir. En utilisant sigmoid y binary_crossentropy les étiquettes seront améliorées individuellement, et c'est ce que vous voulez pour les tâches à étiquettes multiples, n'est-ce pas ?

0 votes

Comment obtiendrez-vous les classes qui ont 1

0voto

shantanu pathak Points 111

Réponse de la documentation de Keras

Je cite le document de Keras lui-même.

Ils ont utilisé la couche de sortie comme couche dense avec une activation sigmoïde. Ils traitent également la classification multi-label comme une classification multi-binaire avec une perte d'entropie croisée binaire.

Voici le modèle créé dans la documentation de Keras

shallow_mlp_model = keras.Sequential( [ layers.Dense(512, activation="relu"), layers.Dense(256, activation="relu"), layers.Dense(lookup.vocabulary_size(), activation="sigmoid"), ] # Plus de détails sur la raison pour laquelle "sigmoïde" a été utilisé ici dans un moment.

Lien vers la documentation Keras : : https://keras.io/examples/nlp/multi_label_classification/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X