Применение метода PyTorch CrossEntropy для мультиклассовой сегментации

Я пытаюсь реализовать простой пример того, как применить кросс-энтропию к тому, что должно быть результатом моей семантической сегментации CNN.

Используя формат pytorch, у меня было бы что-то вроде этого:

out = np.array([[
    [
        [1.,1, 1], 
        [0, 0, 0], 
        [0, 0, 0],
        [0, 0, 0]
    ],
    [
        [0, 0, 0],
        [1, 1, 1],
        [0, 0.,0],
        [0, 0, 0]
    ],
    [
        [0, 0, 0],
        [0, 0, 0],
        [1, 1, 1],
        [0, 0, 0]
    ],
    [
        [0, 0, 0],
        [0, 0, 0],
        [0, 0, 0],
        [1, 1, 1]
    ]
]])

out = torch.tensor(out)

Итак, мои выходные данные здесь имеют размеры (1, 4, 4, 3), представляющие собой пакет из 1 элемента, 4 канала, представляющие 4 возможных класса, и данные 4 на 3 в каждом, сохраняя вероятность того, что эта ячейка принадлежит этому классу.

Теперь моя цель такая:

target=[
        [0, 0, 0],
        [1, 1, 1],
        [2, 2, 2],
        [3, 3, 3]
    ]

Обратите внимание, что в тензоре out каждая строка имеет вероятность 1,0 принадлежать к этому классу, что приводит к идеальному совпадению с целью.

Например, третий канал (канал 2) имеет всю свою 3-ю строку (строка 2) с вероятностью 1,0 из этого канала и нулями в любом другом месте; так что он также соответствует двойкам на цели в третьей строке.

В этом примере я ожидаю минимального значения потерь между двумя тензорами.

Мой вопрос:

  • Как лучше всего использовать метод кросс-энтропийной потери в PyTorch, чтобы отразить, что в этом случае нет разницы между целью и ее предсказанием?
  • Какой размер убытка я должен ожидать от этого?

Вот что у меня получилось:

import torch
from torch.nn import CrossEntropyLoss
import numpy as np

out = torch.Tensor(np.array([[
    [
        [1.,1, 1], 
        [0, 0, 0], 
        [0, 0, 0],
        [0, 0, 0]
    ],
    [
        [0, 0, 0],
        [1, 1, 1],
        [0, 0.,0],
        [0, 0, 0]
    ],
    [
        [0, 0, 0],
        [0, 0, 0],
        [1, 1, 1],
        [0, 0, 0]
    ],
    [
        [0, 0, 0],
        [0, 0, 0],
        [0, 0, 0],
        [1, 1, 1]
    ]
]]))

target = torch.Tensor([[
    [0, 0, 0],
    [1, 1, 1],
    [2, 2, 2],
    [3, 3, 3]
]]).type('torch.LongTensor')

criterion = CrossEntropyLoss()
print(criterion(out, target))

И выходы: tensor(0.7437)

  • Разве я не должен ожидать значения ближе к cero?

заранее спасибо




Ответы (1)


Посмотрите описание nn.CrossEntropyLoss функции, прогноз out, которые вы предоставляете nn.CrossEntropyLoss, не обрабатываются как вероятности класса, а скорее как логиты; Функция потерь выводит вероятности классов из out с помощью soft max, поэтому nn.CrossEntropyLoss никогда не выдаст точно нулевые потери. .

person Shai    schedule 14.02.2019
comment
простите меня за глупый вопрос, но не могли бы вы уточнить ответ немного подробнее, в частности о том, как логиты обрабатываются в функции потерь - person Inder; 14.02.2019
comment
@Shai Понятно. Знаете ли вы, какой метод в PyTorch на самом деле отражает близкое к нулю значение потерь между «выходом» и «целью», как я предполагаю в примере? Или мне, может быть, следует преобразовать мои «целевые» данные? - person lvl; 14.02.2019