Oplær modeller med PyTorch
PyTorch er en almindeligt brugt maskinel indlæringsramme til oplæring af modeller til dyb læring. I Azure Databricks er PyTorch forudinstalleret i ML-klynger .
Seddel
Kodestykkerne i dette undermodul er angivet som eksempler for at fremhæve vigtige punkter. Du har mulighed for at køre kode for at få et fuldt eksempel i øvelsen senere i dette modul.
Definer et PyTorch-netværk
I PyTorch er modeller baseret på et netværk, som du definerer. Netværket består af flere lag, hver med angivne input og output. Derudover definerer arbejdet en fremadrettet funktion, der anvender funktioner på hvert lag, når data overføres via netværket.
Følgende eksempelkode definerer et netværk.
import torch
import torch.nn as nn
import torch.nn.functional as F
class MyNet(nn.Module):
def __init__(self):
super(MyNet, self).__init__()
self.layer1 = nn.Linear(4, 5)
self.layer2 = nn.Linear(5, 5)
self.layer3 = nn.Linear(5, 3)
def forward(self, x):
layer1_output = torch.relu(self.layer1(x))
layer2_output = torch.relu(self.layer2(layer1_output))
y = self.layer3(layer2_output)
return y
Selvom koden kan virke kompleks i starten, definerer denne klasse et relativt simpelt netværk med tre lag:
- Et inputlag, der accepterer fire inputværdier og genererer fem outputværdier for det næste lag.
- Et lag, der accepterer fem input og genererer fem output.
- Et endeligt outputlag, der accepterer fem input og genererer tre output.
Funktionen forward anvender lagene på inputdataene (x), overfører outputtet fra hvert lag til det næste og returnerer til sidst outputtet fra det sidste lag (som indeholder etiketforudsigelsesvektoren y). En rektificeret aktiveringsfunktion for lineær enhed (ReLU) anvendes på outputtet fra lag 1 og 2 for at begrænse outputværdierne til positive tal.
Seddel
Afhængigt af den anvendte type tabskriterium kan du vælge at anvende en aktiveringsfunktion, f.eks. en log_softmax på returværdien for at tvinge den ind i intervallet 0 til 1. Nogle kriterier for tab (f.eks . CrossEntropyLoss, som ofte bruges til klassificering i flere klasse) anvender dog automatisk en passende funktion.
Hvis du vil oprette en model til oplæring, skal du blot oprette en forekomst af netværksklassen som denne:
myModel = MyNet()
Forbered data til modellering
PyTorch-lag fungerer på data, der er formateret som tensors – matrixlignende strukturer. Der er forskellige funktioner til at konvertere andre almindelige dataformater til tensors, og du kan definere en PyTorch-dataindlæser til at læse data tensors i en model til oplæring eller udledning.
Som med de fleste overvågede teknikker til maskinel indlæring skal du definere separate datasæt til oplæring og validering. Denne adskillelse giver dig mulighed for at validere, at modellen forudsiger nøjagtigt, når den præsenteres for data, som den ikke blev oplært i.
Følgende kode definerer to dataindlæsningsmaskiner. den ene til oplæring og den anden til test. Kildedataene for hver indlæsser i dette eksempel antages at være en Numpy-matrix med funktionsværdier og en Numpy-matrix med tilsvarende mærkatværdier.
# Create a dataset and loader for the training data and labels
train_x = torch.Tensor(x_train).float()
train_y = torch.Tensor(y_train).long()
train_ds = td.TensorDataset(train_x,train_y)
train_loader = td.DataLoader(train_ds, batch_size=20,
shuffle=False, num_workers=1)
# Create a dataset and loader for the test data and labels
test_x = torch.Tensor(x_test).float()
test_y = torch.Tensor(y_test).long()
test_ds = td.TensorDataset(test_x,test_y)
test_loader = td.DataLoader(test_ds, batch_size=20,
shuffle=False, num_workers=1)
Indlæsningsmaskinerne i dette eksempel opdeler dataene i batches på 30, som overføres til fremadrettet funktion under oplæring eller konklusion.
Vælg et tabskriterium og en optimeringsalgoritme
Modellen oplæres ved at overføre træningsdataene til netværket, måle tabet (den aggregerede forskel mellem forudsagte og faktiske værdier) og optimere netværket ved at justere vægte og balancer for at minimere tab. De specifikke oplysninger om, hvordan tab beregnes og minimeres, er underlagt det tabskriterium og den optimeringsalgoritme, du vælger.
Kriterier for tab
PyTorch understøtter flere kriterier for tab, herunder (blandt mange andre):
- cross_entropy: En funktion, der måler den samlede forskel mellem forudsagte og faktiske værdier for flere variabler (bruges typisk til at måle tab for klassesandsynlighed i klassificering med flere klasser).
- binary_cross_entropy: En funktion, der måler forskellen mellem forudsagte og faktiske sandsynligheder (bruges typisk til at måle tab for klassesandsynlighed i binær klassificering).
- mse_loss: En funktion, der måler det gennemsnitlige kvadratiske fejltab for forudsagte og faktiske numeriske værdier (typisk brugt til regression).
Hvis du vil angive det tabskriterium, du vil bruge til oplæring af din model, skal du oprette en forekomst af den relevante funktion. Som dette:
import torch.nn as nn
loss_criteria = nn.CrossEntropyLoss
Drikkepenge
Du kan få flere oplysninger om tilgængelige tabskriterier i PyTorch under Tabsfunktioner i dokumentationen til PyTorch.
Optimeringsalgoritmer
Når du har beregnet tabet, bruges en optimering til at bestemme, hvordan du bedst justerer vægte og saldi for at minimere det. Optimering er specifikke implementeringer af en gradueringsstigningstilgang for at minimere en funktion. Tilgængelige optimeringer i PyTorch omfatter (blandt andet):
- Adadelta: En optimering baseret på algoritmen Adaptive Læringsfrekvens .
- Adam: En beregningsmæssigt effektiv optimering baseret på Adam-algoritmen.
- SGD: En optimering baseret på algoritmen stokastisk gradueringsafstamning .
Hvis du vil bruge en af disse algoritmer til at oplære en model, skal du oprette en forekomst af optimeringsfunktionen og angive eventuelle påkrævede parametre. De specifikke parametre varierer afhængigt af den valgte optimering, men de fleste kræver, at du angiver en læringsfrekvens , der styrer størrelsen af justeringer, der foretages med hver optimering.
Følgende kode opretter en forekomst af Adam-optimeringsprogrammet .
import torch.optim as opt
learning_rate = 0.001
optimizer = opt.Adam(model.parameters(), lr=learning_rate)
Drikkepenge
Du kan få flere oplysninger om tilgængelige optimeringer i PyTorch under Algoritmer i dokumentationen til PyTorch.
Opret oplær- og testfunktioner
Når du har defineret et netværk og forberedt data til det, kan du bruge dataene til at oplære og teste en model ved at overføre træningsdataene via netværket, beregne tabet, optimere netværksvægte og -forskelle og validere netværkets ydeevne med testdataene. Det er almindeligt at definere en funktion, der overfører data gennem netværket for at oplære modellen med træningsdataene, og en separat funktion til at teste modellen med testdataene.
Opret en oplæringsfunktion
I følgende eksempel vises en funktion til at oplære en model.
def train(model, data_loader, optimizer):
# Use GPU if available, otherwise CPU
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model.to(device)
# Set the model to training mode (to enable backpropagation)
model.train()
train_loss = 0
# Feed the batches of data forward through the network
for batch, tensor in enumerate(data_loader):
data, target = tensor # Specify features and labels in a tensor
optimizer.zero_grad() # Reset optimizer state
out = model(data) # Pass the data through the network
loss = loss_criteria(out, target) # Calculate the loss
train_loss += loss.item() # Keep a running total of loss for each batch
# backpropagate adjustments to weights/bias
loss.backward()
optimizer.step()
#Return average loss for all batches
avg_loss = train_loss / (batch+1)
print('Training set: Average loss: {:.6f}'.format(avg_loss))
return avg_loss
I følgende eksempel vises en funktion til test af modellen.
def test(model, data_loader):
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model.to(device)
# Switch the model to evaluation mode (so we don't backpropagate)
model.eval()
test_loss = 0
correct = 0
# Pass the data through with no gradient computation
with torch.no_grad():
batch_count = 0
for batch, tensor in enumerate(data_loader):
batch_count += 1
data, target = tensor
# Get the predictions
out = model(data)
# calculate the loss
test_loss += loss_criteria(out, target).item()
# Calculate the accuracy
_, predicted = torch.max(out.data, 1)
correct += torch.sum(target==predicted).item()
# Calculate the average loss and total accuracy for all batches
avg_loss = test_loss/batch_count
print('Validation set: Average loss: {:.6f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
avg_loss, correct, len(data_loader.dataset),
100. * correct / len(data_loader.dataset)))
return avg_loss
Oplær modellen over flere epoker
Hvis du vil oplære en model til dyb læring, kører du typisk oplæringsfunktionen flere gange (kaldet epoker) med det mål at reducere tabet beregnet ud fra træningsdataene hver epoke. Du kan bruge din testfunktion til at validere, at tabet fra testdataene (som modellen ikke blev oplært på) også reduceres i overensstemmelse med træningstabet – med andre ord, at modeltræningen ikke producerer en model, der overbelastes til oplæringsdataene.
Drikkepenge
Du behøver ikke at køre testfunktionen for hver epoke. Du kan vælge at køre den hver anden epoke eller én gang til sidst. Det kan dog være nyttigt at teste modellen, efterhånden som den oplæres, når det afgøres, hvor mange epoker en model begynder at blive overfitted.
Følgende kode oplærer en model over 50 epoker.
epochs = 50
for epoch in range(1, epochs + 1):
# print the epoch number
print('Epoch: {}'.format(epoch))
# Feed training data into the model to optimize the weights
train_loss = train(model, train_loader, optimizer)
print(train_loss)
# Feed the test data into the model to check its performance
test_loss = test(model, test_loader)
print(test_loss)
Gem tilstanden for den oplærte model
Når du har oplært en model, kan du gemme dens vægte og forskelle som denne:
model_file = '/dbfs/my_model.pkl'
torch.save(model.state_dict(), model_file)
Hvis du vil indlæse og bruge modellen på et senere tidspunkt, skal du oprette en forekomst af den netværksklasse, som modellen er baseret på, og indlæse de gemte vægte og forskelle.
model = myNet()
model.load_state_dict(torch.load(model_file))