ฝึกแบบจําลองด้วย PyTorch

เสร็จสมบูรณ์เมื่อ

PyTorch คือเฟรมเวิร์กการเรียนรู้ของเครื่องที่ใช้กันทั่วไปสําหรับแบบจําลองการเรียนรู้เชิงลึกการฝึกอบรม ใน Azure Databricks มีการติดตั้ง PyTorch ไว้ล่วงหน้าในคลัสเตอร์ ML

หมายเหตุ

ส่วนย่อยของโค้ดในหน่วยนี้มีไว้เป็นตัวอย่างเพื่อเน้นจุดสําคัญ คุณจะมีโอกาสเรียกใช้โค้ดสําหรับตัวอย่างการทํางานเต็มรูปแบบในแบบฝึกหัดในภายหลังของโมดูลนี้

กําหนดเครือข่าย PyTorch

ใน PyTorch แบบจําลองจะขึ้นอยู่กับเครือข่ายที่คุณกําหนด เครือข่ายประกอบด้วยหลายเลเยอร์แต่ละรายการมีอินพุตและเอาต์พุตที่ระบุ นอกจากนี้งานจะกําหนดฟังก์ชัน ไปข้างหน้า ที่ใช้ฟังก์ชันกับแต่ละเลเยอร์ในขณะที่ข้อมูลถูกส่งผ่านเครือข่าย

รหัสตัวอย่างต่อไปนี้จะกําหนดเครือข่าย

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

ในขณะที่รหัสอาจดูซับซ้อนในตอนแรก คลาสนี้กําหนดเครือข่ายที่ค่อนข้างง่ายที่มีสามเลเยอร์:

  • เลเยอร์อินพุตที่ยอมรับค่าอินพุตสี่ค่าและสร้างค่าเอาต์พุตห้าค่าสําหรับเลเยอร์ถัดไป
  • เลเยอร์ที่รับข้อมูลป้อนเข้าห้ารายการและสร้างเอาต์พุตห้ารายการ
  • เลเยอร์เอาต์พุตสุดท้ายที่ยอมรับอินพุตห้ารายการและสร้างเอาต์พุตสามรายการ

ฟังก์ชัน ไปข้างหน้า ใช้เลเยอร์กับข้อมูลอินพุต (x) ซึ่งส่งผ่านเอาต์พุตจากแต่ละเลเยอร์ไปยังเลเยอร์ถัดไปและในที่สุดก็ส่งคืนผลลัพธ์จากเลเยอร์สุดท้าย (ซึ่งมีเวกเตอร์การคาดการณ์ป้ายชื่อ , y) ฟังก์ชันการเปิดใช้งาน หน่วยเชิงเส้นที่แก้ไข แล้ว (ReLU) จะถูกนําไปใช้กับเอาต์พุตของเลเยอร์ 1 และ 2 เพื่อจํากัดค่าเอาต์พุตเป็นจํานวนบวก

หมายเหตุ

ขึ้นอยู่กับชนิดของเกณฑ์การสูญหายที่ใช้ คุณอาจเลือกใช้ฟังก์ชันการเปิดใช้งาน เช่น log_softmax กับค่าที่ส่งกลับเพื่อบังคับให้อยู่ในช่วง 0 ถึง 1 อย่างไรก็ตาม เกณฑ์การสูญเสียบางอย่าง (เช่น CrossEntropyLoss ซึ่งมักใช้สําหรับการจัดประเภทแบบหลายคลาส) ใช้ฟังก์ชันที่เหมาะสมโดยอัตโนมัติ

เมื่อต้องสร้างแบบจําลองสําหรับการฝึก คุณเพียงแค่ต้องสร้างอินสแตนซ์ของคลาสเครือข่ายดังนี้:

myModel = MyNet()

เตรียมข้อมูลสําหรับการสร้างแบบจําลอง

เลเยอร์ PyTorch ทํางานกับข้อมูลที่ถูกจัดรูปแบบเป็น Tensors - โครงสร้างที่คล้ายกับเมทริกซ์ มีฟังก์ชันต่าง ๆ มากมายในการแปลงรูปแบบข้อมูลทั่วไปอื่น ๆ เป็นผู้เช่า และคุณสามารถกําหนด ตัวโหลดข้อมูล PyTorch เพื่ออ่านผู้เช่าข้อมูลเป็นแบบจําลองสําหรับการฝึกอบรมหรือการอนุมานได้

