← Назад к вопросам

Что такое перекрестная энтропия?

1.8 Middle🔥 181 комментариев
#Глубокое обучение#Машинное обучение

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое перекрестная энтропия?

Перекрестная энтропия (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

Важные замечания

  1. Численная стабильность — используй CrossEntropyLoss вместо BCELoss + Sigmoid (BCEWithLogitsLoss включает Sigmoid)
  2. Логиты vs вероятности — проверь, требует ли функция потерь логиты или вероятности
  3. Класс-дисбаланс — используй параметр weight для корректировки

Перекрестная энтропия — это фундаментальная метрика в машинном обучении, позволяющая эффективно обучать классификационные модели путём прямого сравнения с истинным распределением.