Microsoft Fabric의 PyTorch를 통해 모델 학습
이 문서에서는 PyTorch 모델의 반복을 학습하고 추적하는 방법을 설명합니다. PyTorch 기계 학습 프레임워크는 Torch 라이브러리를 기반으로 합니다. PyTorch는 컴퓨터 비전 및 자연어 처리 애플리케이션에 자주 사용됩니다.
필수 조건
Notebook에 PyTorch와 torchvision을 설치해야 합니다. 다음 명령을 사용하여 사용자 환경에 이러한 라이브러리 버전을 설치하거나 업그레이드할 수 있습니다.
pip install torch torchvision
기계 학습 실험 설정
MLFLow API를 사용하여 기계 학습 실험을 만들 수 있습니다. MLflow set_experiment()
함수는 아직 기계 학습 실험이 없을 경우 sample-pytorch라는 이름의 새 기계 학습 실험을 만듭니다.
Notebook에서 다음 명령을 실행하여 실험을 만듭니다.
import mlflow
mlflow.set_experiment("sample-pytorch")
Pytorch 모델 학습 및 평가
실험을 설정한 후 수정된 MNIST(미국 국립표준기술원) 데이터 세트를 로드합니다. 테스트 및 학습 데이터 세트를 생성한 다음 학습 함수를 만듭니다.
Notebook에서 다음 코드를 실행하고 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 실험 내에서 실행을 기록합니다.
Notebook에서 다음 코드를 실행하고 모델을 기록합니다.
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}")
모델 로드 및 평가
모델을 저장한 후 추론을 위해 로드할 수 있습니다.
Notebook에서 다음 코드를 실행하고 추론을 위해 모델을 로드합니다.
# 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
)
)