Vòng lặp đào tạo

Khi đào tạo một mô hình học máy, thông thường sẽ có một vòng lặp trong đó dữ liệu đào tạo được nhập (hoặc tạo), các đợt chạy qua một mô hình, độ dốc thu được và mô hình được cập nhật thông qua trình tối ưu hóa. Mặc dù bạn có thể viết vòng lặp đào tạo của riêng mình cho từng ứng dụng đào tạo, Swift cho TensorFlow cung cấp bản tóm tắt vòng đào tạo thử nghiệm có thể đơn giản hóa quy trình này.

Mô-đun TrainingLoop trong kho mô hình chứa phiên bản hiện tại của vòng đào tạo tổng quát thử nghiệm này. Nó được cấu trúc theo cách tích hợp với các trình bao bọc tập dữ liệu phù hợp với API Epochs để dễ dàng nhập dữ liệu và tự động hóa sự tương tác của các mô hình, bộ dữ liệu và trình tối ưu hóa với phần phụ trợ của bộ tăng tốc để đạt được hiệu suất tối ưu. Có thể đạt được sự tùy chỉnh mạnh mẽ của quá trình đào tạo thông qua việc sử dụng các lệnh gọi lại.

Hầu hết các ví dụ dựa trên hình ảnh trong kho mô hình đã được chuyển đổi để sử dụng tính trừu tượng của vòng đào tạo này, cũng như các ví dụ đào tạo mô hình văn bản được giám sát. Tuy nhiên, vòng đào tạo có thể không phù hợp trong thiết kế hiện tại đối với tất cả các mô hình học máy.

Việc triển khai Swift cho vòng đào tạo tổng quát của TensorFlow chịu ảnh hưởng nặng nề từ Fastai's Learner . Để biết thêm về thiết kế của họ, vui lòng tham khảo "fastai: API nhiều lớp cho học sâu" và bài thuyết trình của Sylvain Gugger "Fast.ai - Vòng lặp đào tạo có thể tùy chỉnh vô hạn" .

Cách sử dụng

Ví dụ ResNet-CIFAR10 cung cấp một minh họa tốt về cách sử dụng vòng đào tạo này trong thực tế. Đầu tiên, nhập mô-đun:

import TrainingLoop

sau đó chọn phần phụ trợ tăng tốc bằng cách thiết lập Device . Trong trường hợp này, chúng tôi sẽ chọn chương trình phụ trợ dựa trên X10 XLA và sử dụng trình tăng tốc có sẵn đầu tiên:

let device = Device.defaultXLA

Bước tiếp theo là định cấu hình tập dữ liệu, mô hình và trình tối ưu hóa để sử dụng với vòng đào tạo của bạn:

let dataset = CIFAR10(batchSize: 10, on: device)
var model = ResNet(classCount: 10, depth: .resNet56, downsamplingInFirstStage: false)
var optimizer = SGD(for: model, learningRate: 0.001)

và sau đó thiết lập vòng đào tạo:

var trainingLoop = TrainingLoop(
  training: dataset.training,
  validation: dataset.validation,
  optimizer: optimizer,
  lossFunction: softmaxCrossEntropy,
  metrics: [.accuracy])

Vòng đào tạo giả định rằng tập dữ liệu bạn đang sử dụng tuân thủ API Epochs và cho phép bạn chỉ định phần tách nào trong tập dữ liệu sẽ sử dụng cho việc đào tạo và xác thực. Bất kỳ hàm mất nào cũng có thể được sử dụng sau khi được đặt vào một trình bao bọc tương thích, chẳng hạn như softmaxCrossEntropyđây .

Các số liệu hiện tại có thể được nắm bắt bao gồm:

  • loss
  • accuracy
  • top5Accuracy
  • matthewsCorrelationCoefficient
  • perplexity

Cuối cùng, để thực hiện huấn luyện, bạn gọi lệnh sau:

try! trainingLoop.fit(&model, epochs: 10, on: device)

Điều này sẽ đào tạo mô hình trong 10 kỷ nguyên bằng cách sử dụng chương trình phụ trợ máy gia tốc mà chúng tôi đã chỉ định. Số liệu thống kê sẽ được hiển thị trong quá trình đào tạo trên bảng điều khiển bằng lời nhắc hoạt hình.

Cuộc gọi lại

Việc tùy chỉnh vòng đào tạo tổng quát này diễn ra thông qua việc sử dụng các lệnh gọi lại. Những lệnh gọi lại này có thể được nối vào nhiều điểm khác nhau trong vòng lặp.

Một số lệnh gọi lại tích hợp cung cấp chức năng có thể được thêm vào bất kỳ vòng đào tạo nào. Bao gồm các:

  • Ghi nhật ký số liệu thống kê vào tệp có giá trị được phân tách bằng dấu phẩy (CSV)
  • Điều chỉnh tốc độ học theo lịch tùy chỉnh
  • Theo dõi và vẽ biểu đồ tiến độ đào tạo qua TensorBoard

Ngoài những chức năng này, bạn có thể tạo lệnh gọi lại tùy chỉnh của riêng mình để thêm nhiều chức năng bổ sung vào vòng đào tạo tiêu chuẩn.

Ghi nhật ký CSV

Lớp CSVLogger gói gọn một lệnh gọi lại sẽ ghi số liệu thống kê đào tạo ở định dạng giá trị được phân tách bằng dấu phẩy vào tệp bạn chọn. Tệp này sẽ bắt đầu với các cột có nhãn epoch , batch và bất kỳ số liệu nào bạn đã bật trong vòng đào tạo của mình. Sau đó, một hàng sẽ được ghi cho mỗi lô, với các giá trị hiện tại của các cột đó.

