我对Pytorch如何处理独热编码向量感到非常困惑。在这个教程中,神经网络会生成一个独热编码向量作为其输出。据我所知,教程中神经网络的示意结构应该如下:
然而,labels
并不是独热编码向量格式。我得到了以下size
print(labels.size())print(outputs.size())output>>> torch.Size([4]) output>>> torch.Size([4, 10])
奇迹般地,当我将outputs
和labels
传递给criterion=CrossEntropyLoss()
时,竟然没有错误。
loss = criterion(outputs, labels) # 为什么没有错误?
我的假设:
也许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 blabels_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) # 现在它给我报错
然而,我得到了以下错误
RuntimeError: multi-target not supported at /opt/pytorch/pytorch/aten/src/THCUNN/generic/ClassNLLCriterion.cu:15
那么,Pytorch不支持独热编码向量吗?Pytorch如何为两个张量outputs = [1,0,0],[0,0,1]
和labels = [0,2]
计算交叉熵
?这对我来说完全没有意义。
回答:
PyTorch在其CrossEntropyLoss
文档中说明
该标准期望一个大小为minibatch的一维张量的值的目标为类索引(0到C-1)
换句话说,它在CEL
中概念上内置了你的to_one_hot_vector
函数,并且不公开独热编码API。请注意,与存储类标签相比,独热编码向量在内存使用上效率较低。
如果你被给予独热编码向量并且需要转换为类标签格式(例如为了与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()