เมื่อฝึกโมเดลแมชชีนเลิร์นนิง เป็นเรื่องปกติที่จะมีการวนซ้ำที่มีการนำเข้า (หรือสร้างข้อมูลการฝึก) ชุดการทำงานผ่านโมเดล การไล่ระดับสีที่ได้รับ และโมเดลที่อัปเดตผ่านเครื่องมือเพิ่มประสิทธิภาพ แม้ว่าคุณจะสามารถเขียนลูปการฝึกของคุณเองสำหรับแอปพลิเคชันการฝึกแต่ละรายการได้ แต่ Swift สำหรับ TensorFlow ก็มีนามธรรมของลูปการฝึกทดลองที่อาจช่วยลดความซับซ้อนของกระบวนการนี้
โมดูล TrainingLoop
ภายใน ที่เก็บโมเดล ประกอบด้วยเวอร์ชันปัจจุบันของลูปการฝึกทั่วไปแบบทดลองนี้ มีโครงสร้างในลักษณะที่จะผสานรวมกับชุดข้อมูลที่ห่อหุ้มซึ่งสอดคล้องกับ Epochs API เพื่อการนำเข้าข้อมูลได้ง่าย และเพื่อทำให้การโต้ตอบของโมเดล ชุดข้อมูล และเครื่องมือเพิ่มประสิทธิภาพอัตโนมัติกับแบ็กเอนด์ตัวเร่งความเร็วเพื่อให้ได้ประสิทธิภาพสูงสุด การปรับแต่งกระบวนการฝึกอบรมอย่างหนักสามารถทำได้โดยการใช้การโทรกลับ
ตัวอย่างที่ใช้รูปภาพส่วนใหญ่ในที่เก็บโมเดลได้รับการแปลงเพื่อใช้นามธรรมของลูปการฝึกนี้ เช่นเดียวกับตัวอย่างการฝึกโมเดลข้อความที่ได้รับการดูแล อย่างไรก็ตาม ลูปการฝึกอบรมอาจไม่เหมาะสมในการออกแบบปัจจุบันสำหรับโมเดลการเรียนรู้ของเครื่องทั้งหมด
การใช้งาน Swift สำหรับลูปการฝึกอบรมทั่วไปของ TensorFlow ได้รับอิทธิพลอย่างมากจาก Learner ของ fastai หากต้องการข้อมูลเพิ่มเติมเกี่ยวกับการออกแบบ โปรดดูที่ "fastai: A Layered API สำหรับการเรียนรู้เชิงลึก" และการนำเสนอของ Sylvain Gugger เรื่อง "Fast.ai - ลูปการฝึกอบรมที่ปรับแต่งได้อย่างไร้ขีดจำกัด"
การใช้งาน
ตัวอย่าง ResNet-CIFAR10 เป็นการสาธิตที่ดีถึงวิธีใช้ลูปการฝึกอบรมนี้ในทางปฏิบัติ ขั้นแรก นำเข้าโมดูล:
import TrainingLoop
จากนั้นเลือกแบ็กเอนด์ตัวเร่งความเร็วโดยการตั้งค่า Device
ในกรณีนี้ เราจะเลือกแบ็กเอนด์ที่ใช้ X10 XLA และใช้ตัวเร่งความเร็วตัวแรกที่มีอยู่:
let device = Device.defaultXLA
ขั้นตอนต่อไปคือการกำหนดค่าชุดข้อมูล โมเดล และเครื่องมือเพิ่มประสิทธิภาพเพื่อใช้กับลูปการฝึกของคุณ:
let dataset = CIFAR10(batchSize: 10, on: device)
var model = ResNet(classCount: 10, depth: .resNet56, downsamplingInFirstStage: false)
var optimizer = SGD(for: model, learningRate: 0.001)
จากนั้นตั้งค่าวงการฝึกอบรม:
var trainingLoop = TrainingLoop(
training: dataset.training,
validation: dataset.validation,
optimizer: optimizer,
lossFunction: softmaxCrossEntropy,
metrics: [.accuracy])
ลูปการฝึกอบรมจะถือว่าชุดข้อมูลที่คุณใช้สอดคล้องกับ Epochs API และอนุญาตให้คุณระบุการแยกภายในชุดข้อมูลที่จะใช้สำหรับการฝึกอบรมและการตรวจสอบ สามารถใช้ฟังก์ชันการสูญเสียใดๆ ได้เมื่อวางลงในกระดาษห่อที่เข้ากันได้ เช่น softmaxCrossEntropy
อยู่ ที่นี่
ตัวชี้วัดปัจจุบันที่สามารถบันทึกได้ ได้แก่:
-
loss
-
accuracy
-
top5Accuracy
-
matthewsCorrelationCoefficient
-
perplexity
สุดท้ายนี้ ในการทำการฝึกอบรม คุณเรียกสิ่งต่อไปนี้:
try! trainingLoop.fit(&model, epochs: 10, on: device)
วิธีนี้จะฝึกโมเดลเป็นเวลา 10 ยุคโดยใช้แบ็กเอนด์ตัวเร่งที่เราระบุ สถิติจะแสดงระหว่างการฝึกบนคอนโซลโดยใช้พรอมต์ภาพเคลื่อนไหว
โทรกลับ
การปรับแต่งลูปการฝึกอบรมทั่วไปนี้เกิดขึ้นผ่านการใช้การโทรกลับ การเรียกกลับเหล่านี้สามารถเชื่อมต่อกับจุดต่างๆ ภายในลูปได้
การโทรกลับในตัวหลายรายการมีฟังก์ชันที่สามารถเพิ่มให้กับลูปการฝึกอบรมใดๆ ได้ ซึ่งรวมถึง:
- การบันทึกสถิติลงในไฟล์ค่าที่คั่นด้วยเครื่องหมายจุลภาค (CSV)
- การปรับอัตราการเรียนรู้ตามตารางเวลาที่กำหนดเอง
- ติดตามและแสดงกราฟความคืบหน้าการฝึกอบรมผ่าน TensorBoard
นอกจากนี้ คุณยังสามารถสร้างการโทรกลับที่คุณกำหนดเองเพื่อเพิ่มฟังก์ชันการทำงานเพิ่มเติมให้กับลูปการฝึกมาตรฐานได้
การบันทึก CSV
คลาส CSVLogger
สรุปการโทรกลับที่จะเขียนสถิติการฝึกอบรมในรูปแบบค่าที่คั่นด้วยเครื่องหมายจุลภาคลงในไฟล์ที่คุณเลือก ไฟล์นี้จะเริ่มต้นด้วยคอลัมน์ที่มีป้ายกำกับ epoch
, batch
และเมตริกใดๆ ก็ตามที่คุณเปิดใช้งานภายในลูปการฝึกอบรมของคุณ จากนั้นจะมีการเขียนหนึ่งแถวสำหรับแต่ละชุด พร้อมด้วยค่าปัจจุบันของคอลัมน์เหล่านั้น
หากต้องการเพิ่มการบันทึก CSV ให้กับลูปการฝึกอบรมของคุณ ให้เพิ่มสิ่งต่อไปนี้ลงในอาร์เรย์ของการโทรกลับที่มีให้กับ callbacks:
สำหรับ TrainingLoop
ของคุณ :
try! CSVLogger(path: "file.csv").log
ตามตัวอย่าง ตัวอย่าง LeNet-MNIST
ใช้สิ่งนี้ภายในลูปการฝึกอบรม
ตารางอัตราการเรียนรู้
เป็นเรื่องปกติเมื่อฝึกโมเดลเพื่อเปลี่ยนอัตราการเรียนรู้ที่มอบให้กับเครื่องมือเพิ่มประสิทธิภาพในระหว่างกระบวนการฝึก สิ่งนี้อาจทำได้ง่ายเพียงแค่การลดลงเชิงเส้นเมื่อเวลาผ่านไป หรือซับซ้อนเท่ากับวงจรการวอร์มอัพและการลดลงที่อธิบายโดยฟังก์ชันที่ซับซ้อน
การเรียกกลับ learningRateScheduler
ให้วิธีการอธิบายตารางอัตราการเรียนรู้ที่ประกอบด้วยส่วนต่างๆ โดยแต่ละส่วนจะมีรูปร่างที่แตกต่างกันออกไป ซึ่งสามารถทำได้โดยการกำหนด LearningRateSchedule
ซึ่งประกอบด้วย ScheduleSegment
ซึ่งแต่ละรายการมี Shape
ที่กำหนดโดยฟังก์ชัน อัตราการเรียนรู้เริ่มต้น และอัตราการเรียนรู้ขั้นสุดท้าย
ตัวอย่างเช่น ตัวอย่าง BERT-CoLA ใช้อัตราการเรียนรู้ที่เพิ่มขึ้นเชิงเส้นระหว่างช่วงวอร์มอัพ และลดลงเชิงเส้นหลังจากนั้น เมื่อต้องการทำเช่นนี้ การโทรกลับตามกำหนดการอัตราการเรียนรู้มีการกำหนดดังนี้:
learningRateScheduler(
schedule: makeSchedule(
[
ScheduleSegment(shape: linear, startRate: 0, endRate: peakLearningRate, stepCount: 10),
ScheduleSegment(shape: linear, endRate: 0)
]
)
)
ScheduleSegment
ทั้งสองกำหนดอัตราการเรียนรู้ที่เริ่มต้นที่ 0 และเพิ่มเชิงเส้นเป็น peakLearningRate
ผ่านชุดขั้นตอนแยกกัน 10 ขั้นตอน จากนั้นเริ่มต้นที่อัตราการเรียนรู้ขั้นสุดท้ายจากขั้นตอนก่อนหน้า และลดลงเชิงเส้นเป็น 0 เมื่อสิ้นสุดกระบวนการฝึกอบรม
การบูรณาการเทนเซอร์บอร์ด
TensorBoard เป็นเครื่องมือแสดงภาพอันทรงพลังสำหรับตรวจสอบการฝึกโมเดล วิเคราะห์การฝึกเมื่อเสร็จสิ้น หรือเปรียบเทียบการฝึก Swift สำหรับ TensorFlow รองรับการแสดงภาพ TensorBoard ผ่านการใช้โมดูล TensorBoard
ในที่เก็บโมเดล ซึ่งจัดให้มีการโทรกลับที่บันทึกเมตริกการฝึก
ตัวอย่าง GPT2-WikiText2 จะแสดงวิธีเพิ่มการบันทึก TensorBoard ให้กับการฝึกโมเดลของคุณ ขั้นแรก ให้นำเข้าโมดูล TensorBoard
จากนั้นทำได้ง่ายเพียงแค่เพิ่ม tensorBoardStatisticsLogger()
ให้กับ callbacks:
array ของ TrainingLoop
ตามค่าเริ่มต้น ระบบจะบันทึกการฝึกซ้อมแต่ละครั้งภายในไดเร็กทอรี run/tensorboard/stats
หากต้องการดูสิ่งนี้ภายใน Tensorboard ให้เรียกใช้
tensorboard --logdir ./run/tensorboard/stats
และ TensorBoard ควรเริ่มต้นเซิร์ฟเวอร์ในเครื่องซึ่งคุณสามารถดูเมตริกการฝึกอบรมของคุณได้ ควรแสดงผลการฝึกอบรมและการตรวจสอบแยกกัน และการวิ่งแต่ละครั้งจะมีการประทับเวลาที่ไม่ซ้ำกันเพื่อให้สามารถเปรียบเทียบได้ง่ายระหว่างการวิ่งหลายครั้งในรุ่นเดียวกัน
การออกแบบ Swift สำหรับการรวม TensorFlow TensorBoard ได้รับแรงบันดาลใจจาก tensorboardX การเรียกกลับของ TensorBoard จะสร้างเหตุการณ์ที่เหมาะสมและบัฟเฟอร์โปรโตคอลสรุปโดยตรง และเขียนไว้ในไฟล์บันทึกระหว่างการฝึก
โทรกลับที่กำหนดเอง
นอกเหนือจากการโทรกลับในตัวที่อธิบายไว้ข้างต้นแล้ว คุณยังปรับแต่งฟังก์ชันของลูปการฝึกอบรมได้ด้วยการสร้างการโทรกลับของคุณเอง การเรียกกลับเหล่านี้เป็นฟังก์ชันที่มีลายเซ็นคล้ายกับข้อความต่อไปนี้:
func customCallback<L: TrainingLoopProtocol>(_ loop: inout L, event: TrainingLoopEvent) throws
{
if event == .updateStart {
...
}
}
ลูปการฝึกและสถานะที่เกี่ยวข้องจะถูกส่งผ่านเป็นพารามิเตอร์แรก ส่วนปัจจุบันของลูปที่การโทรกลับตอบสนองนั้นมีให้ผ่าน event
เหตุการณ์ลูปการฝึกมีสถานะใดสถานะหนึ่งต่อไปนี้ ซึ่งแต่ละสถานะจะสอดคล้องกับจุดที่แตกต่างกันในวงจรชีวิตของลูป:
-
fitStart
-
fitEnd
-
epochStart
-
epochEnd
-
trainingStart
-
trainingEnd
-
validationStart
-
validationEnd
-
batchStart
-
batchEnd
-
updateStart
-
inferencePredictionEnd
ฟังก์ชันโทรกลับของคุณสามารถเลือกเปิดใช้งานลอจิกกับสถานะข้างต้นรวมกันได้ ซึ่งช่วยให้สามารถดึงข้อมูลจากหรือควบคุมลูปการฝึกอบรมได้หลายวิธี