Python Pytorch交叉熵输入维
我正试图用Huggingface的BertModel和Pytorch开发一个二元分类器。 分类器模块如下所示:Python Pytorch交叉熵输入维,python,pytorch,python-3.7,cross-entropy,huggingface-transformers,Python,Pytorch,Python 3.7,Cross Entropy,Huggingface Transformers,我正试图用Huggingface的BertModel和Pytorch开发一个二元分类器。 分类器模块如下所示: class SSTClassifierModel(nn.Module): def __init__(self, num_classes = 2, hidden_size = 768): super(SSTClassifierModel, self).__init__() self.number_of_classes = num_classes self.d
class SSTClassifierModel(nn.Module):
def __init__(self, num_classes = 2, hidden_size = 768):
super(SSTClassifierModel, self).__init__()
self.number_of_classes = num_classes
self.dropout = nn.Dropout(0.01)
self.hidden_size = hidden_size
self.bert = BertModel.from_pretrained('bert-base-uncased')
self.classifier = nn.Linear(hidden_size, num_classes)
def forward(self, input_ids, att_masks,token_type_ids, labels):
_, embedding = self.bert(input_ids, token_type_ids, att_masks)
output = self.classifier(self.dropout(embedding))
return output
我培训模型的方式如下:
loss_function = BCELoss()
model.train()
for epoch in range(NO_OF_EPOCHS):
for step, batch in enumerate(train_dataloader):
input_ids = batch[0].to(device)
input_mask = batch[1].to(device)
token_type_ids = batch[2].to(device)
labels = batch[3].to(device)
# assuming batch size = 3, labels is something like:
# tensor([[0],[1],[1]])
model.zero_grad()
model_output = model(input_ids,
input_mask,
token_type_ids,
labels)
# model output is something like: (with batch size = 3)
# tensor([[ 0.3566, -0.0333],
#[ 0.1154, 0.2842],
#[-0.0016, 0.3767]], grad_fn=<AddmmBackward>)
loss = loss_function(model_output.view(-1,2) , labels.view(-1))
我的标签有问题吗?还是我的模型的输出?我真的被困在这里了。Pytorch的BCELoss文档中说:
输入:(N,∗) 哪里∗ 表示任意数量的附加尺寸目标:(N,∗), 与输入相同的形状 我应该如何使标签的形状与模型输出的形状相同?我觉得我遗漏了一些巨大的东西,但我找不到它。很少观察到:
- 您引用的代码使用的是
,但您使用的是CrossEntropyLoss
BCELoss
采用预测逻辑(大小:(N,D))和目标标签(大小:(N,)),而CrossEntropyLoss
采用p(y=1 | x)(大小:(N,))和目标标签(大小:(N,))作为p(y=0 | x),可以从p(y=1 | x)计算得出BCELoss
需要logits,即CrossEntropyLoss
需要概率值BCELoss
loss=loss\u函数(model\u output.view(-1,2)[:,1],labels.view(-1))
上面我假设第二个值是p(y=1 | x)
一种更简洁的方法是使模型只输出一个值,即p(y=1 | x),并将其传递给损失函数。从代码中可以看出,您传递的是logit值,而不是概率值,因此您可能还需要计算sigmoid(model|u输出)
如果您想使用BCELoss
或者您可以使用BCEWithLogitsLoss
另一种选择是将丢失更改为交叉熵无
,这也应该适用,因为它也适用于二进制标签。很少观察到:
- 您引用的代码使用的是
,但您使用的是CrossEntropyLoss
BCELoss
采用预测逻辑(大小:(N,D))和目标标签(大小:(N,)),而CrossEntropyLoss
采用p(y=1 | x)(大小:(N,))和目标标签(大小:(N,))作为p(y=0 | x),可以从p(y=1 | x)计算得出BCELoss
需要logits,即CrossEntropyLoss
需要概率值BCELoss
loss=loss\u函数(model\u output.view(-1,2)[:,1],labels.view(-1))
上面我假设第二个值是p(y=1 | x)
一种更简洁的方法是使模型只输出一个值,即p(y=1 | x),并将其传递给损失函数。从代码中可以看出,您传递的是logit值,而不是概率值,因此您可能还需要计算sigmoid(model|u输出)
如果您想使用BCELoss
或者您可以使用BCEWithLogitsLoss
另一种选择是将丢失更改为
CrossEntropyLoss
,这应该也适用,因为它也适用于二进制标签。噢!谢谢。两者都解决了我的问题。除了我的模型的输出不是p(y=1 | x)和p(y=0 | x)我应该使用softmax!是的,对不起,我意识到有点晚了。我更新了答案以反映所有三种情况——使用CE、BCE和BCElogits lossOh!谢谢。这两种方法都解决了我的问题。除了我模型的输出不是p(y=1 | x)和p(y=0 | x)我应该使用softmax!是的,对不起,我意识到有点晚了。我更新了答案以反映所有三种情况——使用CE、BCE和BCElogits丢失
/usr/local/lib/python3.6/dist-packages/torch/nn/functional.py in binary_cross_entropy(input, target, weight, size_average, reduce, reduction)
2068 if input.numel() != target.numel():
2069 raise ValueError("Target and input must have the same number of elements. target nelement ({}) "
-> 2070 "!= input nelement ({})".format(target.numel(), input.numel()))
2071
2072 if weight is not None:
ValueError: Target and input must have the same number of elements. target nelement (3) != input nelement (6)