Я пытаюсь разработать двоичный классификатор с помощью BertModel и Pytorch от Huggingface. Модуль классификатора выглядит примерно так:
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))
Я делаю .view()
s из-за исходного кода Huggingface для BertForSequenceClassification
здесь который использует точно такой же способ для вычисления потерь. Но я получаю такую ошибку:
/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)
Что-то не так с моими этикетками? или результат моей модели? Я действительно застрял здесь. В документации для BCELoss Pytorch говорится:
Входные данные: (N, *), где * означает любое количество дополнительных измерений
Цель: (N, *), та же форма, что и входные
Как мне сделать мои метки той же формы, что и выходная модель? Я чувствую, что мне не хватает чего-то огромного, но я не могу этого найти.