nn.CrossEntropyLoss()的Pytorch输入

时间:2018-12-26 19:08:59

标签: pytorch logistic-regression

我正在尝试在PyTorch中对简单的0,1标记的数据集执行Logistic回归。该标准或损失定义为:criterion = nn.CrossEntropyLoss()。该模型为:model = LogisticRegression(1,2)

我有一对数据点:dat = (-3.5, 0),第一个元素是数据点,第二个元素是对应的标签。
然后,将输入的第一个元素转换为张量:tensor_input = torch.Tensor([dat[0]])
然后将模型应用于tensor_input:outputs = model(tensor_input)
然后,将标签转换为张量:tensor_label = torch.Tensor([dat[1]])
现在,当我尝试执行此操作时,事情就坏了:loss = criterion(outputs, tensor_label)。它给出错误:RuntimeError: Dimension out of range (expected to be in range of [-1, 0], but got 1)

import torch
import torch.nn as nn

class LogisticRegression(nn.Module):
    def __init__(self, input_size, num_classes):
        super(LogisticRegression, self).__init__()
        self.linear = nn.Linear(input_size, num_classes) 

    def forward(self, x):
        out = self.linear(x)
        return out

model = LogisticRegression(1,2)
criterion = nn.CrossEntropyLoss()
dat = (-3.5,0)
tensor_input = torch.Tensor([dat[0]])
outputs = binary_model(tensor_input)
tensor_label = torch.Tensor([dat[1]])
loss = criterion(outputs, tensor_label)

我一生无法解决。

2 个答案:

答案 0 :(得分:2)

在大多数情况下,PyTorch文档在解释不同功能方面做得非常出色。它们通常包括预期的输入尺寸以及一些简单的示例。
您可以找到nn.CrossEntropyLoss() here的描述。

要遍历您的特定示例,让我们首先查看预期的输入维度:

  

输入:(N,C),其中C =类数。 [...]

此外, N 通常是指批次大小(样本数量)。将此与您当前拥有的进行比较:

outputs.shape
>>> torch.Size([2])

即目前,我们只有(2,)的输入维度,而没有PyTorch期望的(1,2)的输入维度。我们可以通过简单地使用.unsqueeze()来为当前的张量添加“伪”维,从而减轻这种情况:

outputs = binary_model(tensor_input).unsqueeze(dim=0)
outputs.shape
>>> torch.Size([1,2])

现在我们明白了,让我们看一下目标的预期输入:

  

目标:(N)[...]

因此,我们已经有了正确的形状。但是,如果尝试这样做,我们仍然会遇到错误:

RuntimeError: Expected object of scalar type Long but got scalar type Float 
              for argument #2 'target'.

同样,该错误消息非常具有表现力。这里的问题是PyTorch张量(默认情况下)被解释为torch.FloatTensors,但是输入应该是整数(或Long)。我们可以通过在张量创建期间指定确切的类型来简单地做到这一点:

tensor_label = torch.LongTensor([dat[1]])

我正在Linux fyi下使用PyTorch 1.0。

答案 1 :(得分:0)

要在PyTorch中执行Logistic回归,您需要做三件事:

  • 标签(目标)编码为0或1;
  • Sigmoid激活位于最后一层,因此输出数量将为1;
  • 作为损失函数的二元交叉熵。

这里是最小的例子:

import torch
import torch.nn as nn


class LogisticRegression(nn.Module):
    def __init__(self, n_inputs, n_outputs):
        super(LogisticRegression, self).__init__()
        self.linear = nn.Linear(n_inputs, n_outputs)
        self.sigmoid = nn.Sigmoid()


    def forward(self, x):
        x = self.linear(x)
        return self.sigmoid(x)


# Init your model
# Attention!!! your num_output will be 1, because logistic function returns one value in range (0, 1) 
model = LogisticRegression(n_inputs=1, n_outputs=1)
# Define Binary Cross Entropy Loss:
criterion = nn.BCELoss()

# dummy data
data = (42.0, 0)
tensor_input = torch.Tensor([data[0]])
tensor_label = torch.Tensor([data[1]])

outputs = model(tensor_input)

loss = criterion(outputs, tensor_label)

print(loss.item())