Что такое Multilabel Classification (в отличие от Multiclass)? Какую функцию потерь использовать для multilabel?
Краткий тезис
Multilabel classification — задача, где каждый объект может одновременно принадлежать нескольким классам (меткам), в отличие от multiclass, где объект относится ровно к одному из N взаимоисключающих классов. Для multilabel стандартная функция потерь — Binary Cross Entropy (BCE), применяемая независимо к каждой метке, а не Categorical Cross Entropy, которая используется для multiclass. Порог принятия решений в multilabel часто требует калибровки, отличной от стандартного 0.5.
2. Multilabel: несколько бинарных меток
Multilabel classification — задача, где каждый образец может иметь произвольное количество меток из фиксированного набора (вплоть до всех или ни одной). Метки не являются взаимоисключающими.
Ключевые характеристики:
- Выходной слой: sigmoid (независимо для каждой метки, вероятность от 0 до 1)
- Функция потерь: Binary Cross Entropy (BCE), суммированная по всем меткам
- Примеры: тегирование изображений (кошка, собака, улица — одновременно), категоризация текста по жанрам, определение симптомов в медицинской диагностике
- Предсказание: пороговое решение (обычно 0.5) для каждой метки независимо
Математическая формулировка: Для M меток модель выводит вектор вероятностей p = [p₁, p₂, ..., pₘ], где каждая pⱼ ∈ [0,1] независима. Истинные метки — бинарный вектор y (0 или 1 для каждой метки). Функция потерь:
L = -Σⱼ [yⱼ * log(pⱼ) + (1 - yⱼ) * log(1 - pⱼ)]
Пример в NLP: Классификация отзыва на продукт — один отзыв может одновременно содержать метки «качество», «цена», «доставка» и «обслуживание».
Ключевое отличие от multiclass:
| Характеристика | Multiclass | Multilabel |
|---|---|---|
| Количество классов на объект | Ровно 1 | 0, 1 или несколько |
| Взаимоисключение | Да | Нет |
| Функция активации | Softmax | Sigmoid (поэлементно) |
| Функция потерь | CCE | BCE |
| Метод предсказания | Argmax | Порог (threshold) |
3. Функции потерь: Binary Cross Entropy (BCE) vs Categorical Cross Entropy
Binary Cross Entropy (BCE) для multilabel
BCE рассматривает каждую метку как независимую бинарную задачу. Это корректно, так как метки не конкурируют друг с другом.
Формула (для одной метки j):
BCEⱼ = -[yⱼ * log(σ(zⱼ)) + (1 - yⱼ) * log(1 - σ(zⱼ))]
где σ(zⱼ) — сигмоида от логита zⱼ.
Реализация в PyTorch:
import torch.nn as nn
# Вариант 1: BCEWithLogitsLoss (численно стабильнее)
criterion = nn.BCEWithLogitsLoss()
loss = criterion(logits, targets) # logits: [batch, num_labels], targets: [batch, num_labels]
# Вариант 2: Sigmoid + BCELoss
criterion = nn.BCELoss()
probs = torch.sigmoid(logits)
loss = criterion(probs, targets)
Реализация в TensorFlow/Keras:
import tensorflow as tf
# Для multilabel
model.compile(optimizer='adam',
loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
metrics=['accuracy'])
Categorical Cross Entropy (CCE) для multiclass
CCE предполагает, что только один класс может быть истинным. Если применить CCE к multilabel, модель будет штрафовать за одновременное предсказание нескольких меток, что некорректно.
Формула:
CCE = -Σᵢ yᵢ * log(pᵢ)
где pᵢ — softmax-вероятность класса i.
Почему CCE не подходит для multilabel:
- Softmax нормализует выходы так, что сумма вероятностей = 1, создавая ложную конкуренцию между метками
- Если истинных меток несколько, CCE будет пытаться «выбрать» одну, игнорируя остальные
- Градиенты будут распределяться неверно, ухудшая обучение
Альтернативы BCE для multilabel
-
Focal Loss — модификация BCE для работы с дисбалансом классов:
FL = -α * (1 - p)ᵞ * log(p) для положительных метокгде γ ≥ 0 фокусирует обучение на сложных примерах.
-
Asymmetric Loss (ASL) — адаптация Focal Loss для multilabel с разными весами для положительных и отрицательных меток.
-
Ranking-based losses (например, ListNet) — оптимизируют ранжирование меток, а не пороговую классификацию.
4. Порог принятия решений (0.5 vs оптимальный)
Стандартный порог 0.5
По умолчанию для multilabel используется порог 0.5: если sigmoid-вероятность ≥ 0.5, метка считается положительной. Однако это не всегда оптимально.
Проблемы порога 0.5:
- Дисбаланс классов: если метка встречается редко (например, 5% объектов), порог 0.5 может давать слишком много ложных срабатываний
- Разная стоимость ошибок: false positive и false negative могут иметь разную цену
- Калибровка модели: вероятности могут быть смещены (overconfident или underconfident)
Поиск оптимального порога
Оптимальный порог подбирается индивидуально для каждой метки или глобально на валидационной выборке.
Методы поиска порога:
-
По метрике F1 — максимизация F1-score на валидации:
from sklearn.metrics import f1_score import numpy as np def find_optimal_threshold(y_true, y_pred_probs): best_threshold = 0.5 best_f1 = 0 for threshold in np.arange(0.1, 0.9, 0.05): y_pred = (y_pred_probs >= threshold).astype(int) f1 = f1_score(y_true, y_pred, average='micro') if f1 > best_f1: best_f1 = f1 best_threshold = threshold return best_threshold, best_f1 -
По метрике Jaccard index (IoU) — для задач, где важна точность совпадения наборов меток.
-
Per-label thresholds — отдельный порог для каждой метки:
thresholds = {} for label in range(num_labels): best_th, _ = find_optimal_threshold(y_true[:, label], y_pred_probs[:, label]) thresholds[label] = best_th -
Threshold-moving с ROC-кривой — выбор точки на ROC-кривой, ближайшей к (0,1) или максимизирующей метрику.
Практические рекомендации
- Начинайте с порога 0.5, но обязательно калибруйте на валидации
- Для редких меток (менее 10% объектов) порог часто нужно снижать до 0.3-0.4
- Используйте Precision-Recall curve вместо ROC при сильном дисбалансе
- Рассмотрите label smoothing для улучшения калибровки вероятностей
5. Пет-проект для закрепления
Задача: Разработать классификатор тегов для новостных статей, где одна статья может иметь несколько тегов (например, «технологии», «бизнес», «наука»).
Инструменты:
- Python, PyTorch или TensorFlow
- Hugging Face Transformers (BERT или RuBERT)
- scikit-learn для метрик и поиска порога
- Датасет: LC-QuAD 2.0 или любой multilabel-датасет (например, Reuters-21578)
Шаги:
- Загрузите multilabel-датасет (например, Reuters с 90 категориями)
- Предобработайте тексты: токенизация, паддинг до фиксированной длины
- Загрузите предобученный BERT (bert-base-uncased) и замените head на линейный слой с num_labels нейронами
- Обучите модель с BCEWithLogitsLoss, используя AdamW
- На валидации подберите оптимальный порог (по F1-micro)
- Сравните метрики при пороге 0.5 и оптимальном пороге
- Визуализируйте confusion matrix для 5 самых частых меток
Ожидаемый результат:
- Модель с F1-micro > 0.85 на тестовой выборке
- График зависимости F1 от порога
- Вывод: оптимальный порог отличается от 0.5 (обычно ниже для редких меток)
Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 914 | Что такое Multiclass Classification и как работает softmax? |
| 916 | Как работает Hierarchical Classification для иерархических меток? |
Навигация
- Предыдущий: 914
- Следующий: 916
- Индекс: 00. Индекс разборов