Fonction torch.nn.CrossEntropyLoss de PyTorch

PyTorch torch.nn 参考手册Manuel de référence torch.nn de PyTorch


torch.nn.CrossEntropyLossest une fonction de perte utilisée pour la classification multiclasse dans PyTorch.

Elle combine nn.LogSoftmax et nn.NLLLoss, couramment utilisée dans des tâches telles que la classification d'images et la classification de texte.

Définition de fonction

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

Description des paramètres :

  • weight(Tensor) : attribue des poids différents à chaque classe, utilisé en cas de déséquilibre de classes.
  • ignore_index(int) : Ignore le calcul de la perte pour l'index spécifié. Valeur par défaut : -100.
  • reduction(str) : Méthode de réduction de la perte. Les options sont'mean'、'sum'、'none'. Valeur par défaut :'mean'。
  • label_smoothing(float) : Paramètre de lissage des étiquettes, compris entre 0 et 1. Valeur par défaut : 0.

Principe mathématique

La formule de la perte d'entropie croisée :

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

Autrement dit, plus la probabilité prédite de la classe correcte est grande, plus la perte est faible.


Exemples d'utilisation

Exemple 1 : Utilisation de base

Créer et utiliser la perte d'entropie croisée :

Exemple

import torch
import torch.nn as nn

# Créer une fonction de perte
criterion = nn.CrossEntropyLoss()

# Logits renvoyés par le modèle (non normalisés)
# Forme : (batch_size, num_classes)
outputs = torch.randn(4, 10)

# Étiquettes réelles
labels = torch.tensor([2, 5, 1, 7])

# Calculer la perte
loss = criterion(outputs, labels)

print("Sortie du modèle (logits) :", outputs[0].tolist())
print("Étiquettes réelles :", labels[0].item())
print("Perte d'entropie croisée :", loss.item())

Exemple 2 : Poids des classes

Gestion du déséquilibre de classes :

Exemple

import torch
import torch.nn as nn

# Poids des classes : donner un poids plus élevé aux classes minoritaires
# Supposons 10 classes, la classe 3 et la classe 7 sont plus importantes
weight = torch.ones(10)
graisse[3] = 2.0
graisse[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("Perte d'entropie croisée pondérée :", loss.item())

Exemple 3 : Lissage des étiquettes

Utilisez le lissage des étiquettes pour éviter le surapprentissage :

Exemple

import torch
import torch.nn as nn

# Lissage des étiquettes : 0.1 signifie répartir 10% de la probabilité uniformément vers les autres classes
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("Perte avec lissage des étiquettes :", loss.item())

# Comparaison : sans lissage des étiquettes
criterion = nn.CrossEntropyLoss()
loss_no_smooth = criterion(outputs, labels)
print("Perte sans lissage des étiquettes :", loss_no_smooth.item())

Exemple 4 : Pipeline complet d'entraînement de classification

Un exemple complet d'entraînement de modèle :

Exemple

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

# Modèle de classification 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)

# Initialiser le modèle et la perte
model = Classifier()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# Simuler les données d'entraînement
batch_size = 32
x = torch.randn(batch_size, 784)  # Entrée
y = torch.randint(0, 10, (batch_size,))  # Étiquettes

# Passe avant
model.train()
outputs = model(x)
loss = criterion(outputs, y)

# Rétropropagation
optimizer.zero_grad()
loss.backward()
optimizer.step()

print("Perte du lot :", loss.item())

# Prédiction
model.eval()
with torch.no_grad():
    outputs = model(x)
    predictions = outputs.argmax(dim=1)
    accuracy = (predictions == y).float().mean()

print("Précision des prédictions :", accuracy.item())

Exemple 5 : Utilisation de ignore_index

Ignorer des étiquettes spécifiques :

Exemple

import torch
import torch.nn as nn

# Ignorer les échantillons avec label=-100
criterion = nn.CrossEntropyLoss(ignore_index=-100)

outputs = torch.randn(5, 10)
# Certains échantillons ont label -100, ce qui signifie qu'ils sont ignorés
labels = torch.tensor([2, -100, 5, -100, 7])

loss = criterion(outputs, labels)
print("Perte après avoir ignoré les étiquettes spéciales :", loss.item())

Exemple 6 : Différents modes de réduction

Contrôler la méthode de réduction de la perte :

Exemple

import torch
import torch.nn as nn

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

# mean : renvoie la perte moyenne
loss_mean = nn.CrossEntropyLoss(reduction='mean')(outputs, labels)
print("mean:", loss_mean.item())

# sum : renvoie la somme totale
loss_sum = nn.CrossEntropyLoss(reduction='sum')(outputs, labels)
print("sum:", loss_sum.item())

# none : renvoie la perte pour chaque échantillon
loss_none = nn.CrossEntropyLoss(reduction='none')(outputs, labels)
print("none:", loss_none.tolist())

Questions fréquentes

Q1 : Quelle est la différence entre CrossEntropyLoss et NLLLoss ?

CrossEntropyLoss = LogSoftmax + NLLLoss. Il intègre déjà softmax, donc il n'est pas nécessaire de l'ajouter manuellement.

Q2 : Pourquoi la sortie du modèle n'utilise-t-elle pas softmax ?

CrossEntropyLoss calcule automatiquement softmax en interne, et l'utilisation directe des logits améliore la stabilité numérique.

Q3 : À quels scénarios le lissage des étiquettes est-il adapté ?

Le lissage des étiquettes convient aux situations comportant un grand nombre de classes, et il peut améliorer la capacité de généralisation du modèle.


Cas d'utilisation

nn.CrossEntropyLossLes principaux scénarios d'application incluent :

  • Classification d'images: comme CIFAR-10, ImageNet
  • Classification de texte: analyse de sentiments, classification de sujets
  • Tâches de classification multi-classes: toute tâche de classification avec plus de 2 classes

Remarque : les étiquettes doivent être des indices de classe (0 à num_classes-1), et non encodées en one-hot.


PyTorch torch.nn 参考手册Manuel de référence torch.nn de PyTorch

Autres extensions