Как работает CRF (Conditional Random Field) сверху BiLSTM для NER? Зачем нужен слой CRF?
Краткий тезис
CRF (Conditional Random Field) — это вероятностная модель, которая накладывается поверх BiLSTM для решения задачи NER (распознавание именованных сущностей). BiLSTM генерирует скрытые состояния для каждого токена, но не учитывает зависимости между соседними метками. CRF добавляет матрицу переходов между метками, что позволяет моделировать последовательность тегов (например, запрет на переход I-ORG после O). Декодирование выполняется алгоритмом Viterbi, который находит наиболее вероятную последовательность меток с учётом глобальных ограничений.
----|-------|-------|---|-------|-------| | Иван | 0.8 | 0.1 | 0.05| 0.03 | 0.02 | | Петров| 0.1 | 0.7 | 0.1 | 0.05 | 0.05 | | работает | 0.02 | 0.01 | 0.9 | 0.04 | 0.03 | | в | 0.01 | 0.01 | 0.85| 0.1 | 0.03 | | Яндексе | 0.01 | 0.01 | 0.05| 0.1 | 0.83 |
Softmax даёт: B-PER, I-PER, O, O, I-ORG — корректно. Но если модель ошибается, она может выдать B-PER, O, I-PER — что недопустимо.
2. CRF: моделирует переходы между метками (I-ORG не может идти после O)
CRF (Conditional Random Field) — это вероятностная модель, которая вычисляет условную вероятность последовательности меток y = (y_1, ..., y_n) при заданной последовательности скрытых состояний h = (h_1, ..., h_n):
P(y | h) = exp(score(y, h)) / Z(h)
где score(y, h) — сумма двух компонентов:
- Эмиссионные оценки (emission scores):
E_i(y_i) = W_y_i * h_i + b_y_i— насколько токенiсоответствует меткеy_i. - Переходные оценки (transition scores):
T(y_i, y_{i+1})— насколько вероятен переход от меткиy_iкy_{i+1}.
Матрица переходов — это обучаемый параметр размером (num_labels, num_labels). Она кодирует правила:
T(O → I-ORG)— низкая (запрещено, так как сущность не может начаться сI-)T(B-ORG → I-ORG)— высокая (разрешено)T(I-ORG → I-ORG)— высокая (продолжение сущности)T(I-ORG → O)— высокая (конец сущности)
Пример матрицы переходов (фрагмент):
| От \ К | B-PER | I-PER | O | B-ORG | I-ORG |
|---|---|---|---|---|---|
| B-PER | -0.5 | 2.0 | 1.5 | -1.0 | -2.0 |
| I-PER | -1.0 | 1.8 | 2.0 | -1.5 | -2.5 |
| O | 2.0 | -2.0 | 1.0 | 2.0 | -2.0 |
| B-ORG | -1.5 | -2.0 | 1.5 | -0.5 | 2.0 |
| I-ORG | -2.0 | -2.5 | 2.0 | -1.0 | 1.8 |
Здесь T(O → I-ORG) = -2.0 — сильно отрицательное, что делает такой переход маловероятным.
3. Учёт последовательности
CRF учитывает глобальную структуру последовательности через функцию потерь (loss function). Во время обучения минимизируется отрицательное логарифмическое правдоподобие:
Loss = -log P(y_true | h) = -score(y_true, h) + log Z(h)
где Z(h) — сумма по всем возможным последовательностям меток (нормализующая константа). Вычисление Z(h) требует динамического программирования (Forward-Backward algorithm), так как полный перебор экспоненциален.
Преимущества учёта последовательности:
- Глобальная оптимизация: модель штрафуется за недопустимые переходы (например,
O → I-ORG). - Контекстная согласованность: метки внутри одной сущности (B-ORG, I-ORG, I-ORG) получают высокий score, а разрыв сущности (B-ORG, O, I-ORG) — низкий.
- Устойчивость к шуму: даже если эмиссионная оценка для токена слабая, CRF может исправить ошибку за счёт переходов.
Пример сравнения:
- Без CRF:
B-PER (0.6), O (0.4), I-PER (0.5)— softmax выбираетB-PER, O, I-PER(ошибка). - С CRF:
score = E(B-PER) + T(B-PER → O) + E(O) + T(O → I-PER) + E(I-PER). ЕслиT(B-PER → O)иT(O → I-PER)сильно отрицательны, модель выберетB-PER, I-PER, I-PERилиO, O, O.
4. Viterbi для декодирования
На этапе инференса (предсказания) нужно найти наиболее вероятную последовательность меток:
y* = argmax_y P(y | h) = argmax_y score(y, h)
Прямой перебор всех num_labels^n последовательностей невозможен. Используется алгоритм Viterbi — динамическое программирование с временной сложностью O(n * num_labels^2).
Алгоритм Viterbi:
- Инициализация: для каждого токена
iи меткиjвычисляемviterbi[i][j]— максимальный score для последовательности, заканчивающейся на меткуjна позицииi. - Рекурсия:
viterbi[i][j] = E_i(j) + max_k (viterbi[i-1][k] + T(k, j)) - Терминация: выбираем метку с максимальным
viterbi[n][j]. - Обратный проход: восстанавливаем последовательность меток по сохранённым указателям
backpointer[i][j].
Пример работы Viterbi:
- Токены:
[Иван, Петров, работает, в, Яндексе] - Эмиссионные оценки (из BiLSTM): для каждого токена вектор длины 5 (B-PER, I-PER, O, B-ORG, I-ORG).
- Матрица переходов: как в разделе 2.
- Viterbi находит:
B-PER → I-PER → O → B-ORG → I-ORGс максимальным суммарным score.
Код на Python (упрощённо):
def viterbi_decode(emission_scores, transition_matrix):
n, num_labels = emission_scores.shape
viterbi = np.zeros((n, num_labels))
backpointer = np.zeros((n, num_labels), dtype=int)
# Инициализация
viterbi[0] = emission_scores[0]
# Рекурсия
for i in range(1, n):
for j in range(num_labels):
scores = viterbi[i-1] + transition_matrix[:, j] + emission_scores[i, j]
viterbi[i, j] = np.max(scores)
backpointer[i, j] = np.argmax(scores)
# Терминация
best_path = [np.argmax(viterbi[-1])]
for i in range(n-1, 0, -1):
best_path.insert(0, backpointer[i, best_path[0]])
return best_path
5. Пет-проект для закрепления
Задача: Реализовать BiLSTM-CRF для NER на датасете CoNLL-2003 (английский) или на русском датасете (например, RuREBus).
Инструменты:
- Python 3.10+
- PyTorch или TensorFlow
- Hugging Face Transformers (для токенизации)
- SpaCy (для предобработки)
- NumPy, Pandas
Шаги:
- Загрузка данных: скачать CoNLL-2003 или использовать datasets.load_dataset("conll2003").
- Предобработка: токенизация, создание словарей токенов и меток (BIO-разметка).
- Реализация BiLSTM: слой Embedding → BiLSTM → Linear (эмиссионные оценки).
- Реализация CRF: класс
CRFLayerс матрицей переходов и функциямиforward(вычисление loss) иdecode(Viterbi). - Обучение: оптимизатор Adam, loss = NLLLoss, валидация на dev-сете.
- Оценка: метрики precision/recall/F1 для каждой сущности.
Ожидаемый результат:
- Модель достигает F1 > 90% на CoNLL-2003 (сравнимо с классическими подходами).
- Визуализация матрицы переходов: высокие значения на диагонали (I → I) и на переходах B → I, низкие на O → I.
- Пример предсказания:
[B-PER, I-PER, O, B-ORG, I-ORG]для текста "Иван Петров работает в Яндексе".
Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 903 | BiLSTM как базовый энкодер для NER |
| 944 | Формат меток для последовательностной разметки |
| 946 | Альтернатива BiLSTM с attention |
Навигация
- Предыдущий: 944
- Следующий: 946
- Индекс: 00. Индекс разборов