Todos os desafios
Fácil 0 resolvidos 0% de aceitação

Entropia cruzada categórica

Meça a perda de um classificador multiclasse a partir das probabilidades previstas e das classes verdadeiras.

O que você vai aprender

  • Avaliar probabilidades previstas contra as classes reais
  • Tirar a média da perda entre as amostras
  • Evitar log(0) limitando os valores

Problema

Ver original (inglês)

Um classificador multiclasse retorna uma probabilidade por classe (por exemplo, com softmax). A entropia cruzada categórica o penaliza quando ele dá uma probabilidade baixa à classe correta:

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

onde pᵢ é a probabilidade que o modelo deu à classe correta do exemplo i. Para evitar ln(0), primeiro eleve qualquer probabilidade menor que 0.0000001 para 0.0000001.

Implemente categorical_cross_entropy(probabilities, labels).

Entrada

probabilities: Uma linha por exemplo, com uma probabilidade por classe.

labels: O índice da classe correta de cada exemplo (começando em 0).

Saída

Retorne a perda média como número decimal.

Restrições

1 ≤ exemplos ≤ 1.000, 2 ≤ classes ≤ 100

0 ≤ cada probabilidade ≤ 1

0 ≤ labels[i] < número de classes

Exemplos

Exemplo 1
Entrada:
labels = [0, 1]
probabilities = [
    [0.7, 0.2, 0.1],
    [0.1, 0.8, 0.1]
]

Saída esperada:
expected = 0.289909
Entrada:
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}
};

Saída esperada:
double expected = 0.289909;
Entrada:
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}
};

Saída esperada:
double expected = 0.289909;

Explicação

As classes corretas receberam 0.7 e 0.8: -(ln(0.7) + ln(0.8)) / 2 = -(-0.356675 - 0.223144) / 2 ≈ 0.289909.

Exemplo 2
Entrada:
labels = [1]
probabilities = [
    [1.0, 0.0]
]

Saída esperada:
expected = 16.118096
Entrada:
std::vector<long long> labels = {1};
std::vector<std::vector<double>> probabilities = {
    {1.0, 0.0}
};

Saída esperada:
double expected = 16.118096;
Entrada:
long[] labels = new long[] {1};
double[][] probabilities = new double[][] {
    new double[] {1.0, 0.0}
};

Saída esperada:
double expected = 16.118096;

Explicação

A classe correta recebeu probabilidade 0, que é elevada para 0.0000001, então a perda é -ln(0.0000001) ≈ 16.118096: uma resposta errada dada com confiança é punida com força.

Referências

Este desafio foi adaptado para o CodeUtility. Siga o enunciado e as restrições acima.

Aprenda com outros

Soluções da comunidade

Ainda não há soluções publicadas. Resolva este desafio para compartilhar a primeira.