Почему выход BERT трансформатора (для классификации последовательностей) сильно зависит от заполнения максимальной длины последовательности?

#sentiment-analysis #bert-language-model #huggingface-transformers #huggingface-tokenizers

Вопрос:

Я использую Робберта Трансформера (голландскую версию Роберты) для классификации последовательностей, обученного анализу настроений в наборе данных голландских обзоров книг.

Я хотел проверить, насколько хорошо он работает с аналогичным набором данных (также с анализом настроений), поэтому я сделал аннотации для набора текстовых фрагментов и проверил его точность. Когда я проверил, какие предложения классифицированы неправильно, я заметил, что вывод уникального предложения сильно зависит от длины заполнения, которое я даю при маркировке. См. Код ниже.

 from transformers import RobertaTokenizer, RobertaForSequenceClassification
import torch.nn.functional as F
import torch


model = RobertaForSequenceClassification.from_pretrained("pdelobelle/robBERT-dutch-books", num_labels=2)
tokenizer = RobertaTokenizer.from_pretrained("pdelobelle/robBERT-dutch-books", do_lower_case=True)

sent = 'De samenwerking gaat de laatste tijd beter'
max_seq_len = 64


test_token = tokenizer(sent,
                        max_length = max_seq_len,
                        padding = 'max_length',
                        truncation = True,
                        return_tensors = 'pt'
                        )

out = model(test_token['input_ids'],test_token['attention_mask'])

probs = F.softmax(out[0], dim=1).detach().numpy()
 

Для данного примера текста, который переводится на английский как «Сотрудничество в последнее время улучшается», существует огромная разница в выводе по классификации в зависимости от max_seq_len. А именно, для max_seq_len = 64 вывода для probs is:

[[0.99149346 0.00850648]]

в то время как для max_seq_len = 9 , будучи фактической длиной, включая токены cls:

[[0.00494814 0.9950519 ]]

Может ли кто — нибудь объяснить, почему происходит такая огромная разница в классификации? Я бы подумал, что маска внимания гарантирует, что в выходных данных нет разницы из-за заполнения до максимальной длины последовательности.

Ответ №1:

Это вызвано тем, что ваше сравнение неверно. В предложении De samenwerking gaat de laatste tijd beter на самом деле 16 токенов ( 2 для специальных токенов), а не 9. Вы подсчитали только те слова, которые не обязательно являются жетонами.

 print(tokenizer.tokenize(sent))
print(len(tokenizer.tokenize(sent)))
 

Выход:

 ['De', 'Ġsam', 'en', 'wer', 'king', 'Ġga', 'at', 'Ġde', 'Ġla', 'at', 'ste', 'Ġt', 'ij', 'd', 'Ġbe', 'ter']
16
 

Когда вы устанавливаете длину последовательности равной 9, вы сокращаете предложение до:

 tokenizer.decode(tokenizer(sent,
                         max_length = 9,
                         padding = 'max_length',
                         truncation = True,
                         return_tensors = 'pt', 
                         add_special_tokens=False
                         )['input_ids'][0])
 

Выход:

 'De samenwerking gaat de la'
 

И в качестве окончательного доказательства, вывод, когда вы устанавливаете max_length значение 52, также [[0,99149346 0,00850648]].