Training des Modells
Vorbereitung auf das Training
Zunächst muss sichergestellt werden, dass das Modell, die Verlustfunktion und der Optimierer korrekt definiert sind. Gehen wir die einzelnen Schritte durch:
- Verlustfunktion: Für Klassifikationsaufgaben kann
CrossEntropyLoss
verwendet werden, die rohe kontinuierliche Werte (Logits) als Eingabe erwartet und automatischsoftmax
anwendet; - 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 den Logit für die korrekte Klasse bezeichnet;
- C die Gesamtanzahl der Klassen ist.
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), wird eine Aufteilung von 80 % zu 20 % verwendet. In diesem Fall dient der Validierungsdatensatz auch als Testdatensatz.
Außerdem sollten die resultierenden NumPy-Arrays in Tensoren umgewandelt werden, da PyTorch-Modelle Tensoren als Eingabe 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 für jede Epoche die folgenden Schritte:
- Vorwärtsdurchlauf: Die Eingabefeatures werden durch das Modell geleitet, um Vorhersagen zu erzeugen;
- Berechnung des Verlusts: Die Vorhersagen werden mit den tatsächlichen Werten mittels der Verlustfunktion verglichen;
- Rückwärtsdurchlauf: Die Gradienten bezüglich der Modellparameter werden mittels Backpropagation berechnet;
- Aktualisierung der Parameter: Die Modellparameter werden mit dem Optimierer angepasst;
- Überwachung des Fortschritts: Der Verlust wird periodisch ausgegeben, um die Konvergenz zu beobachten.
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()
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 schnell und stabilisiert sich dann allmählich um Epoche 60. Danach 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
Awesome!
Completion rate improved to 5
Training des Modells
Swipe um das Menü anzuzeigen
Vorbereitung auf das Training
Zunächst muss sichergestellt werden, dass das Modell, die Verlustfunktion und der Optimierer korrekt definiert sind. Gehen wir die einzelnen Schritte durch:
- Verlustfunktion: Für Klassifikationsaufgaben kann
CrossEntropyLoss
verwendet werden, die rohe kontinuierliche Werte (Logits) als Eingabe erwartet und automatischsoftmax
anwendet; - 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 den Logit für die korrekte Klasse bezeichnet;
- C die Gesamtanzahl der Klassen ist.
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), wird eine Aufteilung von 80 % zu 20 % verwendet. In diesem Fall dient der Validierungsdatensatz auch als Testdatensatz.
Außerdem sollten die resultierenden NumPy-Arrays in Tensoren umgewandelt werden, da PyTorch-Modelle Tensoren als Eingabe 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 für jede Epoche die folgenden Schritte:
- Vorwärtsdurchlauf: Die Eingabefeatures werden durch das Modell geleitet, um Vorhersagen zu erzeugen;
- Berechnung des Verlusts: Die Vorhersagen werden mit den tatsächlichen Werten mittels der Verlustfunktion verglichen;
- Rückwärtsdurchlauf: Die Gradienten bezüglich der Modellparameter werden mittels Backpropagation berechnet;
- Aktualisierung der Parameter: Die Modellparameter werden mit dem Optimierer angepasst;
- Überwachung des Fortschritts: Der Verlust wird periodisch ausgegeben, um die Konvergenz zu beobachten.
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()
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 schnell und stabilisiert sich dann allmählich um Epoche 60. Danach 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!