เช่นเดียวกับเทคนิคการเรียนรู้ของเครื่องที่มีการกํากับดูแลมากที่สุด คุณควรกําหนดชุดข้อมูลแยกต่างหากสําหรับการฝึกอบรมและการตรวจสอบ การแยกนี้ช่วยให้คุณสามารถตรวจสอบว่าแบบจําลองทํานายได้อย่างถูกต้องเมื่อนําเสนอข้อมูลที่ยังไม่ได้รับการฝึก

โค้ดต่อไปนี้กําหนดตัวโหลดข้อมูลสองตัว หนึ่งสําหรับการฝึกอบรมและอื่น ๆ สําหรับการทดสอบ แหล่งข้อมูลสําหรับตัวโหลดแต่ละตัวในตัวอย่างนี้จะถือว่าเป็นอาร์เรย์ Numpy ของค่าคุณลักษณะและอาร์เรย์ Numpy ของค่าป้ายชื่อที่สอดคล้องกัน

# 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)

ตัวโหลดในตัวอย่างนี้แยกข้อมูลออกเป็นชุดละ 30 ชุดซึ่งจะถูกส่งผ่านไปยังฟังก์ชัน ไปข้างหน้า ในระหว่างการฝึกอบรมหรือการอนุมาน

เลือกเกณฑ์การสูญหายและอัลกอริทึมตัวปรับให้เหมาะสม

แบบจําลองได้รับการฝึกฝนโดยการให้อาหารข้อมูลการฝึกลงในเครือข่ายการวัดผลการสูญเสีย (ความแตกต่างรวมระหว่างค่าที่คาดการณ์และค่าจริง) และปรับเครือข่ายให้เหมาะสมโดยการปรับน้ําหนักและสมดุลเพื่อลดการสูญเสีย รายละเอียดเฉพาะของวิธีการคํานวณการสูญเสียและลดลงถูกควบคุมโดยเกณฑ์การสูญเสียและอัลกอริทึมตัวปรับให้เหมาะสมที่คุณเลือก

เกณฑ์การสูญเสีย

PyTorch สนับสนุนฟังก์ชันเกณฑ์การสูญเสียหลายแบบ รวมถึงฟังก์ชันอื่น ๆ อีกมากมาย::

  • cross_entropy: ฟังก์ชันที่วัดความแตกต่างของการรวมระหว่างค่าที่คาดการณ์และค่าจริงสําหรับตัวแปรหลายรายการ (โดยทั่วไปจะใช้ในการวัดค่าการสูญเสียสําหรับความน่าจะเป็นของคลาสในการจัดประเภทแบบหลายคลาส)
  • binary_cross_entropy: ฟังก์ชันที่วัดความแตกต่างระหว่างความน่าจะเป็นที่คาดการณ์และที่เกิดขึ้นจริง (โดยทั่วไปใช้เพื่อวัดการสูญเสียของคลาสความน่าจะเป็นในการจําแนกประเภทไบนารี)
  • mse_loss: ฟังก์ชันที่วัดการสูญเสียข้อผิดพลาดสี่เหลี่ยมจัตุรัสสําหรับค่าตัวเลขที่คาดการณ์และตามจริง (โดยทั่วไปแล้วใช้สําหรับการถดถอย)

หากต้องการระบุเกณฑ์การสูญหายที่คุณต้องการใช้เมื่อฝึกแบบจําลองของคุณ คุณต้องสร้างอินสแตนซ์ของฟังก์ชันที่เหมาะสม แบบนี้:

import torch.nn as nn

loss_criteria = nn.CrossEntropyLoss

เคล็ดลับ

สําหรับข้อมูลเพิ่มเติมเกี่ยวกับเกณฑ์การสูญเสียที่มีอยู่ใน PyTorch โปรดดู ฟังก์ชัน Loss ในเอกสารประกอบ PyTorch

อัลกอริทึมตัวปรับให้เหมาะสม

เมื่อคํานวณความสูญเสียแล้ว ระบบจะใช้เครื่องมือเพิ่มประสิทธิภาพเพื่อกําหนดวิธีที่ดีที่สุดเพื่อปรับน้ําหนักและสมดุลเพื่อลดขนาดลง ตัวปรับให้เหมาะสมคือการใช้งานเฉพาะของวิธีการ ไล่ระดับสีแบบเซนต์ เพื่อลดฟังก์ชัน ตัวปรับให้เหมาะสมที่พร้อมใช้งานใน PyTorch รวมถึง (และอื่น ๆ):

