Pytorch 不支持 one-hot vector?

新手上路,请多包涵

我对 Pytorch 如何处理单热向量感到非常困惑。在本 教程 中,神经网络将生成一个单热向量作为其输出。据我了解,教程中神经网络的示意结构应该是这样的:

在此处输入图像描述

但是, labels 不是单热矢量格式。我得到以下 size

 print(labels.size())
print(outputs.size())

output>>> torch.Size([4])
output>>> torch.Size([4, 10])

奇迹般地,我将 outputslabels 传递给 criterion=CrossEntropyLoss() ,完全没有错误。

 loss = criterion(outputs, labels) # How come it has no error?

我的假设:

也许 pytorch 会自动将 labels 转换为单热矢量形式。因此,我尝试在将标签传递给损失函数之前将其转换为单热向量。

 def to_one_hot_vector(num_class, label):
    b = np.zeros((label.shape[0], num_class))
    b[np.arange(label.shape[0]), label] = 1

    return b

labels_one_hot = to_one_hot_vector(10,labels)
labels_one_hot = torch.Tensor(labels_one_hot)
labels_one_hot = labels_one_hot.type(torch.LongTensor)

loss = criterion(outputs, labels_one_hot) # Now it gives me error

但是,我收到以下错误

RuntimeError:/opt/pytorch/pytorch/aten/src/THCUNN/generic/ClassNLLCriterion.cu:15 不支持多目标

那么,在 Pytorch 中不支持单热向量? How does Pytorch calculates the cross entropy for the two tensor outputs = [1,0,0],[0,0,1] and labels = [0,2] ?目前对我来说完全没有意义。

原文由 Raven Cheuk 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 506
2 个回答

PyTorch 在其文档中声明 CrossEntropyLoss

该标准期望一个类索引(0 到 C-1)作为大小为 minibatch 的一维张量的每个值的目标

换句话说,它有你的 to_one_hot_vector 概念上内置的功能 CEL 并且不公开单热 API。请注意,与存储类标签相比,one-hot 向量的内存效率较低。

如果您获得了单热向量并且需要转到类标签格式(例如与 CEL 兼容),您可以使用 argmax 如下所示:

 import torch

labels = torch.tensor([1, 2, 3, 5])
one_hot = torch.zeros(4, 6)
one_hot[torch.arange(4), labels] = 1

reverted = torch.argmax(one_hot, dim=1)
assert (labels == reverted).all().item()

原文由 Jatentaki 发布,翻译遵循 CC BY-SA 4.0 许可协议

此代码将帮助您进行 一次热编码 和 _多次热编码_:

 import torch
batch_size=10
n_classes=5
target = torch.randint(high=5, size=(1,10)) # set size (2,10) for MHE
print(target)
y = torch.zeros(batch_size, n_classes)
y[range(y.shape[0]), target]=1
y

OHE 中的输出

tensor([[4, 3, 2, 2, 4, 1, 1, 1, 4, 2]])

tensor([[0., 0., 0., 0., 1.],
        [0., 0., 0., 1., 0.],
        [0., 0., 1., 0., 0.],
        [0., 0., 1., 0., 0.],
        [0., 0., 0., 0., 1.],
        [0., 1., 0., 0., 0.],
        [0., 1., 0., 0., 0.],
        [0., 1., 0., 0., 0.],
        [0., 0., 0., 0., 1.],
        [0., 0., 1., 0., 0.]])

当我设置 target = torch.randint(high=5, size=(2,10))

 tensor([[3, 2, 4, 4, 2, 4, 0, 4, 4, 1],
        [4, 1, 1, 3, 2, 2, 4, 2, 4, 3]])

tensor([[0., 0., 0., 1., 1.],
        [0., 1., 1., 0., 0.],
        [0., 1., 0., 0., 1.],
        [0., 0., 0., 1., 1.],
        [0., 0., 1., 0., 0.],
        [0., 0., 1., 0., 1.],
        [1., 0., 0., 0., 1.],
        [0., 0., 1., 0., 1.],
        [0., 0., 0., 0., 1.],
        [0., 1., 0., 1., 0.]])

如果您需要多个 OHE:

 torch.nn.functional.one_hot(target)

tensor([[[0, 0, 0, 1, 0],
         [0, 0, 1, 0, 0],
         [0, 0, 0, 0, 1],
         [0, 0, 0, 0, 1],
         [0, 0, 1, 0, 0],
         [0, 0, 0, 0, 1],
         [1, 0, 0, 0, 0],
         [0, 0, 0, 0, 1],
         [0, 0, 0, 0, 1],
         [0, 1, 0, 0, 0]],

        [[0, 0, 0, 0, 1],
         [0, 1, 0, 0, 0],
         [0, 1, 0, 0, 0],
         [0, 0, 0, 1, 0],
         [0, 0, 1, 0, 0],
         [0, 0, 1, 0, 0],
         [0, 0, 0, 0, 1],
         [0, 0, 1, 0, 0],
         [0, 0, 0, 0, 1],
         [0, 0, 0, 1, 0]]])

原文由 prosti 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题