当对标签使用一种热编码时,Pytorch nn.CrossEntropyLoss 输出错误值

乘风 pytorch 259

原文标题Pytorch nn.CrossEntropyLoss output wrong values when using one hot encoding for label

我想传入一个包含 4 个这样的值的张量

[.45, .78, .23, .56]

并从网络中得到一个只有最后一个神经元像这样亮的输出

[0,0,0,1]

然后我想传入第二个张量[.67, .89, .34, .12]并从中得到一个输出,看起来像这样[1,0,0,0]只有第一个神经元亮起。

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

train = [
    [torch.FloatTensor([[.45, .78, .23, .56]]), torch.FloatTensor([[0,0,0,1]]) ],
    [torch.FloatTensor([[.67, .89, .34, .12]]), torch.FloatTensor([[1,0,0,0]]) ]
]


class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(4, 2)
        self.fc2 = nn.Linear(2, 4)

    def forward(self, x):
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        return F.softmax(x, dim=0)

net = Net()
print(net)

loss_function = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(net.parameters(), lr=0.1, momentum=0.9, nesterov=True)
criterion = nn.CrossEntropyLoss()

for epoch in range(10):
    for data in train:
        X, y = data
        
        net.zero_grad()
        output = net(X)
        loss = criterion(output, y)
        loss.backward()
        optimizer.step()
        
    print(loss) 

# test
X, y = torch.tensor([.45, .78, .23, .56]), torch.tensor([0,0,0,1])
print(net(X), y)

X, y = torch.tensor([.67, .89, .34, .12]), torch.tensor([1,0,0,0])
print(net(X), y)

不幸的是,网络输出垃圾,不对应任何特定的神经元点亮

tensor(1.3863, grad_fn=<DivBackward1>)
tensor(1.3863, grad_fn=<DivBackward1>)
tensor(1.3863, grad_fn=<DivBackward1>)
tensor(1.3863, grad_fn=<DivBackward1>)
tensor(1.3863, grad_fn=<DivBackward1>)
tensor(1.3863, grad_fn=<DivBackward1>)
tensor(1.3863, grad_fn=<DivBackward1>)
tensor(1.3863, grad_fn=<DivBackward1>)
tensor(1.3863, grad_fn=<DivBackward1>)
tensor(1.3863, grad_fn=<DivBackward1>)
tensor([0.3175, 0.1841, 0.2063, 0.2922], grad_fn=<SoftmaxBackward0>) tensor([0, 0, 0, 1])
tensor([0.3129, 0.1935, 0.2102, 0.2834], grad_fn=<SoftmaxBackward0>) tensor([1, 0, 0, 0])

我得到这样的输出[0.3175, 0.1841, 0.2063, 0.2922]这不是网络应该输出的。

我认为这可能是由于 CrossEntropyLoss 函数比较训练数据 (X) 和标签 y 的方式。我认为是这条线导致了问题loss = criterion(output, y)

我应该使用什么损失函数来获得所需的结果?

原文链接:https://stackoverflow.com//questions/71902203/pytorch-nn-crossentropyloss-output-wrong-values-when-using-one-hot-encoding-for

回复

我来回复
  • Piotr Grzybowski的头像
    Piotr Grzybowski 评论

    问题在于模型中正向函数的输出。 Softmax 应该在维度 1 而不是 0 上计算。请更改它然后它会收敛。

    dim (int) — 计算 Softmax 的维度(因此沿 dim 的每个切片的总和为 1)。

    您希望它在维度 1 上加到 1 而不是 0。为数据集中的每个样本而不是每个特征求和一个。

    Softmax 文档

    另一方面,Softmax 只会返回总和为 1 的值。

    这将不是[0, 1, 0, 0]的向量,而是,例如,[0.05, 0.90, 0.03, 0.01, 0.01]

    在预测之后,您仍然必须使用 argmax 或其他东西来选择最有可能的类。

    2年前 0条评论