หากต้องการใช้อัลกอริทึมเหล่านี้ในการฝึกแบบจําลอง คุณต้องสร้างอินสแตนซ์ของตัวปรับให้เหมาะสมและตั้งค่าพารามิเตอร์ที่จําเป็น พารามิเตอร์เฉพาะจะแตกต่างกันไปขึ้นอยู่กับตัวปรับให้เหมาะสมที่เลือก แต่ส่วนใหญ่ต้องการให้คุณระบุ อัตราการเรียนรู้ ที่ควบคุมขนาดของการปรับเปลี่ยนที่ทํากับการปรับให้เหมาะสมแต่ละครั้ง

โค้ดต่อไปนี้จะสร้างอินสแตนซ์ของตัวปรับให้เหมาะสม Adam

import torch.optim as opt

learning_rate = 0.001
optimizer = opt.Adam(model.parameters(), lr=learning_rate)

เคล็ดลับ

สําหรับข้อมูลเพิ่มเติมเกี่ยวกับตัวปรับให้เหมาะสมที่พร้อมใช้งานใน PyTorch ดู อัลกอริทึม ในเอกสารประกอบของ PyTorch

สร้างฟังก์ชันการฝึกอบรมและทดสอบ

หลังจากที่คุณได้กําหนดเครือข่ายและข้อมูลที่เตรียมไว้แล้วคุณสามารถใช้ข้อมูลเพื่อฝึกและทดสอบแบบจําลองโดยการส่งผ่านข้อมูลการฝึกผ่านเครือข่ายการคํานวณการสูญเสียการปรับน้ําหนักเครือข่ายและความอคติให้เหมาะสมและตรวจสอบประสิทธิภาพของเครือข่ายด้วยข้อมูลทดสอบ เป็นเรื่องปกติที่จะกําหนดฟังก์ชันที่ส่งข้อมูลผ่านเครือข่ายเพื่อ ฝึก แบบจําลองด้วยข้อมูลการทดสอบและฟังก์ชันแยกต่างหากเพื่อ ทดสอบ แบบจําลองด้วยข้อมูลทดสอบ

สร้างฟังก์ชันรถไฟ

ตัวอย่างต่อไปนี้แสดงฟังก์ชันในการฝึกแบบจําลอง

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

ตัวอย่างต่อไปนี้แสดงฟังก์ชันเพื่อทดสอบแบบจําลอง

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

ฝึกแบบจําลองผ่านหลายยุค

ในการฝึกแบบจําลองการเรียนรู้เชิงลึก โดยทั่วไปแล้วคุณจะเรียกใช้ฟังก์ชันการฝึกอบรมหลายครั้ง (เรียกว่า ยุค) โดยมีเป้าหมายในการลดการสูญเสียที่คํานวณจากข้อมูลการฝึกอบรมแต่ละยุค คุณสามารถใช้ฟังก์ชันการทดสอบของคุณเพื่อตรวจสอบว่าการสูญหายจากข้อมูลการทดสอบ (ซึ่งแบบจําลองไม่ได้รับการฝึก) จะลดลงตามการสูญเสียการฝึกเช่นกัน - กล่าวอีกนัยหนึ่งว่าการฝึกแบบจําลองไม่ได้ผลิตแบบจําลองที่ พอดีกับข้อมูล การทดสอบการใช้งาน

เคล็ดลับ

คุณไม่จําเป็นต้องเรียกใช้ฟังก์ชันทดสอบสําหรับทุกกรณี คุณอาจเลือกที่จะเรียกใช้ทุกยุคที่สอง หรือหนึ่งครั้งในตอนท้าย อย่างไรก็ตาม การทดสอบแบบจําลองขณะที่ได้รับการฝึกจะมีประโยชน์ในการกําหนดหลังจากที่จํานวนรายงานที่เริ่มใช้งานแบบจําลองมากเกินไป

โค้ดต่อไปนี้จะฝึกแบบจําลองมากกว่า 50 ยุค

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)

บันทึกสถานะแบบจําลองที่ได้รับการฝึกอบรม

หลังจากที่คุณฝึกแบบจําลองเรียบร้อยแล้ว คุณสามารถประหยัดน้ําหนักและความอคติเช่นนี้:

model_file = '/dbfs/my_model.pkl'
torch.save(model.state_dict(), model_file)

หากต้องการโหลดและใช้แบบจําลองในภายหลัง ให้สร้างอินสแตนซ์ของระดับเครือข่ายที่ใช้แบบจําลองและโหลดน้ําหนักและความอคติที่บันทึกไว้

model = myNet()
model.load_state_dict(torch.load(model_file))