Κοινή χρήση μέσω


Εκπαίδευση μοντέλων με το PyTorch στο Microsoft Fabric

Αυτό το άρθρο περιγράφει τον τρόπο εκπαίδευσης και παρακολούθησης των επαναλήπτων ενός μοντέλου PyTorch. Το πλαίσιο εκμάθησης μηχανής PyTorch βασίζεται στη βιβλιοθήκη Torch. Το PyTorch χρησιμοποιείται συχνά για την όραση υπολογιστών και εφαρμογές επεξεργασίας φυσικής γλώσσας.

Προαπαιτούμενα στοιχεία

Εγκαταστήστε το PyTorch και τη δάδα στο σημειωματάριό σας. Μπορείτε να εγκαταστήσετε ή να αναβαθμίσετε την έκδοση αυτών των βιβλιοθηκών στο περιβάλλον σας, χρησιμοποιώντας την ακόλουθη εντολή:

pip install torch torchvision

Ρύθμιση του πειράματος εκμάθησης μηχανής

Μπορείτε να δημιουργήσετε ένα πείραμα εκμάθησης μηχανής χρησιμοποιώντας το MLFLow API. Η συνάρτηση MLflow set_experiment() δημιουργεί ένα νέο πείραμα εκμάθησης μηχανής με την ονομασία sample-pytorch, εάν δεν υπάρχει ήδη.

Εκτελέστε τον ακόλουθο κώδικα στο σημειωματάριό σας και δημιουργήστε το πείραμα:

import mlflow

mlflow.set_experiment("sample-pytorch")

Εκπαίδευση και αξιολόγηση ενός μοντέλου Pytorch

Αφού ρυθμίσετε το πείραμα, φορτώνετε το σύνολο δεδομένων Τροποποιημένο Εθνικό Ινστιτούτο Προτύπων και Τεχνολογίας (MNIST). Δημιουργείτε τα σύνολα δεδομένων δοκιμής και εκπαίδευσης και, στη συνέχεια, δημιουργείτε μια λειτουργία εκπαίδευσης.

Εκτελέστε τον ακόλουθο κώδικα στο σημειωματάριό σας και εκπαιδεύστε το μοντέλο Pytorch:

import os
import torch
import torch.nn as nn
from torch.autograd import Variable
import torchvision.datasets as dset
import torchvision.transforms as transforms
import torch.nn.functional as F
import torch.optim as optim

# Load the MNIST dataset
root = "/tmp/mnist"
if not os.path.exists(root):
    os.mkdir(root)

trans = transforms.Compose(
    [transforms.ToTensor(), transforms.Normalize((0.5,), (1.0,))]
)

# If the data doesn't exist, download the MNIST dataset
train_set = dset.MNIST(root=root, train=True, transform=trans, download=True)
test_set = dset.MNIST(root=root, train=False, transform=trans, download=True)

batch_size = 100

train_loader = torch.utils.data.DataLoader(
    dataset=train_set, batch_size=batch_size, shuffle=True
)
test_loader = torch.utils.data.DataLoader(
    dataset=test_set, batch_size=batch_size, shuffle=False
) 

print("==>>> total trainning batch number: {}".format(len(train_loader)))
print("==>>> total testing batch number: {}".format(len(test_loader)))

# Define the network
class LeNet(nn.Module):
    def __init__(self):
        super(LeNet, self).__init__()
        self.conv1 = nn.Conv2d(1, 20, 5, 1)
        self.conv2 = nn.Conv2d(20, 50, 5, 1)
        self.fc1 = nn.Linear(4 * 4 * 50, 500)
        self.fc2 = nn.Linear(500, 10)

    def forward(self, x): 
        x = F.relu(self.conv1(x))
        x = F.max_pool2d(x, 2, 2)
        x = F.relu(self.conv2(x))
        x = F.max_pool2d(x, 2, 2)
        x = x.view(-1, 4 * 4 * 50)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return x

    def name(self):
        return "LeNet"

