Quelle fonction de perte pour les tâches de classification multi-classes, multi-étiquettes dans les réseaux de neurones?

64

J'entraîne un réseau de neurones pour classer un ensemble d'objets dans n-classes. Chaque objet peut appartenir à plusieurs classes à la fois (multi-classes, multi-étiquettes).

J'ai lu que pour les problèmes multi-classes, il est généralement recommandé d'utiliser une entropie croisée catégorique et softmax comme fonction de perte au lieu de mse et je comprends plus ou moins pourquoi.

Pour mon problème de multi-label, il n’aurait pas de sens d’utiliser softmax bien sûr, chaque probabilité de classe devant être indépendante de l’autre. Ma dernière couche est donc constituée uniquement d’appareils sigmoïdes qui réduisent leurs entrées dans une plage de probabilités de 0..1 pour chaque classe.

Maintenant, je ne suis pas sûr de la fonction de perte que je devrais utiliser pour cela. En regardant la définition de crossentropie catégorique, je pense que cela ne s'appliquerait pas bien à ce problème car il ne tiendra compte que de la sortie des neurones qui devrait être 1 et ignore les autres.

L'entropie croisée binaire semble être mieux adaptée, mais je ne la vois jamais mentionnée que pour les problèmes de classification binaire avec un seul neurone en sortie.

J'utilise python et keras pour m'entraîner au cas par cas.

aKzenT
la source
1
Je crois que softmax est "des unités sigmoïdes qui écrasent leurs entrées dans une plage de probabilités de 0..1 pour chaque classe".
Hong Ooi
Vous pouvez utiliser softmax comme fonction de perte, puis utiliser des probabilités pour multilabel vos données.
Balboa

Réponses:

30

Si vous utilisez keras, mettez simplement sigmoids sur votre couche de sortie et binary_crossentropy sur votre fonction de coût.

Si vous utilisez tensorflow, vous pouvez utiliser sigmoid_cross_entropy_with_logits . Mais dans mon cas, cette fonction de perte directe ne convergeait pas. Donc, j'ai fini par utiliser une perte d'entropie croisée sigmoïde explicite . Vous pouvez créer le vôtre comme dans cet exemple(yln(sigmoid(logits))+(1y)ln(1sigmoid(logits)))

Sigmoid, contrairement à softmax, ne donne pas en sortie la distribution de probabilité autour de , mais des probabilités indépendantes.nclasses

Si, en moyenne, moins de libellés sont attribués à une ligne, vous pouvez utiliser softmax_cross_entropy_with_logits car, avec cette perte, alors que les classes s'excluent mutuellement, leurs probabilités ne doivent pas nécessairement l'être. Tout ce qui est requis est que chaque ligne d'étiquettes constitue une distribution de probabilité valide. S'ils ne le sont pas, le calcul du gradient sera incorrect.

Alok Nayak
la source
Cher Alok, pouvez-vous expliquer au OP comment il compte utiliser cette fonction et pourquoi cela a du sens? Comme vous le verrez au cours de la visite , les réponses en lien uniquement ne sont pas encouragées sur le site.
Antoine Vernet
Une belle courte explication peut être vue dans keras github: github.com/fchollet/keras/issues/741
Dror Hilman
1
Il n'est pas recommandé d'écrire votre propre fonction de coût lors de l'utilisation de l'entropie croisée - elle peut être sujette à des problèmes de stabilité numérique. Voir github.com/tensorflow/tensorflow/issues/2462 pour une discussion.
kbrose
Une chose est multilabel, une autre chose est multiclass. Sigmoid écrase votre sortie entre 0 et 1, mais l'OP a plusieurs classes. Par conséquent, les sorties doivent être égales à 0 - 10. Les sorties doivent donc ressembler à: [0,5,2,3,1] <--- ce n'est pas ce que sigmoïde Est-ce que.
Mimoralea
dois-je tf.round (logits) avant d'utiliser dans la fonction de coût ou puis-je utiliser directement les logits de la couche cachée à tf.nn.sigmoid ....?
Moine
9

UPDATE (18/04/18): L'ancienne réponse s'avérait toujours utile sur mon modèle. L'astuce consiste à modéliser la fonction de partition et la distribution séparément, en exploitant ainsi la puissance de softmax.

