Training des Modells
Vorbereitung auf das Training
Zunächst müssen Modell, Verlustfunktion und Optimierer korrekt definiert werden. Gehen wir die einzelnen Schritte durch:
- Verlustfunktion: Für Klassifikationsaufgaben kann
CrossEntropyLossverwendet werden, die rohe kontinuierliche Werte (Logits) als Eingabe erwartet und automatischsoftmaxanwendet; - Optimierer: Der Adam-Optimierer kann für effiziente Gradientenaktualisierungen eingesetzt werden.
import torch.nn as nn
import torch.optim as optim
# Define the loss function (cross-entropy for multi-class classification)
criterion = nn.CrossEntropyLoss()
# Define the optimizer (Adam with a learning rate of 0.01)
optimizer = optim.Adam(model.parameters(), lr=0.01)
In PyTorch kombiniert die Kreuzentropie-Verlustfunktion log-softmax und negative log-likelihood (NLL) zu einer einzigen Verlustfunktion:
wobei:
- zy ist das Logit, das der korrekten Klasse entspricht;
- C ist die Gesamtanzahl der Klassen.
Es ist außerdem wichtig, die Daten in Trainings- und Validierungsdatensätze zu unterteilen (idealerweise sollte auch ein separater Testdatensatz existieren). Da der Datensatz relativ klein ist (1143 Zeilen), verwenden wir eine Aufteilung von 80% zu 20%. In diesem Fall dient der Validierungsdatensatz auch als Testdatensatz.
80% für das Training und 20% für das Testen sind in vielen Szenarien geeignet. Bei größeren Datensätzen, beispielsweise mit Millionen von Einträgen, kann auch ein kleinerer Prozentsatz für den Testdatensatz (10% oder weniger) ausreichen, um eine zuverlässige Leistungsbewertung zu erzielen. Umgekehrt ist es bei sehr kleinen Datensätzen (z. B. weniger als tausend Einträge) entscheidend, dass der Testdatensatz groß genug ist (25-30%), um eine aussagekräftige Bewertung der Modellleistung zu ermöglichen.
Außerdem sollten die resultierenden NumPy-Arrays in Tensoren umgewandelt werden, da PyTorch-Modelle Tensor-Eingaben für Berechnungen benötigen.
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
X_train = torch.tensor(X_train, dtype=torch.float32)
X_test = torch.tensor(X_test, dtype=torch.float32)
y_train = torch.tensor(y_train, dtype=torch.long)
y_test = torch.tensor(y_test, dtype=torch.long)
Trainingsschleife
Die Trainingsschleife umfasst die folgenden Schritte für jede Epoche:
- Forward Pass: Weiterleitung der Eingabemerkmale durch das Modell zur Generierung von Vorhersagen;
- Berechnung des Verlusts: Vergleich der Vorhersagen mit den tatsächlichen Werten mittels Verlustfunktion;
- Backward Pass: Berechnung der Gradienten bezüglich der Modellparameter mittels Backpropagation;
- Aktualisierung der Parameter: Anpassung der Modellparameter mit dem Optimierer;
- Überwachung des Fortschritts: Periodische Ausgabe des Verlusts zur Beobachtung der Konvergenz.
Wie ersichtlich, ähnelt der Trainingsprozess dem der linearen Regression.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849import torch.nn as nn import torch import torch.optim as optim import matplotlib.pyplot as plt import os os.system('wget https://staging-content-media-cdn.codefinity.com/courses/1dd2b0f6-6ec0-40e6-a570-ed0ac2209666/section_3/model_definition.py 2>/dev/null') from model_definition import model, X, y from sklearn.model_selection import train_test_split # Set manual seed for reproducibility torch.manual_seed(42) # Reinitialize model after setting seed model.apply(lambda m: m.reset_parameters() if hasattr(m, "reset_parameters") else None) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) X_train = torch.tensor(X_train, dtype=torch.float32) X_test = torch.tensor(X_test, dtype=torch.float32) y_train = torch.tensor(y_train, dtype=torch.long) y_test = torch.tensor(y_test, dtype=torch.long) # Define the loss function (Cross-Entropy for multi-class classification) criterion = nn.CrossEntropyLoss() # Define the optimizer (Adam with a learning rate of 0.01) optimizer = optim.Adam(model.parameters(), lr=0.01) # Number of epochs epochs = 100 # Store losses for plotting training_losses = [] # Training loop for epoch in range(epochs): # Zero out gradients from the previous step optimizer.zero_grad() # Compute predictions predictions = model(X_train) # Compute the loss loss = criterion(predictions, y_train) # Compute gradients loss.backward() # Update parameters optimizer.step() # Store the loss training_losses.append(loss.item()) # Plot the training loss plt.plot(range(epochs), training_losses, label="Training Loss") plt.xlabel("Epoch") plt.ylabel("Loss") plt.title("Training Loss over Epochs") plt.legend() plt.show()
Der Aufruf von model(input) ruft automatisch die Methode forward() des Modells auf. Dies liegt daran, dass nn.Module die Methode __call__ überschreibt, welche intern forward() aufruft. Es wird empfohlen, model(input) anstelle von model.forward(input) zu verwenden, da ersteres sicherstellt, dass alle Hooks oder zusätzlichen Funktionalitäten (z. B. model.train() oder model.eval()) korrekt angewendet werden.
Beobachtung der Konvergenz
Zusätzlich zum Training des Modells wird der Trainingsverlust in jeder Epoche aufgezeichnet und im Zeitverlauf dargestellt. Wie im Diagramm zu sehen ist, sinkt der Trainingsverlust zunächst rasch und stabilisiert sich dann allmählich um Epoche 60. Ab diesem Punkt nimmt der Verlust nur noch sehr langsam ab, was darauf hindeutet, dass das Modell wahrscheinlich konvergiert ist. Daher wären für dieses Modell etwa 40 Epochen ausreichend.
Danke für Ihr Feedback!
Fragen Sie AI
Fragen Sie AI
Fragen Sie alles oder probieren Sie eine der vorgeschlagenen Fragen, um unser Gespräch zu beginnen
Großartig!
Completion Rate verbessert auf 5
Training des Modells
Swipe um das Menü anzuzeigen
Vorbereitung auf das Training
Zunächst müssen Modell, Verlustfunktion und Optimierer korrekt definiert werden. Gehen wir die einzelnen Schritte durch:
- Verlustfunktion: Für Klassifikationsaufgaben kann
CrossEntropyLossverwendet werden, die rohe kontinuierliche Werte (Logits) als Eingabe erwartet und automatischsoftmaxanwendet; - Optimierer: Der Adam-Optimierer kann für effiziente Gradientenaktualisierungen eingesetzt werden.
import torch.nn as nn
import torch.optim as optim
# Define the loss function (cross-entropy for multi-class classification)
criterion = nn.CrossEntropyLoss()
# Define the optimizer (Adam with a learning rate of 0.01)
optimizer = optim.Adam(model.parameters(), lr=0.01)
In PyTorch kombiniert die Kreuzentropie-Verlustfunktion log-softmax und negative log-likelihood (NLL) zu einer einzigen Verlustfunktion:
wobei:
- zy ist das Logit, das der korrekten Klasse entspricht;
- C ist die Gesamtanzahl der Klassen.
Es ist außerdem wichtig, die Daten in Trainings- und Validierungsdatensätze zu unterteilen (idealerweise sollte auch ein separater Testdatensatz existieren). Da der Datensatz relativ klein ist (1143 Zeilen), verwenden wir eine Aufteilung von 80% zu 20%. In diesem Fall dient der Validierungsdatensatz auch als Testdatensatz.
80% für das Training und 20% für das Testen sind in vielen Szenarien geeignet. Bei größeren Datensätzen, beispielsweise mit Millionen von Einträgen, kann auch ein kleinerer Prozentsatz für den Testdatensatz (10% oder weniger) ausreichen, um eine zuverlässige Leistungsbewertung zu erzielen. Umgekehrt ist es bei sehr kleinen Datensätzen (z. B. weniger als tausend Einträge) entscheidend, dass der Testdatensatz groß genug ist (25-30%), um eine aussagekräftige Bewertung der Modellleistung zu ermöglichen.
Außerdem sollten die resultierenden NumPy-Arrays in Tensoren umgewandelt werden, da PyTorch-Modelle Tensor-Eingaben für Berechnungen benötigen.
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
X_train = torch.tensor(X_train, dtype=torch.float32)
X_test = torch.tensor(X_test, dtype=torch.float32)
y_train = torch.tensor(y_train, dtype=torch.long)
y_test = torch.tensor(y_test, dtype=torch.long)
Trainingsschleife
Die Trainingsschleife umfasst die folgenden Schritte für jede Epoche:
- Forward Pass: Weiterleitung der Eingabemerkmale durch das Modell zur Generierung von Vorhersagen;
- Berechnung des Verlusts: Vergleich der Vorhersagen mit den tatsächlichen Werten mittels Verlustfunktion;
- Backward Pass: Berechnung der Gradienten bezüglich der Modellparameter mittels Backpropagation;
- Aktualisierung der Parameter: Anpassung der Modellparameter mit dem Optimierer;
- Überwachung des Fortschritts: Periodische Ausgabe des Verlusts zur Beobachtung der Konvergenz.
Wie ersichtlich, ähnelt der Trainingsprozess dem der linearen Regression.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849import torch.nn as nn import torch import torch.optim as optim import matplotlib.pyplot as plt import os os.system('wget https://staging-content-media-cdn.codefinity.com/courses/1dd2b0f6-6ec0-40e6-a570-ed0ac2209666/section_3/model_definition.py 2>/dev/null') from model_definition import model, X, y from sklearn.model_selection import train_test_split # Set manual seed for reproducibility torch.manual_seed(42) # Reinitialize model after setting seed model.apply(lambda m: m.reset_parameters() if hasattr(m, "reset_parameters") else None) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) X_train = torch.tensor(X_train, dtype=torch.float32) X_test = torch.tensor(X_test, dtype=torch.float32) y_train = torch.tensor(y_train, dtype=torch.long) y_test = torch.tensor(y_test, dtype=torch.long) # Define the loss function (Cross-Entropy for multi-class classification) criterion = nn.CrossEntropyLoss() # Define the optimizer (Adam with a learning rate of 0.01) optimizer = optim.Adam(model.parameters(), lr=0.01) # Number of epochs epochs = 100 # Store losses for plotting training_losses = [] # Training loop for epoch in range(epochs): # Zero out gradients from the previous step optimizer.zero_grad() # Compute predictions predictions = model(X_train) # Compute the loss loss = criterion(predictions, y_train) # Compute gradients loss.backward() # Update parameters optimizer.step() # Store the loss training_losses.append(loss.item()) # Plot the training loss plt.plot(range(epochs), training_losses, label="Training Loss") plt.xlabel("Epoch") plt.ylabel("Loss") plt.title("Training Loss over Epochs") plt.legend() plt.show()
Der Aufruf von model(input) ruft automatisch die Methode forward() des Modells auf. Dies liegt daran, dass nn.Module die Methode __call__ überschreibt, welche intern forward() aufruft. Es wird empfohlen, model(input) anstelle von model.forward(input) zu verwenden, da ersteres sicherstellt, dass alle Hooks oder zusätzlichen Funktionalitäten (z. B. model.train() oder model.eval()) korrekt angewendet werden.
Beobachtung der Konvergenz
Zusätzlich zum Training des Modells wird der Trainingsverlust in jeder Epoche aufgezeichnet und im Zeitverlauf dargestellt. Wie im Diagramm zu sehen ist, sinkt der Trainingsverlust zunächst rasch und stabilisiert sich dann allmählich um Epoche 60. Ab diesem Punkt nimmt der Verlust nur noch sehr langsam ab, was darauf hindeutet, dass das Modell wahrscheinlich konvergiert ist. Daher wären für dieses Modell etwa 40 Epochen ausreichend.
Danke für Ihr Feedback!