У меня есть BertTokenizer
(tokenizer
) и BertModel
(model
) из библиотеки transformers
. Я предварительно обучил модель с нуля с помощью нескольких статей в Википедии, просто чтобы проверить, как она работает.
После предварительного обучения модели я хочу извлечь векторное представление слоя для данного предложения. Для этого я вычисляю среднее из 11 скрытых (размером 768) векторов. Я делаю это следующим образом (line
- это одиночный String
):
padded_sequence = tokenizer(line, padding=True)
indexed_tokens = padded_sequence['input_ids']
attention_mask = padded_sequence["attention_mask"]
tokens_tensor = torch.tensor([indexed_tokens])
attention_mask_tensor = torch.tensor([attention_mask])
outputs = model(tokens_tensor, attention_mask_tensor)
hidden_states = outputs[0]
line_vectorized = hidden_states[0].data.numpy().mean(axis=0)
Все идет нормально. Я могу сделать это для каждого предложения индивидуально. Но теперь я хочу делать это партиями, т.е. У меня есть несколько предложений, и вместо того, чтобы повторять каждое предложение, я отправляю соответствующие тензорные представления, чтобы получить все векторы сразу. Я делаю это следующим образом (lines
это list of Strings
):
padded_sequences = self.tokenizer_PYTORCH(lines, padding=True)
indexed_tokens_list = padded_sequences['input_ids']
attention_mask_list = padded_sequences["attention_mask"]
tokens_tensors_list = [torch.tensor([indexed_tokens]) for indexed_tokens in indexed_tokens_list]
attention_mask_tensors_list = [torch.tensor([attention_mask ]) for attention_mask in attention_mask_list ]
tokens_tensors = torch.cat((tokens_tensors_list), 0)
attention_mask_tensors = torch.cat((attention_mask_tensors_list ), 0)
outputs = model(tokens_tensors, attention_mask_tensors)
hidden_states = outputs[0]
lines_vectorized = [hidden_states[i].data.numpy().mean(axis=0) for i in range(0, len(hidden_states))]
Проблема заключается в следующем: Мне нужно использовать отступы, чтобы можно было соответствующим образом объединить тензоры токенов. Это означает, что индексированные токены и маски внимания могут быть больше, чем в предыдущем случае, когда предложения оценивались индивидуально. Но когда я использую заполнение, я получаю разные результаты для предложений, которые были заполнены.
ПРИМЕР: у меня есть два предложения (на французском, но это не имеет значения):
sentence_A
= appareil digestif - статья из Википедии, свободная энциклопедия
sentence_B
= sauter a la navigation sauter a la recherche cet article est une ebauche careant la biologie
Когда я оцениваю два предложения по отдельности, я получаю:
sentence_A
:
indexed_tokens = [10002, 3101, 4910, 557, 73, 3215, 9630, 2343, 4200, 8363, 10000]
attention_mask = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
line_vectorized = [-0.9304411 0.53798294 -1.6231083 ...]
sentence_B
:
indexed_tokens = [10002, 2217, 6496, 1387, 9876, 2217, 6496, 1387, 4441, 405, 73, 6451, 3, 2190, 5402, 1387, 2971, 10000]
attention_mask = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
line_vectorized = [-0.8077076 0.56028104 -1.5135447 ...]
Но когда я оцениваю два предложения в пакете, я получаю:
sentence_A
:
indexed_tokens = [10002, 3101, 4910, 557, 73, 3215, 9630, 2343, 4200, 8363, 10000, 10004, 10004, 10004, 10004, 10004, 10004, 10004]
attention_mask = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0]
line_vectorized = [-1.0473819 0.6090186 -1.727466 ...]
sentence_B
:
indexed_tokens = [10002, 2217, 6496, 1387, 9876, 2217, 6496, 1387, 4441, 405, 73, 6451, 3, 2190, 5402, 1387, 2971, 10000]
attention_mask = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
line_vectorized = [-0.8077076 0.56028104 -1.5135447 ...]
То есть поскольку sentence_B
больше, чем sentence_A
, sentence_A
был дополнен, а маска внимания также была дополнена нулями. Индексированные токены теперь содержат дополнительные токены (10004
, что я предполагаю empty
). Векторное представление sentence_B
НЕ изменилось. Но векторное представление sentence_A
ИЗМЕНИЛОСЬ.
Я хотел бы знать, работает ли это так, как задумано или нет (я полагаю, что нет). Думаю, я что-то делаю не так, но не могу понять, что именно.
Любые идеи?