nn.CrossEntropyLoss()的Pytorch输入
我试图在PyTorch中对一个简单的0,1标记数据集执行逻辑回归。标准或损失定义为:nn.CrossEntropyLoss()的Pytorch输入,pytorch,logistic-regression,Pytorch,Logistic Regression,我试图在PyTorch中对一个简单的0,1标记数据集执行逻辑回归。标准或损失定义为:criteria=nn.CrossEntropyLoss()。模型为:model=logistic回归(1,2) 我有一个成对的数据点:dat=(-3.5,0),第一个元素是数据点,第二个是相应的标签。 然后我将输入的第一个元素转换成张量:tensor\u input=torch.tensor([dat[0]]) 然后我将模型应用于张量输入:outputs=model(张量输入) 然后我将标签转换为张量:tens
criteria=nn.CrossEntropyLoss()
。模型为:model=logistic回归(1,2)
我有一个成对的数据点:dat=(-3.5,0)
,第一个元素是数据点,第二个是相应的标签。然后我将输入的第一个元素转换成张量:
tensor\u input=torch.tensor([dat[0]])
然后我将模型应用于张量输入:
outputs=model(张量输入)
然后我将标签转换为张量:
tensor\u label=torch.tensor([dat[1]])
现在,当我尝试这样做时,事情发生了变化:
loss=criteria(输出,张量标签)
。它给出和错误:RuntimeError:Dimension超出范围(预期在[-1,0]范围内,但得到1)
我一辈子都搞不懂它。在大多数情况下,PyTorch文档在解释不同功能方面做得非常出色;它们通常包括预期的输入维度,以及一些简单的示例。
您可以找到
nn.CrossEntropyLoss()
的说明
要浏览您的特定示例,让我们从查看预期的输入维度开始:
输入:(N,C),其中C=类数。[……]
此外,N通常指批量大小(样本数量)。要将其与您当前拥有的进行比较,请执行以下操作:
outputs.shape
>>> torch.Size([2])
也就是说,目前我们的输入维度只有(2,)
,而不是PyTorch预期的(1,2)
。我们可以通过在当前张量中添加一个“假”维度来缓解这种情况,只需使用.unsqueze()
如下:
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下使用PyTorch 1.0供参考。要在PyTorch中执行逻辑回归,您需要3件事:
- 编码为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())
请注意:您在示例代码中只定义了
模型
,但稍后将使用二进制模型
进行正向传递。可能只是打字错误,但我不知道你的代码。我部分不同意这个答案。因为这个问题是关于nn.CrossEntropyLoss()
,而不是nn.BCELoss()
,所以它稍微有点偏离,即使它正确地解决了逻辑回归的问题,正如您所提到的。此外,尽管,`nn.Sigmoid()将按元素应用,即输出与输入的形状相同;你必须确保只有一个因素会影响到你自己。
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())