Tous les défis
Facile 0 résolus 0 % de réussite

Entropie croisée catégorielle

Mesurez la perte d'un classifieur multiclasse à partir des probabilités prédites et des vraies classes.

Ce que vous allez apprendre

  • Évaluer les probabilités prédites face aux vraies classes
  • Faire la moyenne de la perte sur les exemples
  • Éviter log(0) en bornant les valeurs

Problème

Un classifieur multiclasse produit une probabilité par classe (par exemple avec softmax). L'entropie croisée catégorielle le pénalise lorsqu'il donne une faible probabilité à la bonne classe :

loss = -(ln(p₁) + ln(p₂) + … + ln(pₙ)) / n

où pᵢ est la probabilité donnée par le modèle à la bonne classe de l'exemple i. Pour éviter ln(0), relevez d'abord toute probabilité inférieure à 0.0000001 à 0.0000001.

Implémentez categorical_cross_entropy(probabilities, labels).

Entrée

probabilities : une ligne par exemple, avec une probabilité par classe.

labels : l'indice de la bonne classe de chaque exemple (à partir de 0).

Sortie

Renvoyez la perte moyenne sous forme de nombre décimal.

Contraintes

1 ≤ exemples ≤ 1 000, 2 ≤ classes ≤ 100

0 ≤ chaque probabilité ≤ 1

0 ≤ labels[i] < nombre de classes

Exemples

Exemple 1
Entrée :
labels = [0, 1]
probabilities = [
    [0.7, 0.2, 0.1],
    [0.1, 0.8, 0.1]
]

Sortie attendue :
expected = 0.289909
Entrée :
std::vector<long long> labels = {0, 1};
std::vector<std::vector<double>> probabilities = {
    {0.7, 0.2, 0.1},
    {0.1, 0.8, 0.1}
};

Sortie attendue :
double expected = 0.289909;
Entrée :
long[] labels = new long[] {0, 1};
double[][] probabilities = new double[][] {
    new double[] {0.7, 0.2, 0.1},
    new double[] {0.1, 0.8, 0.1}
};

Sortie attendue :
double expected = 0.289909;

Explication

Les bonnes classes ont reçu 0.7 et 0.8 : -(ln(0.7) + ln(0.8)) / 2 = -(-0.356675 - 0.223144) / 2 ≈ 0.289909.

Exemple 2
Entrée :
labels = [1]
probabilities = [
    [1.0, 0.0]
]

Sortie attendue :
expected = 16.118096
Entrée :
std::vector<long long> labels = {1};
std::vector<std::vector<double>> probabilities = {
    {1.0, 0.0}
};

Sortie attendue :
double expected = 16.118096;
Entrée :
long[] labels = new long[] {1};
double[][] probabilities = new double[][] {
    new double[] {1.0, 0.0}
};

Sortie attendue :
double expected = 16.118096;

Explication

La bonne classe a reçu la probabilité 0, relevée à 0.0000001, donc la perte vaut -ln(0.0000001) ≈ 16.118096 : une mauvaise réponse donnée avec assurance est lourdement pénalisée.

Références

Ce défi a été adapté pour CodeUtility. Suivez l'énoncé et les contraintes ci-dessus.

Apprenez des autres

Solutions de la communauté

Aucune solution publiée pour l'instant. Résolvez ce défi pour partager la première.