Nguyên mẫu cho sản xuất: Điều chỉnh siêu tham số

1. Tổng quan

Trong bài tập thực hành này, bạn sẽ sử dụng Vertex AI để chạy một công việc điều chỉnh siêu tham số trên Vertex AI Training.

Bài tập thực hành này là một phần trong loạt video Từ nguyên mẫu đến vận hành thực tế. Hãy nhớ hoàn thành bài tập thực hành trước đó trước khi thử bài tập thực hành này. Bạn có thể xem loạt video đi kèm để tìm hiểu thêm:

.

Kiến thức bạn sẽ học được

Bạn sẽ tìm hiểu cách:

  • Sửa đổi mã xử lý ứng dụng huấn luyện để tự động điều chỉnh siêu tham số
  • Định cấu hình và chạy một công việc điều chỉnh siêu tham số bằng Vertex AI Python SDK

Tổng chi phí để chạy bài tập thực hành này trên Google Cloud là khoảng 1 USD.

2. Giới thiệu về Vertex AI

Bài tập thực hành này sử dụng sản phẩm AI mới nhất hiện có trên Google Cloud. Vertex AI tích hợp các sản phẩm học máy trên Google Cloud thành một trải nghiệm phát triển liền mạch. Trước đây, các mô hình được huấn luyện bằng AutoML và các mô hình tuỳ chỉnh có thể truy cập thông qua các dịch vụ riêng biệt. Sản phẩm mới này kết hợp cả hai thành một API duy nhất, cùng với các sản phẩm mới khác. Bạn cũng có thể di chuyển các dự án hiện có sang Vertex AI.

Vertex AI bao gồm nhiều sản phẩm khác nhau để hỗ trợ quy trình học máy đầu cuối. Bài tập thực hành này sẽ tập trung vào các sản phẩm được nêu bật bên dưới: Training (Huấn luyện) và Workbench (Bàn làm việc)

Tổng quan về sản phẩm Vertex

3. Thiết lập môi trường

Hoàn tất các bước trong bài tập thực hành Huấn luyện các mô hình tuỳ chỉnh bằng Vertex AI để thiết lập môi trường.

4. Vùng chứa hoá mã xử lý ứng dụng huấn luyện

Bạn sẽ gửi công việc huấn luyện này đến Vertex AI bằng cách đặt mã xử lý ứng dụng huấn luyện vào một vùng chứa Docker và đẩy vùng chứa này lên Google Artifact Registry. Bằng cách sử dụng phương pháp này, bạn có thể huấn luyện và điều chỉnh một mô hình được xây dựng bằng bất kỳ khung nào.

Để bắt đầu, trong trình đơn Trình chạy của sổ tay Workbench mà bạn đã tạo trong các bài tập thực hành trước, hãy mở một cửa sổ dòng lệnh.

Mở cửa sổ lệnh trong sổ tay

Bước 1: Viết mã huấn luyện

Tạo một thư mục mới có tên là flowers-hptune rồi chuyển sang thư mục đó:

mkdir flowers-hptune
cd flowers-hptune

Chạy lệnh sau để tạo một thư mục cho mã huấn luyện và một tệp Python nơi bạn sẽ thêm mã bên dưới.

mkdir trainer
touch trainer/task.py

Bây giờ, bạn sẽ có nội dung sau trong thư mục flowers-hptune/:

+ trainer/
    + task.py

Tiếp theo, hãy mở tệp task.py mà bạn vừa tạo rồi sao chép mã bên dưới.

Bạn cần thay thế {your-gcs-bucket} trong BUCKET_ROOT bằng bộ chứa Cloud Storage nơi bạn đã lưu trữ tập dữ liệu hoa trong Bài tập thực hành 1.

import tensorflow as tf
import numpy as np
import os
import hypertune
import argparse

## Replace {your-gcs-bucket} !!
BUCKET_ROOT='/gcs/{your-gcs-bucket}'

