Функция PyTorch torch.nn.CrossEntropyLoss
Справочное руководство PyTorch torch.nn
torch.nn.CrossEntropyLossявляется функцией потерь, используемой для многоклассовой классификации в PyTorch.
Она объединяет nn.LogSoftmax и nn.NLLLoss, обычно используется в таких задачах, как классификация изображений и классификация текста.
Определение функции
torch.nn.CrossEntropyLoss(weight=None, ignore_index=-100, reduction='mean', label_smoothing=0.0)
Описание параметров:
weight(Tensor): назначает разные веса каждому классу, используется в ситуациях дисбаланса классов.ignore_index(int): Игнорирует вычисление потерь для указанного индекса. По умолчанию -100.reduction(str): Метод редукции потерь. Возможные варианты:'mean'、'sum'、'none'. По умолчанию —'mean'。label_smoothing(float): Параметр сглаживания меток в диапазоне от 0 до 1. По умолчанию 0.
Математический принцип
Формула кросс-энтропийной потери:
Loss = -log(exp(y_true) / sum(exp(y_i)))
То есть чем больше предсказанная вероятность правильного класса, тем меньше потеря.
Примеры использования
Пример 1: Базовое использование
Создание и использование кросс-энтропийной потери:
Пример
import torch.nn as nn
# Создание функции потерь
criterion = nn.CrossEntropyLoss()
# Логиты, выдаваемые моделью (ненормализованные)
# Форма: (batch_size, num_classes)
outputs = torch.randn(4, 10)
# Истинные метки
labels = torch.tensor([2, 5, 1, 7])
# Вычислить потери
loss = criterion(outputs, labels)
print("Выход модели (логиты):", outputs[0].tolist())
print("Истинные метки:", labels[0].item())
print("Кросс-энтропийная потеря:", loss.item())
Пример 2: Веса классов
Обработка дисбаланса классов:
Пример
import torch.nn as nn
# Веса классов: дать больший вес классам меньшинства
# Предположим, 10 классов, класс 3 и класс 7 более важны
weight = torch.ones(10)
насыщенность[3] = 2.0
насыщенность[7] = 2.0
criterion_weighted = nn.CrossEntropyLoss(weight=weight)
outputs = torch.randn(4, 10)
labels = torch.tensor([2, 3, 7, 5])
loss = criterion_weighted(outputs, labels)
print("Взвешенная кросс-энтропийная потеря:", loss.item())
Пример 3: Сглаживание меток
Используйте сглаживание меток, чтобы предотвратить переобучение:
Пример
import torch.nn as nn
# Сглаживание меток: 0.1 означает равномерное распределение 10% вероятности по другим классам
criterion_smooth = nn.CrossEntropyLoss(label_smoothing=0.1)
outputs = torch.randn(4, 10)
labels = torch.tensor([2, 5, 1, 7])
loss = criterion_smooth(outputs, labels)
print("Потери со сглаживанием меток:", loss.item())
# Сравнение: без сглаживания меток
criterion = nn.CrossEntropyLoss()
loss_no_smooth = criterion(outputs, labels)
print("Потери без сглаживания меток:", loss_no_smooth.item())
Пример 4: Полный конвейер обучения классификации
Полный пример обучения модели:
Пример
import torch.nn as nn
import torch.optim as optim
# Простая модель классификации
class Classifier(nn.Module):
def __init__(self, input_dim=784, num_classes=10):
super(Classifier, self).__init__()
self.fc = nn.Sequential(
nn.Linear(input_dim, 256),
nn.ReLU(),
nn.Dropout(0.5),
nn.Linear(256, num_classes)
)
def forward(self, x):
return self.fc(x)
# Инициализация модели и функции потерь
model = Classifier()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# Имитация обучающих данных
batch_size = 32
x = torch.randn(batch_size, 784) # Ввод
y = torch.randint(0, 10, (batch_size,)) # Метки
# Прямой проход
model.train()
outputs = model(x)
loss = criterion(outputs, y)
# Обратный проход
optimizer.zero_grad()
loss.backward()
optimizer.step()
print("Потери пакета:", loss.item())
# Предсказание
model.eval()
with torch.no_grad():
outputs = model(x)
predictions = outputs.argmax(dim=1)
accuracy = (predictions == y).float().mean()
print("Точность предсказания:", accuracy.item())
Пример 5: Использование ignore_index
Игнорировать определенные метки:
Пример
import torch.nn as nn
# Игнорировать образцы с меткой=-100
criterion = nn.CrossEntropyLoss(ignore_index=-100)
outputs = torch.randn(5, 10)
# Некоторые образцы имеют метку -100, что означает, что они игнорируются
labels = torch.tensor([2, -100, 5, -100, 7])
loss = criterion(outputs, labels)
print("Потери после игнорирования специальных меток:", loss.item())
Пример 6: Различные режимы сокращения
Управление методом сокращения потерь:
Пример
import torch.nn as nn
outputs = torch.randn(4, 10)
labels = torch.tensor([2, 5, 1, 7])
# mean: возвращает средние потери
loss_mean = nn.CrossEntropyLoss(reduction='mean')(outputs, labels)
print("mean:", loss_mean.item())
# sum: возвращает общую сумму
loss_sum = nn.CrossEntropyLoss(reduction='sum')(outputs, labels)
print("sum:", loss_sum.item())
# none: возвращает потерю для каждого примера
loss_none = nn.CrossEntropyLoss(reduction='none')(outputs, labels)
print("none:", loss_none.tolist())
Часто задаваемые вопросы
Вопрос 1: В чем разница между CrossEntropyLoss и NLLLoss?
CrossEntropyLoss = LogSoftmax + NLLLoss. CrossEntropyLoss уже включает в себя softmax, поэтому его не нужно добавлять вручную.
Вопрос 2: Почему для выхода модели не используется softmax?
CrossEntropyLoss автоматически вычисляет softmax внутри, а прямое использование логитов повышает численную устойчивость.
Вопрос 3: Для каких сценариев подходит сглаживание меток?
Сглаживание меток подходит для ситуаций с большим числом классов и может улучшить обобщающую способность модели.
Сценарии использования
nn.CrossEntropyLossОсновные сценарии применения включают:
- Классификация изображений: например, CIFAR-10, ImageNet
- Классификация текста: анализ тональности, классификация тем
- Задачи многоклассовой классификации: любая задача классификации с более чем 2 классами
Примечание: метки должны быть индексами классов (от 0 до num_classes-1), а не one-hot-кодированными.
Другие расширения