Все задачи
Легко Решено: 0 Процент решений: 0%

Категориальная перекрёстная энтропия

Вычислите потери многоклассового классификатора по предсказанным вероятностям и истинным классам.

Чему вы научитесь

  • Оценивать предсказанные вероятности по истинным классам
  • Усреднять потери по примерам
  • Избегать log(0) с помощью ограничения

Условие

Многоклассовый классификатор выдаёт по одной вероятности на класс (например, через softmax). Категориальная перекрёстная энтропия штрафует его, когда он даёт правильному классу низкую вероятность:

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

где pᵢ — вероятность, которую модель дала правильному классу примера i. Чтобы избежать ln(0), сначала поднимите все вероятности меньше 0.0000001 до 0.0000001.

Реализуйте categorical_cross_entropy(probabilities, labels).

Входные данные

probabilities: по одной строке на пример, по одной вероятности на класс.

labels: индекс правильного класса каждого примера (с 0).

Выходные данные

Верните средние потери как дробное число.

Ограничения

1 ≤ число примеров ≤ 1000, 2 ≤ число классов ≤ 100

0 ≤ каждая вероятность ≤ 1

0 ≤ labels[i] < число классов

Примеры

Пример 1
Ввод:
labels = [0, 1]
probabilities = [
    [0.7, 0.2, 0.1],
    [0.1, 0.8, 0.1]
]

Ожидаемый вывод:
expected = 0.289909
Ввод:
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}
};

Ожидаемый вывод:
double expected = 0.289909;
Ввод:
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}
};

Ожидаемый вывод:
double expected = 0.289909;

Пояснение

Правильные классы получили 0.7 и 0.8: -(ln(0.7) + ln(0.8)) / 2 = -(-0.356675 - 0.223144) / 2 ≈ 0.289909.

Пример 2
Ввод:
labels = [1]
probabilities = [
    [1.0, 0.0]
]

Ожидаемый вывод:
expected = 16.118096
Ввод:
std::vector<long long> labels = {1};
std::vector<std::vector<double>> probabilities = {
    {1.0, 0.0}
};

Ожидаемый вывод:
double expected = 16.118096;
Ввод:
long[] labels = new long[] {1};
double[][] probabilities = new double[][] {
    new double[] {1.0, 0.0}
};

Ожидаемый вывод:
double expected = 16.118096;

Пояснение

Правильный класс получил вероятность 0, которая поднимается до 0.0000001, поэтому потери равны -ln(0.0000001) ≈ 16.118096: уверенный неверный ответ сильно штрафуется.

Ссылки

Это задание адаптировано для CodeUtility. Следуйте условию и ограничениям выше.

Учитесь у других

Решения сообщества

Пока нет опубликованных решений. Решите задание, чтобы поделиться первым.