我正在尝试在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)
我一生无法解决。
答案 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回归,您需要做三件事:
这里是最小的例子:
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())