Considérez que votre vecteur d’observation contient étiquettes. (1 si l'échantillon i contient l'étiquette m, 0 sinon). L’objectif serait donc de modéliser la matrice de manière individuelle. Par conséquent, le modèle évalue . Pensez à développer pour obtenir deux propriétés:ymyim=δimF(yi,xi)=logP(yi|xi)yim=ZP(ym)

  1. Fonction de distribution:mP(ym)=1
  2. Fonction de partition: estime le nombre d'étiquettesZ

Ensuite, il s’agit de modéliser les deux séparément. La fonction de distribution est mieux modélisée avec une couche softmax , et la fonction de partition peut être modélisée avec une unité linéaire (en pratique, je l'ai écrêtée sur . Une modélisation plus sophistiquée telle qu'une unité de Poisson fonctionnerait probablement mieux). Ensuite, vous pouvez choisir d'appliquer la perte distribuée (KL sur la distribution et MSE sur la partition), ou vous pouvez essayer la perte suivante sur leur produit.max(0.01,output)

En pratique, le choix de l'optimiseur fait également une énorme différence. Mon expérience avec l'approche par factorisation est que cela fonctionne mieux sous Adadelta (Adagrad ne fonctionne pas pour moi, je n'ai pas encore essayé RMSprop, les performances de SGD sont soumises à des paramètres).

Commentaire latéral sur sigmoïde : J'ai certainement essayé sigmoïde + croix croisée et cela n'a pas fonctionné. Le modèle inclinait à prédire le uniquement et n'a pas réussi à saisir la variation de la fonction de distribution. (alias, c'est en quelque sorte assez utile pour modéliser la partition et il peut y avoir une raison mathématique derrière cela)Z

UPDATE : (Pensée aléatoire) Il semble que l’utilisation du processus de Dirichlet permettrait l’intégration de certains éléments antérieurs sur le nombre d’étiquettes?

UPDATE : Par expérience, la divergence KL modifiée est toujours encline à donner une sortie multi-classe plutôt qu'une sortie multi-étiquette.


(Ancienne réponse)

Mon expérience avec l'entropie croisée sigmoïde n'était pas très agréable. Pour le moment, j'utilise une divergence KL modifiée. Il prend la forme

Loss(P,Q)=x|P(x)Q(x)||logP(x)Q(x)|=x|(P(x)Q(x))logP(x)Q(x)|
Où est la pseudo-distribution cible et est la pseudo-distribution prédite (mais la fonction est symétrique et n'a donc aucune importance)P(x)Q(x)

Ils sont appelés pseudo-distributions pour ne pas être normalisés. Vous pouvez donc avoir si vous avez 2 étiquettes pour un échantillon particulier.xP(x)=2

Keras impelmentation

def abs_KL_div(y_true, y_pred):
    y_true = K.clip(y_true, K.epsilon(), None)
    y_pred = K.clip(y_pred, K.epsilon(), None)
    return K.sum( K.abs( (y_true- y_pred) * (K.log(y_true / y_pred))), axis=-1)
devrait voir
la source
sur mon jeu de données particulier, adamétait beaucoup mieux quermsprop
shadi
Si vous utilisez une telle perte pour la formation, comment le faire en phase de test? Utilisez également softmax pour la prédiction, mais comment sélectionner le seuil pour déterminer les classes multi-étiquettes?
karl_TUM
1

Je n'ai pas encore utilisé de keras. Prenant caffe par exemple, vous pouvez utiliser SigmoidCrossEntropyLossLayerpour des problèmes multi-étiquettes.

Mintaka
la source
1
Vous voulez expliquer pourquoi c'est une bonne approche?
Firebug
0

En fait, dans tensorsflow, vous pouvez toujours utiliser la sigmoid_cross_entropy_meanfonction de calcul de perte en multi-étiquettes, je le confirme

un singe unique
la source
Donnez-nous un lien vers la documentation
Ivelin
0

Je suis un débutant ici mais je vais essayer de tenter le coup avec cette question. Je cherchais la même chose que vous et, finalement, j'ai trouvé un très bon tutoriel de classification multi-classes de keras @ http://machinelearningmastery.com/multi-class-classification-tutorial-keras-deep-learning-library/ .

L’auteur de ce tutoriel utilise une fonction de perte d’entropie croisée catégorique, et il existe un autre fil qui peut vous aider à trouver la solution @ ici .

Willy satrio nugroho
la source
3
Ce n'est pas seulement multi-classe, c'est aussi multi-étiquettes.
Moine