Función PyTorch torch.nn.CrossEntropyLoss

PyTorch torch.nn 参考手册Manual de referencia de PyTorch torch.nn


torch.nn.CrossEntropyLossEs la función de pérdida utilizada para clasificación multiclase en PyTorch.

Combina nn.LogSoftmax y nn.NLLLoss, y se usa comúnmente en tareas como clasificación de imágenes y clasificación de texto.

Definición de la función

torch.nn.CrossEntropyLoss(weight=None, ignore_index=-100, reduction='mean', label_smoothing=0.0)

Descripción de parámetros:

  • weight(Tensor): Asigna un peso diferente a cada clase, para casos de desequilibrio de clases.
  • ignore_index(int): Ignora el cálculo de pérdida del índice especificado. Por defecto es -100.
  • reduction(str): Modo de agregación de pérdida. Opcional'mean'、'sum'、'none'. Por defecto es'mean'。
  • label_smoothing(float): Parámetro de suavizado de etiquetas, con valores entre 0 y 1. Por defecto es 0.

Principio matemático

La fórmula de la pérdida de entropía cruzada:

Loss = -log(exp(y_true) / sum(exp(y_i)))

Es decir, cuanto mayor sea la probabilidad predicha para la clase correcta, menor será la pérdida.


Ejemplos de uso

Ejemplo 1: Uso básico

Crear y usar la pérdida de entropía cruzada:

Ejemplo

import torch
import torch.nn as nn

# Crear la función de pérdida
criterion = nn.CrossEntropyLoss()

# Logits de salida del modelo (sin normalizar)
# Forma: (batch_size, num_classes)
outputs = torch.randn(4, 10)

# Etiquetas reales
labels = torch.tensor([2, 5, 1, 7])

# Calcular la pérdida
loss = criterion(outputs, labels)

print("Salida del modelo (logits):", outputs[0].tolist())
print("Etiquetas reales:", labels[0].item())
print("Pérdida de entropía cruzada:", loss.item())

Ejemplo 2: Pesos de clase

Manejar el desequilibrio de clases:

Ejemplo

import torch
import torch.nn as nn

# Pesos de clase: dar mayor peso a las clases minoritarias
# Supongamos 10 clases, la clase 3 y la clase 7 son más importantes
weight = torch.ones(10)
weight[3] = 2.0
weight[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("Pérdida de entropía cruzada ponderada:", loss.item())

Ejemplo 3: Suavizado de etiquetas

Usar suavizado de etiquetas para prevenir el sobreajuste:

Ejemplo

import torch
import torch.nn as nn

# Suavizado de etiquetas: 0.1 significa distribuir uniformemente el 10% de la probabilidad a otras clases
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("Pérdida con suavizado de etiquetas:", loss.item())

# Comparación: sin suavizado de etiquetas
criterion = nn.CrossEntropyLoss()
loss_no_smooth = criterion(outputs, labels)
print("Pérdida sin suavizado de etiquetas:", loss_no_smooth.item())

Ejemplo 4: Flujo completo de entrenamiento de clasificación

Ejemplo completo de entrenamiento de modelo:

Ejemplo

import torch
import torch.nn as nn
import torch.optim as optim

# Modelo de clasificación simple
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)

# Inicializar el modelo y la pérdida
model = Classifier()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# Simular datos de entrenamiento
batch_size = 32
x = torch.randn(batch_size, 784)  # Entrada
y = torch.randint(0, 10, (batch_size,))  # Etiquetas

# Propagación hacia adelante
model.train()
outputs = model(x)
loss = criterion(outputs, y)

# Propagación hacia atrás
optimizer.zero_grad()
loss.backward()
optimizer.step()

print("Pérdida del lote:", loss.item())

# Predicción
model.eval()
with torch.no_grad():
    outputs = model(x)
    predictions = outputs.argmax(dim=1)
    accuracy = (predictions == y).float().mean()

print("Precisión de la predicción:", accuracy.item())

Ejemplo 5: Uso de ignore_index

Ignorar etiquetas específicas:

Ejemplo

import torch
import torch.nn as nn

# Ignorar las muestras con label=-100
criterion = nn.CrossEntropyLoss(ignore_index=-100)

outputs = torch.randn(5, 10)
# Las etiquetas de algunas muestras son -100, lo que indica que se ignoran
labels = torch.tensor([2, -100, 5, -100, 7])

loss = criterion(outputs, labels)
print("Pérdida después de ignorar etiquetas especiales:", loss.item())

Ejemplo 6: Diferentes modos de reduction

Controlar el modo de agregación de pérdida:

Ejemplo

import torch
import torch.nn as nn

outputs = torch.randn(4, 10)
labels = torch.tensor([2, 5, 1, 7])

# mean: devuelve la pérdida promedio
loss_mean = nn.CrossEntropyLoss(reduction='mean')(outputs, labels)
print("mean:", loss_mean.item())

# sum: devuelve la suma total
loss_sum = nn.CrossEntropyLoss(reduction='sum')(outputs, labels)
print("sum:", loss_sum.item())

# none: devuelve la pérdida de cada muestra
loss_none = nn.CrossEntropyLoss(reduction='none')(outputs, labels)
print("none:", loss_none.tolist())

Preguntas frecuentes

Q1: ¿Cuál es la diferencia entre CrossEntropyLoss y NLLLoss?

CrossEntropyLoss = LogSoftmax + NLLLoss. Ya tiene softmax incorporado, no es necesario agregarlo manualmente.

Q2: ¿Por qué la salida del modelo no usa softmax?

CrossEntropyLoss calcula softmax automáticamente en su interior; usar logits directamente puede mejorar la estabilidad numérica.

Q3: ¿Para qué escenarios es adecuado el suavizado de etiquetas?

El suavizado de etiquetas es adecuado para casos con un gran número de clases y puede mejorar la capacidad de generalización del modelo.


Escenarios de uso

nn.CrossEntropyLossLos principales escenarios de aplicación incluyen:

  • Clasificación de imágenes: como CIFAR-10, ImageNet
  • Clasificación de texto: análisis de sentimientos, clasificación de temas
  • Tareas de clasificación multiclase: cualquier tarea de clasificación con más de 2 clases

Nota: las etiquetas deben ser índices de clase (0 a num_classes-1), no codificación one-hot.


PyTorch torch.nn 参考手册Manual de referencia de PyTorch torch.nn

Otras extensiones