Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lernen Training des Modells | Abschnitt
PyTorch-Grundlagen für ML-Ingenieure

bookTraining des Modells

Vorbereitung auf das Training

Zunächst müssen Modell, Verlustfunktion und Optimierer korrekt definiert werden. Gehen wir die einzelnen Schritte durch:

  1. Verlustfunktion: Für Klassifikationsaufgaben kann CrossEntropyLoss verwendet werden, die rohe kontinuierliche Werte (Logits) als Eingabe erwartet und automatisch softmax anwendet;
  2. 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:

L=log(ezyj=1Cezj)\mathcal{L} = - \log{\left( \frac{e^{z_y}}{\sum^C_{j=1}e^{z_j}} \right)}

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.

Note
Mehr erfahren

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:

  1. Forward Pass: Weiterleitung der Eingabemerkmale durch das Modell zur Generierung von Vorhersagen;
  2. Berechnung des Verlusts: Vergleich der Vorhersagen mit den tatsächlichen Werten mittels Verlustfunktion;
  3. Backward Pass: Berechnung der Gradienten bezüglich der Modellparameter mittels Backpropagation;
  4. Aktualisierung der Parameter: Anpassung der Modellparameter mit dem Optimierer;
  5. Überwachung des Fortschritts: Periodische Ausgabe des Verlusts zur Beobachtung der Konvergenz.

Wie ersichtlich, ähnelt der Trainingsprozess dem der linearen Regression.

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
import 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()
copy
Note
Hinweis

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.

question mark

Welche der folgenden Optionen beschreibt die korrekte Abfolge der Schritte in einer PyTorch-Trainingsschleife?

Select the correct answer

War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 1. Kapitel 18

Fragen Sie AI

expand

Fragen Sie AI

ChatGPT

Fragen Sie alles oder probieren Sie eine der vorgeschlagenen Fragen, um unser Gespräch zu beginnen

bookTraining 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:

  1. Verlustfunktion: Für Klassifikationsaufgaben kann CrossEntropyLoss verwendet werden, die rohe kontinuierliche Werte (Logits) als Eingabe erwartet und automatisch softmax anwendet;
  2. 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:

L=log(ezyj=1Cezj)\mathcal{L} = - \log{\left( \frac{e^{z_y}}{\sum^C_{j=1}e^{z_j}} \right)}

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.

Note
Mehr erfahren

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:

  1. Forward Pass: Weiterleitung der Eingabemerkmale durch das Modell zur Generierung von Vorhersagen;
  2. Berechnung des Verlusts: Vergleich der Vorhersagen mit den tatsächlichen Werten mittels Verlustfunktion;
  3. Backward Pass: Berechnung der Gradienten bezüglich der Modellparameter mittels Backpropagation;
  4. Aktualisierung der Parameter: Anpassung der Modellparameter mit dem Optimierer;
  5. Überwachung des Fortschritts: Periodische Ausgabe des Verlusts zur Beobachtung der Konvergenz.

Wie ersichtlich, ähnelt der Trainingsprozess dem der linearen Regression.

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
import 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()
copy
Note
Hinweis

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.

question mark

Welche der folgenden Optionen beschreibt die korrekte Abfolge der Schritte in einer PyTorch-Trainingsschleife?

Select the correct answer

War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 1. Kapitel 18
some-alt