#pytorch #loss-function #conv-neural-network
#pytorch #функция потерь #conv-нейронная сеть
Вопрос:
Я видел, как решатель судоку CNN использует разреженную категориальную перекрестную энтропию в качестве функции потерь, используя фреймворк TensorFlow, мне интересно, существует ли аналогичная функция для Pytorch? если нет, то как я мог бы потенциально вычислить потерю 2d-массива с помощью Pytorch?
Комментарии:
1.
nn.CrossEntropyLoss
является разреженной категориальной перекрестной энтропией (т. Е. Принимает целые числа в качестве целевых значений вместо одноразовых векторов).2. итак, могу ли я использовать 2d-массив в качестве выходных данных и цели?
3. Нет, вы должны использовать 2d массив в качестве выходных данных и 1d массив целочисленных индексов в качестве целевых значений. Смотрите Этот ответ для получения информации о различиях.
4. Я предполагаю, что для игры в судоку каждый квадрат будет иметь собственный вывод в 9 логитов, поэтому сеть будет выводить
[B, 9, 81]
тензор логитов, а целями будут тензор формы,[B, 81]
содержащий целые числа от 0 до 8 включительно (соответствующие отметкам от 1 до 9 соответственно), гдеB
— размер пакета.
Ответ №1:
Вот пример использования nn.Перекрестные энтропийные потери для сегментации изображения с пакетом классов size 1, width 2, height 2 и 3.
Сегментация изображения — это проблема классификации на уровне пикселей. Конечно, вы также можете использовать nn.CrossEntropyLoss и для базовой классификации изображений.
Проблему судоку в вопросе можно рассматривать как проблему сегментации изображения, где у вас есть 10 классов (10 цифр) (хотя нейронные сети не подходят для решения комбинаторных задач, таких как судоку, которые уже имеют эффективные алгоритмы точного разрешения).
nn.CrossEntropyLoss принимает метки истинности непосредственно как целые числа в [0, N_CLASSES[ (нет необходимости кодировать метки onehot):
import torch
from torch import nn
import numpy as np
# logits predicted
x = np.array([[
[[1,0,0],[1,0,0]], # predict class 0 for pixel (0,0) and class 0 for pixel (0,1)
[[0,1,0],[0,0,1]], # predict class 1 for pixel (1,0) and class 2 for pixel (1,1)
]])*5 # multiply by 5 to give bigger losses
print("logits map :")
print(x)
# ground truth labels
y = np.array([[
[0,1], # must predict class 0 for pixel (0,0) and class 1 for pixel (0,1)
[1,2], # must predict class 1 for pixel (1,0) and class 2 for pixel (1,1)
]])
print("nlabels map :")
print(y)
x=torch.Tensor(x).permute((0,3,1,2)) # shape of preds must be (N, C, H, W) instead of (N, H, W, C)
y=torch.Tensor(y).long() # shape of labels must be (N, H, W) and type must be long integer
losses = nn.CrossEntropyLoss(reduction="none")(x, y) # reduction="none" to get the loss by pixel
print("nLosses map :")
print(losses)
# notice that the loss is big only for pixel (0,1) where we predicted 0 instead of 1