我在一个项目中使用加速数据来预测一些活动。
但我在损失计算上有问题。我用的是CrossEntropyLoss
数据如下所示
我使用每行的前4个数据来预测索引,就像每行的最后一个一样。

1 84 84 81 4
81 85 85 80 1
81 82 84 80 1
1 85 84 2 0
81 85 82 80 1
81 82 84 80 1
81 25 84 80 5

错误消息如下。
minoh@minoh-VirtualBox:~/cow$ python lec5.py
Traceback (most recent call last):
  File "lec5.py", line 97, in <module>
    train(epoch)
  File "lec5.py", line 74, in train
    loss = criterion(y_pred, labels)
  File "/home/minoh/anaconda3/lib/python3.6/site-packages/torch/nn/modules/module.py", line 357, in __call__
    result = self.forward(*input, **kwargs)
  File "/home/minoh/anaconda3/lib/python3.6/site-packages/torch/nn/modules/loss.py", line 679, in forward
    self.ignore_index, self.reduce)
  File "/home/minoh/anaconda3/lib/python3.6/site-packages/torch/nn/functional.py", line 1161, in cross_entropy
    return nll_loss(log_softmax(input, 1), target, weight, size_average, ignore_index, reduce)
  File "/home/minoh/anaconda3/lib/python3.6/site-packages/torch/nn/functional.py", line 1052, in nll_loss
    return torch._C._nn.nll_loss(input, target, weight, size_average, ignore_index, reduce)
RuntimeError: multi-target not supported at /opt/conda/conda-bld/pytorch_1518243271935/work/torch/lib/THNN/generic/ClassNLLCriterion.c:22

我的代码基于Sung Kim's pytorch
import numpy as np
import torch
from torch.autograd import Variable
import torch.nn.functional as F
from torch.utils.data import Dataset, DataLoader
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms

class CowDataset(Dataset):
    def __init__(self):
        xy_str = np.loadtxt('cow_test', delimiter = ' ', dtype = np.str)
        xy = xy_str.astype(np.float32)
        xy_int = xy_str.astype(np.int)
        self.len = xy.shape[0]
        self.x_data = torch.from_numpy(xy[:, 0:4])
        self.y_data = torch.from_numpy(xy_int[:, [4]])

    def __getitem__(self, index):
        return self.x_data[index], self.y_data[index]

    def __len__(self):
        return self.len

dataset = CowDataset()
train_loader = DataLoader(dataset = dataset, batch_size = 32, shuffle = True)

class CowTestset(Dataset):
        def __init__(self):
                xy_str = np.loadtxt('cow_test2', delimiter = ' ', dtype =np.str)
                xy = xy_str.astype(np.float32)
                xy_int = xy_str.astype(np.int)
                self.len = xy.shape[0]
                self.x_data = torch.from_numpy(xy[:, 0:4])
                self.y_data = torch.from_numpy(xy_int[:, [4]])

        def __getitem__(self, index):
                return self.x_data[index], self.y_data[index]

        def __len__(self):
                return self.len

testset = CowTestset()
test_loader = DataLoader(dataset = testset, batch_size = 32, shuffle = True)

class Model(torch.nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.l1 = torch.nn.Linear(4,5)
        self.l2 = torch.nn.Linear(5,7)
        self.l3 = torch.nn.Linear(7,6)
        self.sigmoid = torch.nn.Sigmoid()

    def forward(self, x):
        out1 = self.sigmoid(self.l1(x))
        out2 = self.sigmoid(self.l2(out1))
        y_pred = self.sigmoid(self.l3(out2))
        return y_pred

model = Model()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr = 0.1, momentum = 0.5)

def train(epoch):
    model.train()
    for batch_idx, (inputs, labels) in enumerate(train_loader):
        inputs, labels = Variable(inputs), Variable(labels)
        optimizer.zero_grad()
        y_pred = model(inputs)
        loss = criterion(y_pred, labels)
        loss.backward()
        optimizer.step()
        if batch_idx % 10 == 0:
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                epoch, batch_idx * len(data), len(train_loader.dataset),
                100. * batch_idx / len(train_loader), loss.data[0]))

def test():
    model.eval()
    test_loss = 0
    correct = 0
    for data, target in test_loader:
        data, target = Variable(data, volatile = True), Variable(target)
        print(target)
        output = model(data)
        test_loss += criterion(output, target).data[0]
        pred = output.data.max(1, keepdim = True)[1]
        correct += pred.eq(target.data.view_as(pred)).cpu().sum()
    test_loss /= len(test_loader.dataset)
    print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(test_loader.dataset), 100.* correct / len(test_loader.dataset)))

for epoch in range(1,7):
    train(epoch)
    test()

最佳答案

好啊。所以我复制了你的问题,在搜索和阅读了CrossEntropyLoss()的API之后,我发现这是因为你有一个错误的标签尺寸。
Offical docs of CrossEntropyLoss这里。你可以看到
输入:(n,c)其中c=类数
目标:(n)其中每个值为0≤目标[i]≤c-1
在这里,在您的criterion()函数中,您有一个batchSize x 7输入和batchSize x 1标签。令人困惑的是,假设你的batchSize是10,10x1张量不能被看作是10张量,这就是损失函数所期望的。必须明确地进行大小转换。
解决方案:
在调用labels = labels.squeeze_()之前添加loss = criterion(y_pred, labels)并在测试代码中执行相同的操作。squeeze_()函数将删除1号尺寸。现在你有一个batchSize大小的标签。

关于python - pytorch错误:CrossEntropyLoss()不支持多目标,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49206550/

10-11 20:22