ฝึกแบบจําลองด้วย 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 รวมถึง (และอื่น ๆ):
- Adadelta: ตัวปรับให้เหมาะสมตามอัลกอริทึมอัตราการเรียนรู้แบบปรับได้
- Adam: เครื่องมือเพิ่มประสิทธิภาพที่มีประสิทธิภาพด้านการคํานวณตามอัลกอริทึม Adam
- SGD: เครื่องมือเพิ่มประสิทธิภาพที่ยึดตามอัลกอริทึมการไล่ระดับสี stochastic
หากต้องการใช้อัลกอริทึมเหล่านี้ในการฝึกแบบจําลอง คุณต้องสร้างอินสแตนซ์ของตัวปรับให้เหมาะสมและตั้งค่าพารามิเตอร์ที่จําเป็น พารามิเตอร์เฉพาะจะแตกต่างกันไปขึ้นอยู่กับตัวปรับให้เหมาะสมที่เลือก แต่ส่วนใหญ่ต้องการให้คุณระบุ อัตราการเรียนรู้ ที่ควบคุมขนาดของการปรับเปลี่ยนที่ทํากับการปรับให้เหมาะสมแต่ละครั้ง
โค้ดต่อไปนี้จะสร้างอินสแตนซ์ของตัวปรับให้เหมาะสม 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))