web-dev-qa-db-fra.com

Keras: crossentropie binaire pondérée

J'ai essayé d'implémenter une crossentropie binaire pondérée avec Keras, mais je ne suis pas sûr que le code soit correct. Le résultat de la formation semble être un peu déroutant. Après quelques époques, je n'ai plus qu'une précision d'environ 0,15. Je pense que c'est beaucoup trop moins (même pour une supposition aléatoire).

Il y a en général environ 11% dans la sortie et 89% de zéros; les poids sont donc w_zero = 0.89 et w_one = 0.11.

Mon code:

def create_weighted_binary_crossentropy(zero_weight, one_weight):

    def weighted_binary_crossentropy(y_true, y_pred):

        # Original binary crossentropy (see losses.py):
        # K.mean(K.binary_crossentropy(y_true, y_pred), axis=-1)

        # Calculate the binary crossentropy
        b_ce = K.binary_crossentropy(y_true, y_pred)

        # Apply the weights
        weight_vector = y_true * one_weight + (1. - y_true) * zero_weight
        weighted_b_ce = weight_vector * b_ce

        # Return the mean error
        return K.mean(weighted_b_ce)

    return weighted_binary_crossentropy

Peut-être que quelqu'un voit ce qui ne va pas?

Je vous remercie

6
Kevin Meier

Normalement, la classe minoritaire aura un poids plus élevé. Il vaut mieux utiliser one_weight=0.89, zero_weight=0.11 (au fait, vous pouvez utiliser class_weight={0: 0.11, 1: 0.89}, comme suggéré dans le commentaire).

Sous déséquilibre de classe, votre modèle voit beaucoup plus de zéros que d’autres. Il apprendra également à prévoir plus de zéros que ceux-ci, car la perte d’entraînement peut ainsi être minimisée. C'est aussi pourquoi vous voyez une précision proche de la proportion de 0,11. Si vous prenez une moyenne par rapport aux prévisions du modèle, elle devrait être très proche de zéro.

L’utilisation des pondérations de classe a pour but de modifier la fonction de perte afin que la «solution simple» (c’est-à-dire la prédiction de zéros) ne puisse minimiser la perte d’entraînement et c’est pourquoi il est préférable d’utiliser un poids plus élevé pour les uns.

Notez que les meilleurs poids ne sont pas nécessairement 0.89 et 0.11. Parfois, vous devrez peut-être essayer quelque chose comme prendre des logarithmes ou des racines carrées (ou n’importe quel poids satisfaisant one_weight > zero_weight) pour que cela fonctionne.

3
Yu-Yang

Je pense que l'utilisation du poids de classe dans model.fit n'est pas correcte. {0 : 0.11 1 : 0.89}, 0 voici l'index, pas la classe 0. Keras Documentation: https://keras.io/models/sequential/ Class_weight: index facultatif de mappage de dictionnaire (entiers) sur une valeur pondérée (float), utilisée pour pondérer la fonction de perte ( pendant l'entraînement seulement). Cela peut être utile pour dire au modèle de "faire plus attention" aux échantillons d'une classe sous-représentée.

0
Cheng Yang