Träning av Modellen
Förberedelse för träning
Först måste du säkerställa att modellen, förlustfunktionen och optimeraren är korrekt definierade. Låt oss gå igenom varje steg:
- Förlustfunktion: för klassificering kan du använda
CrossEntropyLoss, som förväntar sig råa kontinuerliga värden (logits) som indata och automatiskt applicerarsoftmax; - Optimerare: du kan använda Adam-optimeraren för effektiva gradientuppdateringar.
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)
I PyTorch kombinerar cross-entropy-förlusten log-softmax och negativ log-likelihood (NLL) till en enda förlustfunktion:
Där:
- zy är logiten som motsvarar korrekt klass;
- C är det totala antalet klasser.
Det är också viktigt att dela upp data i tränings- och valideringsuppsättningar (idealiskt bör även en separat testuppsättning finnas). Eftersom datasetet är relativt litet (1143 rader), används en 80% till 20% uppdelning. I detta fall kommer valideringsuppsättningen även att fungera som testuppsättning.
80% för träning och 20% för testning är ofta lämpligt för många scenarier. För större dataset, såsom de med miljontals poster, kan dock en mindre andel tilldelad testuppsättningen (10% eller mindre) vara tillräcklig för att uppnå en tillförlitlig prestandautvärdering. Omvänt, med mycket små dataset (t.ex. färre än tusen poster), är det avgörande att säkerställa att testuppsättningen är tillräckligt stor (25-30%) för att ge en meningsfull utvärdering av modellens prestanda.
Dessutom bör de resulterande NumPy-arrayerna konverteras till tensorer, eftersom PyTorch-modeller kräver tensorinmatningar för beräkningar.
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)
Träningsloop
Träningsloopen omfattar följande steg för varje epok:
- Framåtriktad passering: mata in funktionerna genom modellen för att generera prediktioner;
- Beräkning av förlust: jämför prediktionerna med de faktiska värdena med hjälp av förlustfunktionen;
- Bakåtriktad passering: beräkna gradienter med avseende på modellparametrarna med hjälp av backpropagation;
- Uppdatering av parametrar: justera modellparametrarna med hjälp av optimeraren;
- Övervakning av framsteg: skriv ut förlusten periodiskt för att observera konvergens.
Som du kan se liknar träningsprocessen den för linjär 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()
Att anropa model(input) anropar automatiskt modellens forward()-metod. Detta beror på att nn.Module överskuggar metoden __call__, som internt anropar forward(). Det rekommenderas att använda model(input) istället för model.forward(input), eftersom det förstnämnda säkerställer att eventuella hooks eller ytterligare funktionaliteter (t.ex. model.train() eller model.eval()) tillämpas korrekt.
Observera konvergens
Utöver att träna modellen registreras även träningsförlusten vid varje epok och plottas över tid. Som visas i grafen minskar träningsförlusten initialt snabbt och stabiliseras sedan gradvis runt epok 60. Efter denna punkt minskar förlusten i en mycket långsammare takt, vilket tyder på att modellen sannolikt har konvergerat. Därför skulle det vara tillräckligt att använda cirka 40 epoker för denna modell.
Tack för dina kommentarer!
Fråga AI
Fråga AI
Fråga vad du vill eller prova någon av de föreslagna frågorna för att starta vårt samtal
Fantastiskt!
Completion betyg förbättrat till 5
Träning av Modellen
Svep för att visa menyn
Förberedelse för träning
Först måste du säkerställa att modellen, förlustfunktionen och optimeraren är korrekt definierade. Låt oss gå igenom varje steg:
- Förlustfunktion: för klassificering kan du använda
CrossEntropyLoss, som förväntar sig råa kontinuerliga värden (logits) som indata och automatiskt applicerarsoftmax; - Optimerare: du kan använda Adam-optimeraren för effektiva gradientuppdateringar.
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)
I PyTorch kombinerar cross-entropy-förlusten log-softmax och negativ log-likelihood (NLL) till en enda förlustfunktion:
Där:
- zy är logiten som motsvarar korrekt klass;
- C är det totala antalet klasser.
Det är också viktigt att dela upp data i tränings- och valideringsuppsättningar (idealiskt bör även en separat testuppsättning finnas). Eftersom datasetet är relativt litet (1143 rader), används en 80% till 20% uppdelning. I detta fall kommer valideringsuppsättningen även att fungera som testuppsättning.
80% för träning och 20% för testning är ofta lämpligt för många scenarier. För större dataset, såsom de med miljontals poster, kan dock en mindre andel tilldelad testuppsättningen (10% eller mindre) vara tillräcklig för att uppnå en tillförlitlig prestandautvärdering. Omvänt, med mycket små dataset (t.ex. färre än tusen poster), är det avgörande att säkerställa att testuppsättningen är tillräckligt stor (25-30%) för att ge en meningsfull utvärdering av modellens prestanda.
Dessutom bör de resulterande NumPy-arrayerna konverteras till tensorer, eftersom PyTorch-modeller kräver tensorinmatningar för beräkningar.
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)
Träningsloop
Träningsloopen omfattar följande steg för varje epok:
- Framåtriktad passering: mata in funktionerna genom modellen för att generera prediktioner;
- Beräkning av förlust: jämför prediktionerna med de faktiska värdena med hjälp av förlustfunktionen;
- Bakåtriktad passering: beräkna gradienter med avseende på modellparametrarna med hjälp av backpropagation;
- Uppdatering av parametrar: justera modellparametrarna med hjälp av optimeraren;
- Övervakning av framsteg: skriv ut förlusten periodiskt för att observera konvergens.
Som du kan se liknar träningsprocessen den för linjär 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()
Att anropa model(input) anropar automatiskt modellens forward()-metod. Detta beror på att nn.Module överskuggar metoden __call__, som internt anropar forward(). Det rekommenderas att använda model(input) istället för model.forward(input), eftersom det förstnämnda säkerställer att eventuella hooks eller ytterligare funktionaliteter (t.ex. model.train() eller model.eval()) tillämpas korrekt.
Observera konvergens
Utöver att träna modellen registreras även träningsförlusten vid varje epok och plottas över tid. Som visas i grafen minskar träningsförlusten initialt snabbt och stabiliseras sedan gradvis runt epok 60. Efter denna punkt minskar förlusten i en mycket långsammare takt, vilket tyder på att modellen sannolikt har konvergerat. Därför skulle det vara tillräckligt att använda cirka 40 epoker för denna modell.
Tack för dina kommentarer!