Функция PyTorch torch.nn.CrossEntropyLoss

PyTorch torch.nn 参考手册Справочное руководство 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
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
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
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
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
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
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-кодированными.


PyTorch torch.nn 参考手册Справочное руководство PyTorch torch.nn

Другие расширения