Как BERT представляет выходные данные
Что проверяют
Понимаете ли вы, что именно лежит на выходе энкодера и какой кусок брать под конкретную задачу. Следом почти всегда спрашивают, как получить эмбеддинг предложения и почему «сырой» [CLS] для поиска похожих текстов работает плохо.
Как отвечать
Начните с входа: текст режется токенизатором WordPiece (у оригинальных английских моделей словарь около 30 тысяч подслов), в начало ставится [CLS], между сегментами и в конце [SEP], максимум 512 токенов. Дальше перечислите, что возвращает модель, на примере BertModel из Hugging Face transformers:
last_hidden_state: тензор(batch, seq_len, hidden), по вектору на каждый токен с учётом контекста с обеих сторон.hiddenравен 768 у base и 1024 у large;pooler_output: вектор[CLS]после линейного слоя иtanh, размер(batch, hidden). Этот слой обучался на задаче предсказания следующего предложения, поэтому как универсальный эмбеддинг он слабый;hidden_states: приoutput_hidden_states=Trueкортеж из выхода слоя эмбеддингов и всех 12 (или 24) слоёв энкодера. Иногда признаки берут конкатенацией последних четырёх;attentions: приoutput_attentions=Trueвеса внимания(batch, heads, seq_len, seq_len)для каждого слоя.
Под задачу: классификация текста берёт [CLS] и дообучает поверх голову (BertForSequenceClassification), разметка токенов вроде NER использует вектор каждого токена, QA предсказывает начало и конец ответа по двум логитам на токен. Для эмбеддинга предложения без дообучения лучше среднее по токенам с учётом attention_mask, а ещё лучше модели семейства Sentence-BERT.
Где спотыкаются
Путают last_hidden_state и pooler_output или считают, что BERT выдаёт один вектор на текст.
Усредняют векторы без маски внимания, и паддинги тянут эмбеддинги коротких текстов к одному и тому же шуму.
Забывают про подслова: слово «переобучение» может превратиться в несколько токенов, поэтому число выходных векторов не совпадает с числом слов, и для NER метки нужно выравнивать, обычно по первому подслову.