Lære opp modeller med PyTorch
PyTorch er et vanlig maskinlæringsrammeverk for opplæring av dype læringsmodeller. I Azure Databricks forhåndsinstalleres PyTorch i ML-klynger .
Merk deg
Kodesnuttene i denne enheten er angitt som eksempler for å fremheve viktige punkter. Du får muligheten til å kjøre kode for et fullstendig, fungerende eksempel i øvelsen senere i denne modulen.
Definer et PyTorch-nettverk
I PyTorch er modeller basert på et nettverk du definerer. Nettverket består av flere lag, hver med angitte inndata og utdata. I tillegg definerer arbeidet en fremoverfunksjon som bruker funksjoner på hvert lag etter hvert som data sendes gjennom nettverket.
Følgende eksempelkode definerer et nettverk.
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
Selv om koden kan virke kompleks i begynnelsen, definerer denne klassen et relativt enkelt nettverk med tre lag:
- Et inndatalag som godtar fire inndataverdier og genererer fem utdataverdier for neste lag.
- Et lag som godtar fem inndata og genererer fem utdata.
- Et endelig utdatalag som godtar fem inndata og genererer tre utdata.
Fremover-funksjonen bruker lagene på inndata (x), sender utdataene fra hvert lag til neste og returnerer til slutt utdataene fra det siste laget (som inneholder etikettprognosevektoren, y). En rektifisert lineær enhet (ReLU)-aktiveringsfunksjon brukes på utdataene i lag 1 og 2 for å begrense utdataverdiene til positive tall.
Merk deg
Avhengig av typen tapskriterie som brukes, kan du velge å bruke en aktiveringsfunksjon, for eksempel en log_softmax for returverdien for å tvinge den inn i området 0 til 1. Noen tapskriterier (for eksempel CrossEntropyLoss, som vanligvis brukes for flerklasseklassifisering), bruker imidlertid automatisk en passende funksjon.
Hvis du vil opprette en modell for opplæring, trenger du bare å opprette en forekomst av nettverksklassen slik:
myModel = MyNet()
Klargjøre data for modellering
PyTorch-lag fungerer på data som er formatert som tensorer – matriselignende strukturer. Det finnes ulike funksjoner for å konvertere andre vanlige dataformater til tensorer, og du kan definere en PyTorch-datalaster for å lese data tensorer til en modell for opplæring eller inferencing.
Som med de fleste maskinlæringsteknikker med tilsyn, bør du definere separate datasett for opplæring og validering. Denne fordelingen gjør det mulig å validere at modellen forutsier nøyaktig når den presenteres med data som den ikke ble opplært på.
Følgende kode definerer to datainnlastere. en for opplæring og den andre for testing. Kildedataene for hver innlaster i dette eksemplet antas å være en Numpy-matrise med funksjonsverdier og en Numpy-matrise med tilsvarende etikettverdier.
# 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)
Innlasterne i dette eksemplet deler dataene i grupper på 30, som sendes til forward-funksjonen under opplæring eller slutning.
Velg en tapskriterie- og optimaliseringsalgoritme
Modellen læres opp ved å mate opplæringsdataene inn i nettverket, måle tapet (den aggregerte forskjellen mellom forventede og faktiske verdier) og optimalisere nettverket ved å justere vektene og saldoene for å minimere tap. De spesifikke detaljene for hvordan tap beregnes og minimeres, styres av tapskriteriet og optimaliseringsalgoritmen du velger.
Tapskriterier
PyTorch støtter flere tapskriteriefunksjoner, inkludert (blant mange andre):
- cross_entropy: En funksjon som måler den samlede forskjellen mellom forventede og faktiske verdier for flere variabler (vanligvis brukt til å måle tap for klassesannsynligheter i multiklasseklassifisering).
- binary_cross_entropy: En funksjon som måler forskjellen mellom forventede og faktiske sannsynligheter (vanligvis brukt til å måle tap for klassesannsynligheter i binær klassifisering).
- mse_loss: En funksjon som måler gjennomsnittlig kvadratfeiltap for forventede og faktiske numeriske verdier (vanligvis brukt for regresjon).
Hvis du vil angi tapskriteriet du vil bruke når du trener modellen, oppretter du en forekomst av riktig funksjon. som dette:
import torch.nn as nn
loss_criteria = nn.CrossEntropyLoss
Tips
Hvis du vil ha mer informasjon om tilgjengelige tapskriterier i PyTorch, kan du se Tap-funksjoner i PyTorch-dokumentasjonen.
Optimaliseringsalgoritmer
Etter å ha beregnet tapet, brukes en optimalisering til å bestemme hvordan du best kan justere vekter og saldoer for å minimere det. Optimaliseringer er spesifikke implementeringer av en gradert nedstigningstilnærming for å minimere en funksjon. Tilgjengelige optimaliseringer i PyTorch inkluderer (blant annet):
- Adadelta: En optimalisering basert på algoritmen adaptiv læringshastighet .
- Adam: En beregningseffektiv optimalisering basert på Adam-algoritmen .
- SGD: En optimalisering basert på den stokastiske gradientnedstigningsalgoritmen .
Hvis du vil bruke noen av disse algoritmene til å lære opp en modell, må du opprette en forekomst av optimaliseringen og angi eventuelle nødvendige parametere. De spesifikke parameterne varierer avhengig av optimaliseringen som er valgt, men de fleste krever at du angir en læringsrate som styrer størrelsen på justeringene som gjøres med hver optimalisering.
Følgende kode oppretter en forekomst av Adam-optimaliseringen .
import torch.optim as opt
learning_rate = 0.001
optimizer = opt.Adam(model.parameters(), lr=learning_rate)
Tips
Hvis du vil ha mer informasjon om tilgjengelige optimaliseringer i PyTorch, kan du se Algoritmer i PyTorch-dokumentasjonen.
Opprette tog- og testfunksjoner
Når du har definert et nettverk og klargjort data for det, kan du bruke dataene til å lære opp og teste en modell ved å sende opplæringsdataene gjennom nettverket, beregne tap, optimalisere nettverksvektene og skjevhetene og validere ytelsen til nettverket med testdataene. Det er vanlig å definere en funksjon som sender data gjennom nettverket for å lære opp modellen med opplæringsdataene, og en egen funksjon for å teste modellen med testdataene.
Opprett en togfunksjon
Eksemplet nedenfor viser en funksjon for å lære opp en modell.
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
Følgende eksempel viser en funksjon for å teste 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
Kalibrer modellen over flere epoker
For å lære opp en dyp læringsmodell kjører du vanligvis opplæringsfunksjonen flere ganger (referert til som epoker), med mål om å redusere tapet beregnet fra opplæringsdataene hver epoke. Du kan bruke testfunksjonen til å bekrefte at tapet fra testdataene (som modellen ikke ble opplært på) også reduseres i tråd med opplæringstapet – med andre ord at modellopplæringen ikke produserer en modell som er overtilpasset til opplæringsdataene.
Tips
Du trenger ikke å kjøre testfunksjonen for hver epoke. Du kan velge å kjøre den hvert sekund epoke, eller en gang på slutten. Det kan imidlertid være nyttig å teste modellen etter hvor mange epoker en modell begynner å bli overtilpasset.
Følgende kode trener en modell 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)
Lagre den opplærte modelltilstanden
Når du har trent en modell, kan du spare vekter og skjevheter som dette:
model_file = '/dbfs/my_model.pkl'
torch.save(model.state_dict(), model_file)
Hvis du vil laste inn og bruke modellen senere, oppretter du en forekomst av nettverksklassen som modellen er basert på, og laster inn de lagrede vektene og skjevhetene.
model = myNet()
model.load_state_dict(torch.load(model_file))