Трансформаторы BertModel выводят строку вместо тензора

Я слежу за этим учебник, который кодирует классификатор анализа настроений с использованием BERT с библиотекой huggingface, и у меня очень странное поведение. При попытке использовать модель BERT с образцом текста я получаю строку вместо скрытого состояния. Это код, который я использую:

import transformers
from transformers import BertModel, BertTokenizer

print(transformers.__version__)

PRE_TRAINED_MODEL_NAME = 'bert-base-cased'
PATH_OF_CACHE = "/home/mwon/data-mwon/paperChega/src_classificador/data/hugingface"

tokenizer = BertTokenizer.from_pretrained(PRE_TRAINED_MODEL_NAME,cache_dir = PATH_OF_CACHE)

sample_txt = 'When was I last outside? I am stuck at home for 2 weeks.'

encoding_sample = tokenizer.encode_plus(
  sample_txt,
  max_length=32,
  add_special_tokens=True, # Add '[CLS]' and '[SEP]'
  return_token_type_ids=False,
  padding=True,
  truncation = True,
  return_attention_mask=True,
  return_tensors='pt',  # Return PyTorch tensors
)

bert_model = BertModel.from_pretrained(PRE_TRAINED_MODEL_NAME,cache_dir = PATH_OF_CACHE)


last_hidden_state, pooled_output = bert_model(
  encoding_sample['input_ids'],
  encoding_sample['attention_mask']
)

print([last_hidden_state,pooled_output])

что выводит:

4.0.0
['last_hidden_state', 'pooler_output']
 

person Miguel    schedule 03.12.2020    source источник


Ответы (2)


Хотя ответ от Aakash предлагает решение проблемы, он не объясняет проблему. Начиная с одного из выпусков библиотеки трансформаторов 3.X, модели больше не возвращают кортежи, а конкретные выходные объекты:

o = bert_model(
    encoding_sample['input_ids'],
    encoding_sample['attention_mask']
)
print(type(o))
print(o.keys())

Выход:

transformers.modeling_outputs.BaseModelOutputWithPoolingAndCrossAttentions
odict_keys(['last_hidden_state', 'pooler_output'])

Вы можете вернуться к предыдущему поведению, добавив return_dict=False, чтобы получить кортеж:

o = bert_model(
   encoding_sample['input_ids'],
   encoding_sample['attention_mask'],
   return_dict=False
)

print(type(o))

Выход:

<class 'tuple'>

Я не рекомендую этого делать, потому что теперь однозначно выбрать определенную часть вывода, не обращаясь к документации, как показано в примере ниже:

o = bert_model(encoding_sample['input_ids'],  encoding_sample['attention_mask'], return_dict=False, output_attentions=True, output_hidden_states=True)
print('I am a tuple with {} elements. You do not know what each element presents without checking the documentation'.format(len(o)))

o = bert_model(encoding_sample['input_ids'],  encoding_sample['attention_mask'], output_attentions=True, output_hidden_states=True)
print('I am a cool object and you can acces my elements with o.last_hidden_state, o["last_hidden_state"] or even o[0]. My keys are; {} '.format(o.keys()))

Выход:

I am a tuple with 4 elements. You do not know what each element presents without checking the documentation
I am a cool object and you can acces my elements with o.last_hidden_state,  o["last_hidden_state"] or even o[0]. My keys are; odict_keys(['last_hidden_state', 'pooler_output', 'hidden_states', 'attentions']) 
person cronoik    schedule 10.12.2020
comment
В самом деле, я рекомендую всегда использовать return_dict=True, чтобы выходные данные можно было однозначно извлечь из словаря, возвращаемого моделью. - person stackoverflowuser2010; 10.12.2020
comment
Как декодировать вывод bertmodel, чтобы получить предложение или строку? - person shaik moeed; 16.06.2021
comment
Вывод bert_model - это просто контекстуализированное представление вашего ввода, и предложение остается прежним. Вы можете просто выполнить tokenizer.decode(input_ids). Если у вас есть другой слой поверх койки, это другое дело. В этом случае, пожалуйста, задайте свой вопрос. @shaikmoeed - person cronoik; 17.06.2021

Я столкнулся с той же проблемой, когда учился внедрять Bert. Я заметил, что с помощью

last_hidden_state, pooled_output = bert_model(encoding_sample['input_ids'], encoding_sample['attention_mask'])

вот в чем проблема. Использовать:

outputs = bert_model(encoding_sample['input_ids'], encoding_sample['attention_mask'])

и извлеките состояние last_hidden, используя

output[0]

Вы можете обратиться к документации здесь, в которой рассказывается, что возвращает BertModel

person Aakash Bhatia    schedule 04.12.2020