# Train the model
model = LeNet()

optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)

criterion = nn.CrossEntropyLoss()

for epoch in range(1):
    # Model training
    ave_loss = 0
    for batch_idx, (x, target) in enumerate(train_loader):
        optimizer.zero_grad()
        x, target = Variable(x), Variable(target)
        out = model(x)
        loss = criterion(out, target)
        ave_loss = (ave_loss * batch_idx + loss.item()) / (batch_idx + 1)
        loss.backward()
        optimizer.step()
        if (batch_idx + 1) % 100 == 0 or (batch_idx + 1) == len(train_loader):
            print(
                "==>>> epoch: {}, batch index: {}, train loss: {:.6f}".format(
                    epoch, batch_idx + 1, ave_loss
                )
            )
    # Model testing
    correct_cnt, total_cnt, ave_loss = 0, 0, 0
    for batch_idx, (x, target) in enumerate(test_loader):
        x, target = Variable(x, volatile=True), Variable(target, volatile=True)
        out = model(x)
        loss = criterion(out, target)
        _, pred_label = torch.max(out.data, 1)
        total_cnt += x.data.size()[0]
        correct_cnt += (pred_label == target.data).sum()
        ave_loss = (ave_loss * batch_idx + loss.item()) / (batch_idx + 1)

        if (batch_idx + 1) % 100 == 0 or (batch_idx + 1) == len(test_loader):
            print(
                "==>>> epoch: {}, batch index: {}, test loss: {:.6f}, acc: {:.3f}".format(
                    epoch, batch_idx + 1, ave_loss, correct_cnt * 1.0 / total_cnt
                )
            )

torch.save(model.state_dict(), model.name())

Καταγραφή μοντέλου με MLflow

Η επόμενη εργασία ξεκινά μια εκτέλεση MLflow και παρακολουθεί τα αποτελέσματα στο πείραμα εκμάθησης μηχανής. Το δείγμα κώδικα δημιουργεί ένα νέο μοντέλο με την ονομασία sample-pytorch. Δημιουργεί μια εκτέλεση με τις καθορισμένες παραμέτρους και καταγράφει την εκτέλεση εντός του πειράματος sample-pytorch .

Εκτελέστε τον ακόλουθο κώδικα στο σημειωματάριό σας και καταγράψτε το μοντέλο:

with mlflow.start_run() as run:
    print("log pytorch model:")
    mlflow.pytorch.log_model(
        model, "pytorch-model", registered_model_name="sample-pytorch"
    )

    model_uri = "runs:/{}/pytorch-model".format(run.info.run_id)
    print("Model saved in run %s" % run.info.run_id)
    print(f"Model URI: {model_uri}")

Φόρτωση και αξιολόγηση του μοντέλου

Αφού αποθηκεύσετε το μοντέλο, μπορείτε να το φορτώσετε για συμπεράνεις.

Εκτελέστε τον ακόλουθο κώδικα στο σημειωματάριό σας και φορτώστε το μοντέλο για συμπεράνεις:

# Inference with loading the logged model
loaded_model = mlflow.pytorch.load_model(model_uri)
print(type(loaded_model))

correct_cnt, total_cnt, ave_loss = 0, 0, 0
for batch_idx, (x, target) in enumerate(test_loader):
    x, target = Variable(x, volatile=True), Variable(target, volatile=True)
    out = loaded_model(x)
    loss = criterion(out, target)
    _, pred_label = torch.max(out.data, 1)
    total_cnt += x.data.size()[0]
    correct_cnt += (pred_label == target.data).sum()
    ave_loss = (ave_loss * batch_idx + loss.item()) / (batch_idx + 1)

    if (batch_idx + 1) % 100 == 0 or (batch_idx + 1) == len(test_loader):
        print(
            "==>>> epoch: {}, batch index: {}, test loss: {:.6f}, acc: {:.3f}".format(
                epoch, batch_idx + 1, ave_loss, correct_cnt * 1.0 / total_cnt
            )
        )