BERT: контекстные эмбеддинги и двунаправленность
BERT решил ту самую проблему статичных эмбеддингов: теперь вектор слова зависит от предложения, а само предложение читается сразу в обе стороны.
BERT (Bidirectional Encoder Representations from Transformers) — модель на основе энкодера трансформера, которая строит контекстные эмбеддинги слов, учитывая контекст слева и справа одновременно.
Замыкаем круг: контекстные эмбеддинги
Помните проблему омонимов из раздела про эмбеддинги? Статичный word2vec давал «ключу» один вектор на все значения. BERT это чинит: он пропускает всё предложение через self-attention, и каждое слово получает контекстный вектор. «Ключ» в «повернул ключ в замке» и «ключ бьёт из земли» получат разные представления, потому что окружение разное. Это прямое решение проблемы, которую мы сформулировали ещё в разделе 4.
Двунаправленность: читаем в обе стороны
Слово «bidirectional» в названии — ключевое. RNN читала слева направо; чтобы понять слово, она видела только то, что было до него. BERT через self-attention видит всё предложение сразу — и левый, и правый контекст. Чтобы понять «банк» в «он сел на банк у реки», важно слово «реки» справа. Двунаправленность даёт это.
«он положил деньги в [банк]» -> правый контекст «деньги» => финансовый
«он сидел на [банк]е у реки» -> правый контекст «реки» => берег/скамья
BERT учитывает контекст с ОБЕИХ сторон слова одновременно
Как BERT обучают: маскирование
Главная хитрость предобучения BERT — masked language modeling. В предложении случайно прячут (маскируют) часть слов, и модель должна их угадать по контексту с обеих сторон. Чтобы заполнить пропуск, ей приходится по-настоящему понять предложение. Сымитируем саму задачу.
sentence = "кошка пьёт [MASK] из миски"
# по контексту слева и справа угадываем замаскированное слово
candidates = {"молоко": 0.82, "воду": 0.15, "камень": 0.01, "счастье": 0.02}
best = max(candidates, key=candidates.get)
print("Предложение:", sentence)
print("Кандидаты и вероятности:")
for word, p in sorted(candidates.items(), key=lambda x: -x[1]):
print(" %-8s %.2f" % (word, p))
print("BERT заполнил бы пропуск словом:", best)
Вывод:
Предложение: кошка пьёт [MASK] из миски Кандидаты и вероятности: молоко 0.82 воду 0.15 счастье 0.02 камень 0.01 BERT заполнил бы пропуск словом: молоко
Чтобы поставить «молоко», а не «камень», модель должна понимать, что кошки пьют и что в миске бывает жидкое. Решая миллионы таких задач на огромном корпусе, BERT выучивает глубокое представление языка — без всякой ручной разметки.
Энкодер, а не генератор
BERT использует только энкодерную часть трансформера. Он не порождает текст слово за словом — он понимает текст, выдавая богатые контекстные векторы. Поэтому BERT идеален для задач понимания: классификация, NER, поиск ответа в тексте, оценка похожести. Для генерации текста используют другую ветвь — GPT (следующий урок).
Как BERT применяют
- Дообучение (fine-tuning): берут предобученный BERT и доучивают на своей задаче (например, классификация отзывов) — нужно мало данных.
- Эмбеддинги предложений: вектор предложения для поиска и кластеризации.
- NER и извлечение информации: разметка сущностей в тексте.
Итог
- BERT даёт контекстные эмбеддинги: вектор слова зависит от предложения.
- Это решает проблему омонимов статичных эмбеддингов.
- Двунаправленность — учёт контекста слева и справа одновременно.
- Обучается маскированием слов (masked language modeling) без разметки.
- BERT — про понимание текста (энкодер), не про генерацию.