วงการฝึก

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

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