# Define variables
NUM_CLASSES = 5
EPOCHS=10
BATCH_SIZE = 32

IMG_HEIGHT = 180
IMG_WIDTH = 180

DATA_DIR = f'{BUCKET_ROOT}/flower_photos'

def get_args():
  '''Parses args. Must include all hyperparameters you want to tune.'''

  parser = argparse.ArgumentParser()
  parser.add_argument(
      '--learning_rate',
      required=True,
      type=float,
      help='learning rate')
  parser.add_argument(
      '--momentum',
      required=True,
      type=float,
      help='SGD momentum value')
  parser.add_argument(
      '--num_units',
      required=True,
      type=int,
      help='number of units in last hidden layer')
  args = parser.parse_args()
  return args

def create_datasets(data_dir, batch_size):
  '''Creates train and validation datasets.'''

  train_dataset = tf.keras.utils.image_dataset_from_directory(
    data_dir,
    validation_split=0.2,
    subset="training",
    seed=123,
    image_size=(IMG_HEIGHT, IMG_WIDTH),
    batch_size=batch_size)

  validation_dataset = tf.keras.utils.image_dataset_from_directory(
    data_dir,
    validation_split=0.2,
    subset="validation",
    seed=123,
    image_size=(IMG_HEIGHT, IMG_WIDTH),
    batch_size=batch_size)

  train_dataset = train_dataset.cache().shuffle(1000).prefetch(buffer_size=tf.data.AUTOTUNE)
  validation_dataset = validation_dataset.cache().prefetch(buffer_size=tf.data.AUTOTUNE)

  return train_dataset, validation_dataset


