Множественные интервалы ответов в контексте, ответы на вопросы BERT - PullRequest
0 голосов
/ 25 мая 2020

Я пишу систему ответов на вопросы с использованием предварительно обученного BERT с линейным слоем и слоем softmax сверху. Следуя шаблонам, доступным на net, ярлыки одного примера обычно состоят только из одного answer_start_index и одного answer_end_index. Например, из Huggingface при создании экземпляра объекта SQUADFeatures:

```
self.input_ids = input_ids
self.attention_mask = attention_mask
self.token_type_ids = token_type_ids
self.cls_index = cls_index
self.p_mask = p_mask

self.example_index = example_index
self.unique_id = unique_id
self.paragraph_len = paragraph_len
self.token_is_max_context = token_is_max_context
self.tokens = tokens
self.token_to_orig_map = token_to_orig_map

self.start_position = start_position
self.end_position = end_position
self.is_impossible = is_impossible
self.qas_id = qas_id
```

Однако в моем собственном наборе данных у меня есть примеры, когда слово ответа находится в нескольких местах в контексте, т.е. несколько правильных интервалов, составляющих ответ.

Моя проблема в том, что я не знаю, как управлять такими примерами? В шаблонах, доступных в net, ярлыки обычно находятся в списке, например:

  • [start_example1, start_example2, start_example3]
  • [end_example1, end_example2, end_example3]

В моем случае это может выглядеть так:

  • [start_example1, [start_example2_1, start_example2_2], start_example3]
  • и то же самое для концов, конечно

Другими словами, у меня нет списка, содержащего одну метку для каждого примера, но список, содержащий либо одиночные метки, либо список «меток», например, то есть список, состоящий из списков.

Следуя другим шаблонам, следующим шагом в процессе будет:

```
input_ids = torch.cat(input_ids, dim=0)
attention_masks = torch.cat(attention_masks, dim=0)
token_type_ids = torch.cat(token_type_ids, dim=0)
span_starts = torch(span_starts) #Something like this
span_ends = torch(span_ends) #Something like this
```

Однако это, конечно (?) Вызывает ошибку, поскольку мои списки span_start и span_end не содержат только одно- элементы, но иногда и список в списке.

Кто-нибудь знает, как я могу решить эту проблему? Должен ли я использовать только примеры, в которых есть только один диапазон, составляющий ответ, присутствующий в контексте?

Если я работаю над ошибкой torch, будет ли работать обратное распространение / оценка / вычисление потерь?

Спасибо! / В

1 Ответ

0 голосов
/ 28 мая 2020

Вы проверили код?

from transformers import BertTokenizer, BertForQuestionAnswering
import torch

tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertForQuestionAnswering.from_pretrained('bert-large-uncased-whole-word-masking-finetuned-squad')

question, text = "Who was Jim Henson?", "Jim Henson was a nice puppet"
encoding = tokenizer.encode_plus(question, text)
input_ids, token_type_ids = encoding["input_ids"], encoding["token_type_ids"]
start_scores, end_scores = model(torch.tensor([input_ids]), token_type_ids=torch.tensor([token_type_ids]))

all_tokens = tokenizer.convert_ids_to_tokens(input_ids)
answer = ' '.join(all_tokens[torch.argmax(start_scores) : torch.argmax(end_scores)+1])

assert answer == "a nice puppet"

Я не уверен, что это лучший способ, но вы можете проверить вместо argmax использовать topk, и проверить, соответствует ли это правильному ответу .

t = torch.LongTensor([0,1,2,3,4,5,6,7,8,9])
t
_, indices = t.topk(4)
indices#([9, 8, 7, 6])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...