Để thêm tính năng ghi nhật ký CSV vào vòng lặp đào tạo của bạn, hãy thêm nội dung như sau vào một loạt lệnh gọi lại được cung cấp cho callbacks: cho TrainingLoop của bạn:

try! CSVLogger(path: "file.csv").log

Ví dụ: mẫu LeNet-MNIST sử dụng điều này trong vòng đào tạo của nó.

Bảng tỷ lệ học tập

Điều phổ biến là khi đào tạo một mô hình để thay đổi tốc độ học tập được cung cấp cho trình tối ưu hóa trong quá trình đào tạo. Điều này có thể đơn giản như giảm tuyến tính theo thời gian hoặc phức tạp như chu kỳ khởi động và suy giảm được mô tả bằng các hàm phức tạp.

Lệnh gọi lại learningRateScheduler cung cấp phương tiện mô tả lịch trình tốc độ học tập bao gồm các phân đoạn khác nhau, mỗi phân đoạn có hình dạng riêng biệt. Điều này được thực hiện bằng cách xác định một LearningRateSchedule bao gồm ScheduleSegment mà mỗi cái có một Shape được xác định bởi một hàm, tốc độ học ban đầu và tốc độ học cuối cùng.

Ví dụ: mẫu BERT-CoLA sử dụng tốc độ học tập tăng tuyến tính trong giai đoạn khởi động và giảm tuyến tính sau đó. Để thực hiện điều này, lệnh gọi lại lịch trình tốc độ học tập được xác định như sau:

learningRateScheduler(
  schedule: makeSchedule(
    [
      ScheduleSegment(shape: linear, startRate: 0, endRate: peakLearningRate, stepCount: 10),
      ScheduleSegment(shape: linear, endRate: 0)
    ]
  )
)

Hai ScheduleSegment xác định tốc độ học bắt đầu từ 0 và tăng tuyến tính đến peakLearningRate qua chuỗi 10 bước riêng biệt, sau đó bắt đầu ở tốc độ học cuối cùng từ bước trước và giảm tuyến tính xuống 0 khi kết thúc quá trình đào tạo.

Tích hợp TensorBoard

TensorBoard là một công cụ trực quan mạnh mẽ để theo dõi quá trình đào tạo theo mô hình, phân tích quá trình đào tạo khi hoàn thành hoặc so sánh các lần đào tạo. Swift cho TensorFlow hỗ trợ trực quan hóa TensorBoard thông qua việc sử dụng mô-đun TensorBoard trong kho lưu trữ mô hình, cung cấp các lệnh gọi lại ghi nhật ký số liệu đào tạo.

Mẫu GPT2-WikiText2 minh họa cách thêm tính năng ghi nhật ký TensorBoard vào quá trình đào tạo mô hình của bạn. Đầu tiên, nhập mô-đun TensorBoard . Sau đó, việc này đơn giản như việc thêm tensorBoardStatisticsLogger() vào các lệnh gọi lại TrainingLoop của bạn callbacks: array.

Theo mặc định, thao tác này sẽ ghi lại từng lần chạy đào tạo trong thư mục run/tensorboard/stats . Để xem cái này trong Tensorboard, hãy chạy

tensorboard --logdir ./run/tensorboard/stats

và TensorBoard sẽ khởi động một máy chủ cục bộ nơi bạn có thể xem số liệu đào tạo của mình. Kết quả đào tạo và xác nhận phải được hiển thị riêng biệt và mỗi lần chạy có dấu thời gian duy nhất để cho phép dễ dàng so sánh giữa nhiều lần chạy của cùng một mô hình.

Thiết kế của Swift dành cho tích hợp TensorFlow TensorBoard được lấy cảm hứng từ tensorboardX . Lệnh gọi lại TensorBoard trực tiếp tạo vùng đệm giao thức tóm tắt và sự kiện thích hợp, đồng thời ghi chúng vào tệp nhật ký trong quá trình đào tạo.

Cuộc gọi lại tùy chỉnh

Ngoài các lệnh gọi lại tích hợp được mô tả ở trên, bạn có khả năng tùy chỉnh chức năng của vòng lặp đào tạo bằng cách tạo các lệnh gọi lại của riêng bạn. Các lệnh gọi lại này là các hàm có chữ ký tương tự như sau:

func customCallback<L: TrainingLoopProtocol>(_ loop: inout L, event: TrainingLoopEvent) throws
{
  if event == .updateStart {
    ...
  }
}

Vòng huấn luyện và trạng thái liên quan được truyền vào dưới dạng tham số đầu tiên. Phần hiện tại của vòng lặp mà lệnh gọi lại đang phản hồi được cung cấp thông qua event . Sự kiện vòng lặp huấn luyện có một trong các trạng thái sau, mỗi trạng thái tương ứng với một điểm khác nhau trong vòng đời của vòng lặp:

  • fitStart
  • fitEnd
  • epochStart
  • epochEnd
  • trainingStart
  • trainingEnd
  • validationStart
  • validationEnd
  • batchStart
  • batchEnd
  • updateStart
  • inferencePredictionEnd

Hàm gọi lại của bạn có thể chọn kích hoạt logic của nó trên bất kỳ sự kết hợp nào của các trạng thái trên, điều này cho phép trích xuất dữ liệu từ hoặc kiểm soát vòng lặp đào tạo theo nhiều cách.