Modele de tren cu PyTorch
PyTorch este un cadru de învățare programată utilizat de obicei pentru instruirea modelelor de învățare profundă. În Azure Databricks, PyTorch este preinstalat în clusterele ML .
Notă
Fragmentele de cod din această unitate sunt furnizate ca exemple pentru a sublinia punctele cheie. Veți avea ocazia să rulați cod pentru un exemplu complet, de lucru în exercițiul următor în acest modul.
Definiți o rețea PyTorch
În PyTorch, modelele se bazează pe o rețea pe care o definiți. Rețeaua constă din mai multe straturi, fiecare cu intrări și ieșiri specificate. În plus, munca definește o funcție de redirecționare care aplică funcții fiecărui strat pe măsură ce datele sunt transmise prin rețea.
Următorul exemplu de cod definește o rețea.
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
În timp ce codul poate părea complex la început, această clasă definește o rețea relativ simplă cu trei straturi:
- Un strat de intrare care acceptă patru valori de intrare și generează cinci valori de ieșire pentru următorul strat.
- Un strat care acceptă cinci intrări și generează cinci ieșiri.
- Un strat final de ieșire care acceptă cinci intrări și generează trei ieșiri.
Funcția forward aplică straturile la datele de intrare (x), care transmite ieșirea din fiecare strat în următorul și, în cele din urmă, returnează rezultatul din ultimul strat (care conține vectorul de predicție a etichetei, y). O funcție de activare a unității liniare rectificate (ReLU) se aplică ieșirilor nivelurilor 1 și 2 pentru a limita valorile de ieșire la numere pozitive.
Notă
În funcție de tipul de criteriu de pierdere utilizat, puteți alege să aplicați o funcție de activare, cum ar fi o log_softmax la valoarea returnată, pentru a o forța în intervalul 0-1. Cu toate acestea, unele criterii de pierdere (cum ar fi CrossEntropyLoss, care este utilizat de obicei pentru clasificarea multiclass) aplică automat o funcție adecvată.
Pentru a crea un model de instruire, trebuie doar să creați o instanță a clasei de rețea astfel:
myModel = MyNet()
Pregătirea datelor pentru modelare
Straturile PyTorch lucrează la date formatate ca tensori - structuri de matrice asemănătoare. Există diverse funcții pentru a efectua conversia altor formate de date comune în tensoruri și puteți defini un încărcător de date PyTorch pentru a citi tensori de date într-un model pentru instruire sau deducere.
La fel ca în cazul celor mai supravegheate tehnici de învățare programată, ar trebui să definiți seturi de date separate pentru instruire și validare. Această separare vă permite să validați că modelul prezice corect atunci când este prezentat cu date pe care nu a fost instruit.
Următorul cod definește două încărcătoare de date; una pentru instruire, iar cealaltă pentru testare. Datele sursă pentru fiecare încărcător din acest exemplu se consideră a fi o matrice Numpy de valori de caracteristici și o matrice Numpy de valori de etichete corespondente.
# 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)
Încărcătoarele din acest exemplu scindează datele în grupuri de 30, care sunt transmise funcției de redirecționare în timpul instruirii sau al deducerii.
Alegeți un criteriu de pierdere și algoritmul de optimizare
Modelul este instruit prin alimentarea datelor de instruire în rețea, prin măsurarea pierderii (diferența agregată dintre valorile estimate și cele reale) și optimizarea rețelei prin ajustarea greutăților și soldurilor pentru a reduce pierderea. Detaliile specifice ale modului în care este calculată și minimizată pierderea este guvernată de criteriul de pierdere și de algoritmul de optimizare pe care îl alegeți.
Criterii de pierdere
PyTorch acceptă mai multe funcții de criterii de pierdere, inclusiv (printre multe altele):
- cross_entropy: O funcție care măsoară diferența agregată dintre valorile estimate și valorile reale pentru mai multe variabile (utilizată de obicei pentru a măsura pierderile pentru probabilitățile de clasă în clasificarea multiclasă).
- binary_cross_entropy: O funcție care măsoară diferența dintre probabilitățile estimate și cele reale (utilizată de obicei pentru a măsura pierderile pentru probabilitățile de clasă în clasificarea binară).
- mse_loss: O funcție care măsoară pierderea de eroare pătrată medie pentru valorile numerice estimate și reale (utilizată de obicei pentru regresie).
Pentru a specifica criteriul de pierdere pe care doriți să-l utilizați atunci când vă instruiți modelul, creați o instanță a funcției corespunzătoare; aşa:
import torch.nn as nn
loss_criteria = nn.CrossEntropyLoss
Sfat
Pentru mai multe informații despre criteriile de pierdere disponibile în PyTorch, consultați Funcții de pierdere în documentația PyTorch.
Algoritmi de optimizare
După ce ați calculat pierderea, se utilizează un optimizator pentru a determina cât mai bine să ajustați greutățile și soldurile pentru a-l minimiza. Optimizatorii sunt implementări specifice ale unei abordări descendentă gradient pentru minimizarea unei funcții. Optimizatoarele disponibile în PyTorch includ (printre altele):
- Adadelta: Un optimizator bazat pe algoritmul ratei de învățare adaptivă .
- Un optimizator eficient calculat pe baza algoritmului Adam .
- SGD: Un optimizator bazat pe algoritmul de descent de gradient stochastic .
Pentru a utiliza oricare dintre acești algoritmi pentru a instrui un model, trebuie să creați o instanță a optimizatorului și să setați toți parametrii necesari. Parametrii specifici variază în funcție de optimizatorul ales, dar cel mai mult vă solicită să specificați o rată de învățare care guvernează dimensiunea ajustărilor efectuate cu fiecare optimizare.
Următorul cod creează o instanță a optimizatorului Adam .
import torch.optim as opt
learning_rate = 0.001
optimizer = opt.Adam(model.parameters(), lr=learning_rate)
Sfat
Pentru mai multe informații despre optimizatorii disponibili în PyTorch, consultați Algoritmi în documentația PyTorch.
Crearea funcțiilor de instruire și testare
După ce ați definit o rețea și date pregătite pentru aceasta, puteți utiliza datele pentru a instrui și a testa un model, trecând datele de instruire prin rețea, calculând pierderile, optimizând greutățile și biza rețelei și validând performanța rețelei cu datele de test. Este comun să definiți o funcție care transmite date prin rețea pentru a instrui modelul cu datele de instruire și o funcție separată pentru a testa modelul cu datele de test.
Crearea unei funcții de tren
Următorul exemplu arată o funcție pentru instruirea unui 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
Următorul exemplu arată o funcție pentru a testa modelul.
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
Instruiți modelul peste mai multe epoci
Pentru a instrui un model de învățare profundă, rulați de obicei funcția de instruire de mai multe ori (denumite epoci), cu scopul de a reduce pierderea calculată din datele de instruire pe fiecare epocă. Puteți utiliza funcția de testare pentru a valida faptul că pierderea datelor de test (pe care modelul nu a fost instruit) reduce, de asemenea, în conformitate cu pierderile de instruire, cu alte cuvinte, că instruirea modelului nu produce un model care este supraasistat cu datele de instruire.
Sfat
Nu trebuie să rulați funcția de test pentru fiecare epocă. Puteți alege să-l rulați la fiecare a doua epocă sau o dată la sfârșit. Totuși, testarea modelului în timp ce este instruit poate fi utilă pentru a determina după câte epoci începe să devină supraaplicate.
Următorul cod instruiește un model de peste 50 de epoci.
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)
Salvați starea modelului instruit
După ce ați instruit cu succes un model, îi puteți economisi greutățile și biaza astfel:
model_file = '/dbfs/my_model.pkl'
torch.save(model.state_dict(), model_file)
Pentru a încărca și a utiliza modelul ulterior, creați o instanță a clasei de rețea pe care se bazează modelul și încărcați greutățile salvate și biază.
model = myNet()
model.load_state_dict(torch.load(model_file))