PyTorch torch.nn.CrossEntropyLoss Funktion

PyTorch torch.nn 参考手册PyTorch torch.nn Referenzhandbuch


torch.nn.CrossEntropyLossist eine Verlustfunktion, die für die Multiklassenklassifikation in PyTorch verwendet wird.

Es kombiniert nn.LogSoftmax und nn.NLLLoss und wird häufig in Aufgaben wie Bildklassifikation und Textklassifikation verwendet.

Funktionsdefinition

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

Parameterbeschreibung:

  • weight(Tensor): Weist jeder Klasse unterschiedliche Gewichte zu, wird für Situationen mit Klassenungleichgewicht verwendet.
  • ignore_index(int): Ignoriert die Verlustberechnung für den angegebenen Index. Standardwert ist -100.
  • reduction(str): Methode zur Verlustreduktion. Optionen sind'mean'、'sum'、'none'. Standardwert ist'mean'。
  • label_smoothing(float): Label-Smoothing-Parameter, im Bereich von 0 bis 1. Standardwert ist 0.

Mathematisches Prinzip

Die Formel für den Cross-Entropy-Verlust:

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

Das heißt, je größer die vorhergesagte Wahrscheinlichkeit der korrekten Klasse, desto kleiner der Verlust.


Anwendungsbeispiele

Beispiel 1: Grundlegende Verwendung

Cross-Entropy-Verlust erstellen und verwenden:

Beispiel

import torch
import torch.nn as nn

# Verlustfunktion erstellen
criterion = nn.CrossEntropyLoss()

# Vom Modell ausgegebene Logits (unnormalisiert)
# Form: (batch_size, num_classes)
outputs = torch.randn(4, 10)

# Wahre Labels
labels = torch.tensor([2, 5, 1, 7])

# Verlust berechnen
loss = criterion(outputs, labels)

print("Modellausgabe (Logits):", outputs[0].tolist())
print("Wahre Labels:", labels[0].item())
print("Kreuzentropieverlust:", loss.item())

Beispiel 2: Klassengewichte

Umgang mit Klassenungleichgewicht:

Beispiel

import torch
import torch.nn as nn

# Klassengewichte: Minderheitsklassen höher gewichten
# Annahme: 10 Klassen, Klasse 3 und Klasse 7 sind wichtiger
weight = torch.ones(10)
Gewicht[3] = 2.0
Gewicht[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("Gewichteter Kreuzentropieverlust:", loss.item())

Beispiel 3: Label-Smoothing

Verwenden Sie Label-Smoothing, um Overfitting zu verhindern:

Beispiel

import torch
import torch.nn as nn

# Label-Smoothing: 0.1 bedeutet, 10% der Wahrscheinlichkeit gleichmäßig auf die anderen Klassen zu verteilen
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("Verlust mit Label-Smoothing:", loss.item())

# Vergleich: ohne Label-Smoothing
criterion = nn.CrossEntropyLoss()
loss_no_smooth = criterion(outputs, labels)
print("Verlust ohne Label-Smoothing:", loss_no_smooth.item())

Beispiel 4: Vollständige Klassifikations-Trainingspipeline

Ein vollständiges Beispiel für das Modelltraining:

Beispiel

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

# Einfaches Klassifikationsmodell
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)

# Modell und Verlust initialisieren
model = Classifier()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# Trainingsdaten simulieren
batch_size = 32
x = torch.randn(batch_size, 784)  # Eingabe
y = torch.randint(0, 10, (batch_size,))  # Beschriftungen

# Vorwärtsdurchlauf
model.train()
outputs = model(x)
loss = criterion(outputs, y)

# Rückwärtsdurchlauf
optimizer.zero_grad()
loss.backward()
optimizer.step()

print("Batch-Verlust:", loss.item())

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

print("Vorhersagegenauigkeit:", accuracy.item())

Beispiel 5: Verwendung von ignore_index

Spezifische Labels ignorieren:

Beispiel

import torch
import torch.nn as nn

# Samples mit label=-100 ignorieren
criterion = nn.CrossEntropyLoss(ignore_index=-100)

outputs = torch.randn(5, 10)
# Einige Samples haben label -100, was bedeutet, dass sie ignoriert werden
labels = torch.tensor([2, -100, 5, -100, 7])

loss = criterion(outputs, labels)
print("Verlust nach Ignorieren spezieller Labels:", loss.item())

Beispiel 6: Verschiedene Reduktionsmodi

Steuern Sie die Methode zur Verlustreduzierung:

Beispiel

import torch
import torch.nn as nn

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

# mean: gibt den durchschnittlichen Verlust zurück
loss_mean = nn.CrossEntropyLoss(reduction='mean')(outputs, labels)
print("mean:", loss_mean.item())

# sum: gibt die Gesamtsumme zurück
loss_sum = nn.CrossEntropyLoss(reduction='sum')(outputs, labels)
print("sum:", loss_sum.item())

# none: gibt den Verlust für jede Stichprobe zurück
loss_none = nn.CrossEntropyLoss(reduction='none')(outputs, labels)
print("none:", loss_none.tolist())

Häufig gestellte Fragen

F1: Was ist der Unterschied zwischen CrossEntropyLoss und NLLLoss?

CrossEntropyLoss = LogSoftmax + NLLLoss. Softmax ist bereits integriert, daher muss es nicht manuell hinzugefügt werden.

F2: Warum verwendet die Modellausgabe kein Softmax?

CrossEntropyLoss berechnet Softmax automatisch intern, und die direkte Verwendung von Logits verbessert die numerische Stabilität.

F3: Für welche Szenarien ist Label Smoothing geeignet?

Label Smoothing eignet sich für Situationen mit einer großen Anzahl von Klassen und kann die Generalisierungsfähigkeit des Modells verbessern.


Anwendungsfälle

nn.CrossEntropyLossDie wichtigsten Anwendungsszenarien umfassen:

  • Bildklassifikation: wie CIFAR-10, ImageNet
  • Textklassifikation: Sentimentanalyse, Themenklassifikation
  • Multiklassen-Klassifikationsaufgaben: jede Klassifikationsaufgabe mit mehr als 2 Klassen

Hinweis: Labels sollten Klassenindizes sein (0 bis num_classes-1), nicht one-hot-kodiert.


PyTorch torch.nn 参考手册PyTorch torch.nn Referenzhandbuch

Andere Erweiterungen