def create_model(num_units, learning_rate, momentum):
  '''Creates model.'''

  model = tf.keras.Sequential([
    tf.keras.layers.Resizing(IMG_HEIGHT, IMG_WIDTH),
    tf.keras.layers.Rescaling(1./255, input_shape=(IMG_HEIGHT, IMG_WIDTH, 3)),
    tf.keras.layers.Conv2D(16, 3, padding='same', activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Conv2D(32, 3, padding='same', activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Conv2D(64, 3, padding='same', activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(num_units, activation='relu'),
    tf.keras.layers.Dense(NUM_CLASSES, activation='softmax')
  ])

  model.compile(optimizer=tf.keras.optimizers.SGD(learning_rate=learning_rate, momentum=momentum),
              loss=tf.keras.losses.SparseCategoricalCrossentropy(),
              metrics=['accuracy'])
  
  return model

def main():
  args = get_args()
  train_dataset, validation_dataset = create_datasets(DATA_DIR, BATCH_SIZE)
  model = create_model(args.num_units, args.learning_rate, args.momentum)
  history = model.fit(train_dataset, validation_data=validation_dataset, epochs=EPOCHS)

  # DEFINE METRIC
  hp_metric = history.history['val_accuracy'][-1]

  hpt = hypertune.HyperTune()
  hpt.report_hyperparameter_tuning_metric(
      hyperparameter_metric_tag='accuracy',
      metric_value=hp_metric,
      global_step=EPOCHS)


if __name__ == "__main__":
    main()

Trước khi bạn xây dựng vùng chứa, hãy xem xét kỹ hơn về mã. Có một số thành phần dành riêng cho việc sử dụng dịch vụ điều chỉnh siêu tham số.

  1. Tập lệnh nhập thư viện hypertune.
  2. Hàm get_args() xác định một đối số dòng lệnh cho từng siêu tham số mà bạn muốn điều chỉnh. Trong ví dụ này, các siêu tham số sẽ được điều chỉnh là tốc độ học, giá trị động lượng trong trình tối ưu hoá và số lượng đơn vị trong lớp ẩn cuối cùng của mô hình, nhưng bạn có thể thoải mái thử nghiệm các siêu tham số khác. Giá trị được truyền trong các đối số đó sau đó được dùng để đặt siêu tham số tương ứng trong mã.
  3. Ở cuối hàm main(), thư viện hypertune được dùng để xác định chỉ số mà bạn muốn tối ưu hoá. Trong TensorFlow, phương thức keras model.fit trả về một đối tượng History. Thuộc tính History.history là một bản ghi các giá trị tổn thất huấn luyện và giá trị chỉ số ở các kỷ nguyên liên tiếp. Nếu bạn truyền dữ liệu xác thực đến model.fit, thì thuộc tính History.history cũng sẽ bao gồm tổn thất xác thực và giá trị chỉ số. Ví dụ: nếu bạn huấn luyện một mô hình trong 3 kỷ nguyên bằng dữ liệu xác thực và cung cấp accuracy làm chỉ số, thì thuộc tính History.history sẽ trông tương tự như từ điển sau.
{
 "accuracy": [
   0.7795261740684509,
   0.9471358060836792,
   0.9870933294296265
 ],
 "loss": [
   0.6340447664260864,
   0.16712145507335663,
   0.04546636343002319
 ],
 "val_accuracy": [
   0.3795261740684509,
   0.4471358060836792,
   0.4870933294296265
 ],
 "val_loss": [
   2.044623374938965,
   4.100203514099121,
   3.0728273391723633
 ]

Nếu bạn muốn dịch vụ điều chỉnh siêu tham số khám phá các giá trị giúp tối đa hoá độ chính xác xác thực của mô hình, thì bạn sẽ xác định chỉ số là mục nhập cuối cùng (hoặc NUM_EPOCS - 1) của danh sách val_accuracy. Sau đó, hãy truyền chỉ số này đến một thực thể của HyperTune. Bạn có thể chọn bất kỳ chuỗi nào bạn thích cho hyperparameter_metric_tag, nhưng bạn sẽ cần sử dụng lại chuỗi đó sau khi bắt đầu công việc điều chỉnh siêu tham số.

Bước 2: Tạo Dockerfile

Để vùng chứa hoá mã, bạn cần tạo một Dockerfile. Trong Dockerfile, bạn sẽ đưa vào tất cả các lệnh cần thiết để chạy hình ảnh. Lệnh này sẽ cài đặt tất cả các thư viện cần thiết và thiết lập điểm vào cho mã huấn luyện.

Trong Dòng lệnh, hãy tạo một Dockerfile trống trong thư mục gốc của flowers-hptune:

touch Dockerfile

Bây giờ, bạn sẽ có nội dung sau trong thư mục flowers-hptune/:

+ Dockerfile
+ trainer/
    + task.py

Mở Dockerfile rồi sao chép nội dung sau vào đó. Bạn sẽ nhận thấy rằng Dockerfile này gần giống với Dockerfile mà chúng ta đã sử dụng trong bài tập thực hành đầu tiên, ngoại trừ việc giờ đây chúng ta đang cài đặt thư viện cloudml-hypertune.

FROM gcr.io/deeplearning-platform-release/tf2-gpu.2-8

WORKDIR /

# Installs hypertune library
RUN pip install cloudml-hypertune

# Copies the trainer code to the docker image.
COPY trainer /trainer

# Sets up the entry point to invoke the trainer.
ENTRYPOINT ["python", "-m", "trainer.task"]

Bước 3: Xây dựng vùng chứa

Trong Dòng lệnh, hãy chạy lệnh sau để xác định một biến môi trường cho dự án của bạn, nhớ thay thế your-cloud-project bằng mã dự án:

PROJECT_ID='your-cloud-project'

Xác định một kho lưu trữ trong Artifact Registry. Chúng ta sẽ sử dụng kho lưu trữ mà chúng ta đã tạo trong bài tập thực hành đầu tiên.

REPO_NAME='flower-app'

Xác định một biến bằng URI của hình ảnh vùng chứa trong Google Artifact Registry:

IMAGE_URI=us-central1-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/flower_image_hptune:latest

Định cấu hình Docker

gcloud auth configure-docker \
    us-central1-docker.pkg.dev

Sau đó, hãy xây dựng vùng chứa bằng cách chạy lệnh sau từ thư mục gốc của flower-hptune:

docker build ./ -t $IMAGE_URI

Cuối cùng, hãy đẩy vùng chứa đó lên Artifact Registry:

docker push $IMAGE_URI

Sau khi đẩy vùng chứa lên Artifact Registry, bạn có thể bắt đầu công việc huấn luyện.

5. Chạy công việc điều chỉnh siêu tham số bằng SDK

Trong phần này, bạn sẽ tìm hiểu cách định cấu hình và gửi công việc điều chỉnh siêu tham số bằng Vertex Python API.

Trong Trình chạy, hãy tạo một sổ tay TensorFlow 2.

new_notebook

Nhập Vertex AI SDK.

from google.cloud import aiplatform
from google.cloud.aiplatform import hyperparameter_tuning as hpt

Để chạy công việc điều chỉnh siêu tham số, trước tiên, bạn cần xác định worker_pool_specs, trong đó chỉ định loại máy và hình ảnh Docker. Thông số kỹ thuật sau đây xác định một máy có 2 GPU NVIDIA Tesla V100.

Bạn cần thay thế {PROJECT_ID} trong image_uri bằng dự án của mình.

# The spec of the worker pools including machine type and Docker image
# Be sure to replace PROJECT_ID in the `image_uri` with your project.

worker_pool_specs = [{
    "machine_spec": {
        "machine_type": "n1-standard-4",
        "accelerator_type": "NVIDIA_TESLA_V100",
        "accelerator_count": 1
    },
    "replica_count": 1,
    "container_spec": {
        "image_uri": "us-central1-docker.pkg.dev/{PROJECT_ID}/flower-app/flower_image_hptune:latest"
    }
}]

Tiếp theo, hãy xác định parameter_spec, đây là một từ điển chỉ định các tham số mà bạn muốn tối ưu hoá. Khoá từ điển là chuỗi mà bạn đã gán cho đối số dòng lệnh cho từng siêu tham số và giá trị từ điển là thông số kỹ thuật tham số.

Đối với mỗi siêu tham số, bạn cần xác định Loại cũng như ranh giới cho các giá trị mà dịch vụ điều chỉnh sẽ thử. Siêu tham số có thể thuộc loại Double, Integer, Categorical hoặc Discrete. Nếu chọn loại Double hoặc Integer, bạn cần cung cấp giá trị tối thiểu và tối đa. Và nếu chọn Categorical hoặc Discrete, bạn cần cung cấp các giá trị. Đối với các loại Double và Integer, bạn cũng cần cung cấp giá trị Tỷ lệ. Bạn có thể tìm hiểu thêm về cách chọn tỷ lệ tốt nhất trong video này.

# Dictionary representing parameters to optimize.
# The dictionary key is the parameter_id, which is passed into your training
# job as a command line argument,
# And the dictionary value is the parameter specification of the metric.
parameter_spec = {
    "learning_rate": hpt.DoubleParameterSpec(min=0.001, max=1, scale="log"),
    "momentum": hpt.DoubleParameterSpec(min=0, max=1, scale="linear"),
    "num_units": hpt.DiscreteParameterSpec(values=[64, 128, 512], scale=None)
}

Thông số kỹ thuật cuối cùng cần xác định là metric_spec, đây là một từ điển đại diện cho chỉ số cần tối ưu hoá. Khoá từ điển là hyperparameter_metric_tag mà bạn đặt trong mã xử lý ứng dụng huấn luyện và giá trị là mục tiêu tối ưu hoá.

# Dictionary representing metric to optimize.
# The dictionary key is the metric_id, which is reported by your training job,
# And the dictionary value is the optimization goal of the metric.
metric_spec={'accuracy':'maximize'}

Sau khi xác định các thông số kỹ thuật, bạn sẽ tạo một CustomJob. Đây là thông số kỹ thuật chung sẽ được dùng để chạy công việc trên mỗi thử nghiệm điều chỉnh siêu tham số.

Bạn cần thay thế {YOUR_BUCKET} bằng bộ chứa mà bạn đã tạo trước đó.

# Replace YOUR_BUCKET
my_custom_job = aiplatform.CustomJob(display_name='flowers-hptune-job',
                              worker_pool_specs=worker_pool_specs,
                              staging_bucket='gs://{YOUR_BUCKET}')

Sau đó, hãy tạo và chạy HyperparameterTuningJob.

hp_job = aiplatform.HyperparameterTuningJob(
    display_name='flowers-hptune-job',
    custom_job=my_custom_job,
    metric_spec=metric_spec,
    parameter_spec=parameter_spec,
    max_trial_count=15,
    parallel_trial_count=3)

hp_job.run()

Có một vài đối số cần lưu ý:

  • max_trial_count: Bạn cần đặt một giới hạn trên cho số lượng thử nghiệm mà dịch vụ sẽ chạy. Nhiều thử nghiệm thường dẫn đến kết quả tốt hơn, nhưng sẽ có một điểm lợi nhuận giảm dần, sau đó các thử nghiệm bổ sung sẽ có ít hoặc không ảnh hưởng đến chỉ số mà bạn đang cố gắng tối ưu hoá. Bạn nên bắt đầu với một số lượng thử nghiệm nhỏ hơn và cảm nhận được mức độ ảnh hưởng của các siêu tham số đã chọn trước khi tăng quy mô.
  • parallel_trial_count: Nếu bạn sử dụng các thử nghiệm song song, dịch vụ sẽ cung cấp nhiều cụm xử lý huấn luyện. Việc tăng số lượng thử nghiệm song song sẽ làm giảm thời gian chạy công việc điều chỉnh siêu tham số; tuy nhiên, điều này có thể làm giảm hiệu quả tổng thể của công việc. Lý do là vì chiến lược điều chỉnh mặc định sử dụng kết quả của các thử nghiệm trước đó để thông báo việc gán giá trị trong các thử nghiệm tiếp theo.
  • search_algorithm: Bạn có thể đặt thuật toán tìm kiếm thành lưới, ngẫu nhiên hoặc mặc định (Không có). Tuỳ chọn mặc định áp dụng phương pháp tối ưu hoá Bayesian để tìm kiếm không gian các giá trị siêu tham số có thể và là thuật toán được đề xuất. Bạn có thể tìm hiểu thêm về thuật toán này tại đây.

Trong bảng điều khiển, bạn có thể thấy tiến trình của công việc.

hp_job

Và khi hoàn tất, bạn có thể xem kết quả của mỗi lần thử nghiệm và tập hợp giá trị nào hoạt động tốt nhất.

hp_results

🎉 Xin chúc mừng! 🎉

Bạn đã tìm hiểu cách sử dụng Vertex AI để:

  • Chạy một công việc điều chỉnh siêu tham số tự động

Để tìm hiểu thêm về các phần khác nhau của Vertex, hãy xem tài liệu.

6. Dọn dẹp

Vì chúng tôi đã định cấu hình sổ tay để hết thời gian chờ sau 60 phút không hoạt động, nên chúng tôi không cần lo lắng về việc tắt thực thể. Nếu muốn tắt thực thể theo cách thủ công, hãy nhấp vào nút Dừng trên phần Vertex AI Workbench của bảng điều khiển. Nếu bạn muốn xoá hoàn toàn sổ tay, hãy nhấp vào nút Xoá.

Dừng phiên bản

Để xoá vùng chứa bộ nhớ, hãy sử dụng trình đơn Điều hướng trong Cloud Console, duyệt đến Bộ nhớ, chọn vùng chứa của bạn rồi nhấp vào Xoá:

Xoá bộ nhớ