Aivaro
  • Оглавление
  • Вопросы
  • Практика
  • Вики
  • Материалы сообщества
  • Тесты
  • Поиск
✈Telegram @ai_varo
RUEN中文
…
Оглавление/Вопросы/#945

Как работает 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-PERI-PEROB-ORGI-ORG
B-PER-0.52.01.5-1.0-2.0
I-PER-1.01.82.0-1.5-2.5
O2.0-2.01.02.0-2.0
B-ORG-1.5-2.01.5-0.52.0
I-ORG-2.0-2.52.0-1.01.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:

  1. Инициализация: для каждого токена i и метки j вычисляем viterbi[i][j] — максимальный score для последовательности, заканчивающейся на метку j на позиции i.
  2. Рекурсия: viterbi[i][j] = E_i(j) + max_k (viterbi[i-1][k] + T(k, j))
  3. Терминация: выбираем метку с максимальным viterbi[n][j].
  4. Обратный проход: восстанавливаем последовательность меток по сохранённым указателям 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

Шаги:

  1. Загрузка данных: скачать CoNLL-2003 или использовать datasets.load_dataset("conll2003").
  2. Предобработка: токенизация, создание словарей токенов и меток (BIO-разметка).
  3. Реализация BiLSTM: слой Embedding → BiLSTM → Linear (эмиссионные оценки).
  4. Реализация CRF: класс CRFLayer с матрицей переходов и функциями forward (вычисление loss) и decode (Viterbi).
  5. Обучение: оптимизатор Adam, loss = NLLLoss, валидация на dev-сете.
  6. Оценка: метрики precision/recall/F1 для каждой сущности.

Ожидаемый результат:

  • Модель достигает F1 > 90% на CoNLL-2003 (сравнимо с классическими подходами).
  • Визуализация матрицы переходов: высокие значения на диагонали (I → I) и на переходах B → I, низкие на O → I.
  • Пример предсказания: [B-PER, I-PER, O, B-ORG, I-ORG] для текста "Иван Петров работает в Яндексе".

Связь с другими вопросами

ВопросТема
903BiLSTM как базовый энкодер для NER
944Формат меток для последовательностной разметки
946Альтернатива BiLSTM с attention

Навигация

  • Предыдущий: 944
  • Следующий: 946
  • Индекс: 00. Индекс разборов