Что такое перекрестная энтропия?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое перекрестная энтропия?
Перекрестная энтропия (Cross-Entropy Loss) — это функция потерь, которая измеряет различие между предсказанным распределением вероятностей и истинным распределением. Это одна из самых популярных функций потерь в классификации и глубоком обучении.
Математическое определение
Для бинарной классификации:
L = -[y * log(p) + (1-y) * log(1-p)]
где:
- y = 0 или 1 (истинный класс)
- p = вероятность класса 1 (предсказание модели)
Для многоклассовой классификации:
L = -Σ(y_i * log(p_i))
где:
- y_i = 1 если это истинный класс, иначе 0 (one-hot кодирование)
- p_i = предсказанная вероятность класса i
Практические примеры
Пример 1: Бинарная классификация
import numpy as np
from sklearn.metrics import log_loss
# Истинные метки: [0, 1, 1, 0]
y_true = np.array([0, 1, 1, 0])
# Предсказанные вероятности
y_pred = np.array([0.1, 0.9, 0.8, 0.2])
# Расчёт cross-entropy
loss = log_loss(y_true, y_pred)
print(f"Cross-Entropy Loss: {loss}")
# Ручной расчёт:
loss_manual = -(np.sum(y_true * np.log(y_pred) + (1 - y_true) * np.log(1 - y_pred))) / len(y_true)
print(f"Ручной расчёт: {loss_manual}")
Пример 2: Многоклассовая классификация
import torch
import torch.nn as nn
# 3 класса, batch размер = 2
y_true = torch.LongTensor([0, 2]) # [класс 0, класс 2]
# Логиты (сырые выходы модели)
logits = torch.tensor([
[2.0, 1.0, 0.1], # образец 1
[0.1, 0.1, 2.5] # образец 2
])
# CrossEntropyLoss автоматически применяет softmax
criterion = nn.CrossEntropyLoss()
loss = criterion(logits, y_true)
print(f"Cross-Entropy Loss: {loss}")
Интерпретация значений
- loss = 0 — идеальное предсказание (вероятность истинного класса = 1.0)
- loss = 0.69 — случайный выбор (вероятность = 0.5 в бинарной классификации)
- loss → ∞ — уверенное неправильное предсказание (p = 0.001 вместо 1.0)
import numpy as np
# Идеальное предсказание
print(-np.log(1.0)) # 0.0
# Умеренно уверенное правильное предсказание
print(-np.log(0.9)) # 0.105
# Неправильное предсказание
print(-np.log(0.1)) # 2.303
# Очень неправильное предсказание
print(-np.log(0.001)) # 6.908
Почему перекрестная энтропия работает хорошо?
1. Чувствительность к ошибкам
Перекрестная энтропия сильно штрафует уверенные неправильные предсказания:
import matplotlib.pyplot as plt
import numpy as np
y_true = 1
y_pred_range = np.linspace(0.01, 0.99, 100)
loss = -y_true * np.log(y_pred_range)
plt.plot(y_pred_range, loss)
plt.xlabel('Предсказанная вероятность')
plt.ylabel('Cross-Entropy Loss')
plt.title('Штраф за неправильные предсказания растёт экспоненциально')
plt.show()
2. Математические свойства
- Гладкая функция (подходит для градиентного спуска)
- Производная простая и численно стабильна
- Связана с информационной теорией (KL-дивергенция)
3. Эффективность обучения
Производная перекрестной энтропии по логитам простая:
∂L/∂logits = softmax(logits) - y_true
Это даёт прямую сигнал для обновления весов.
Варианты перекрестной энтропии
1. Binary Cross-Entropy (бинарная классификация)
import torch.nn as nn
criterion = nn.BCELoss() # Для вероятностей [0, 1]
criterion = nn.BCEWithLogitsLoss() # Для логитов (рекомендуется)
2. Categorical Cross-Entropy (многоклассовая)
criterion = nn.CrossEntropyLoss() # Включает softmax
3. С взвешиванием классов
Для несбалансированных данных:
class_weights = torch.tensor([1.0, 2.5, 1.8])
criterion = nn.CrossEntropyLoss(weight=class_weights)
Связь с другими метриками
Cross-Entropy vs KL-дивергенция:
CE(y_true, y_pred) = H(y_true) + KL(y_true || y_pred)
где H — энтропия истинного распределения.
Cross-Entropy vs Log Loss:
Это одно и то же для классификации (часто используются взаимозаменяемо).
Практический пример: полный pipeline
import torch
import torch.nn as nn
from torch.optim import Adam
# Модель
model = nn.Sequential(
nn.Linear(10, 32),
nn.ReLU(),
nn.Linear(32, 3) # 3 класса
)
# Функция потерь
criterion = nn.CrossEntropyLoss()
optimizer = Adam(model.parameters())
# Обучение
X = torch.randn(100, 10)
y = torch.randint(0, 3, (100,)) # Метки классов
for epoch in range(10):
logits = model(X)
loss = criterion(logits, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
print(f"Epoch {epoch}, Loss: {loss.item():.4f}")
# Предсказание
with torch.no_grad():
logits = model(X[:5])
probs = torch.softmax(logits, dim=1)
predictions = torch.argmax(probs, dim=1)
Когда использовать
- Классификация (бинарная и многоклассовая) — основной выбор
- Многолабельная классификация — используй Binary Cross-Entropy для каждого класса
- Регрессия — не подходит, используй MSE или MAE
Важные замечания
- Численная стабильность — используй CrossEntropyLoss вместо BCELoss + Sigmoid (BCEWithLogitsLoss включает Sigmoid)
- Логиты vs вероятности — проверь, требует ли функция потерь логиты или вероятности
- Класс-дисбаланс — используй параметр
weightдля корректировки
Перекрестная энтропия — это фундаментальная метрика в машинном обучении, позволяющая эффективно обучать классификационные модели путём прямого сравнения с истинным распределением.