Как рассчитать кросс-энтропию из вероятностей в PyTorch? - PullRequest
2 голосов
/ 11 февраля 2020

По умолчанию PyTorch cross_entropy принимает логиты (необработанные выходные данные модели) в качестве входных данных. Я знаю, что CrossEntropyLoss объединяет LogSoftmax (log (softmax (x))) и NLLLoss (потеря отрицательного логарифма) в одном классе. Итак, я думаю, что могу использовать NLLLoss для получения кросс-энтропийной потери от вероятностей следующим образом:

истинные метки: [1, 0, 1]
вероятности: [0,1, 0,9] , [0,9, 0,1], [0,2, 0,8]

enter image description here

, где y_i,j обозначает истинное значение, т.е. 1, если образец i принадлежит классу j и 0 в противном случае. и p_i,j обозначает вероятность, предсказанную вашей моделью выборки i, принадлежащей классу j.

Если я вычислю вручную, получится:

>>> -(math.log(0.9) + math.log(0.9) + math.log(0.8))
0.4338

Использование PyTorch:

>>> labels = torch.tensor([1, 0, 1], dtype=torch.long)
>>> probs = torch.tensor([[0.1, 0.9], [0.9, 0.1], [0.2, 0.8]], dtype=torch.float)
>>> F.nll_loss(torch.log(probs), labels)
tensor(0.1446)

Что я делаю не так? Почему ответ отличается?

1 Ответ

3 голосов
/ 11 февраля 2020

В PyTorch есть параметр уменьшения для всех функций потерь. Как видно из документации , параметр сокращения по умолчанию равен «среднее», которое делит сумму на количество элементов в пакете. Чтобы получить поведение суммирования (0,4338), как вам нужно, вы должны задать параметр сокращения следующим образом:

F.nll_loss(torch.log(probs), labels,reduction='sum')
...