Vertex AI: Tinh chỉnh siêu tham số

1. Tổng quan

Trong phòng thí nghiệm này, bạn sẽ sử dụng AI Vertex để chạy công việc điều chỉnh siêu tham số cho mô hình TensorFlow. Mặc dù phòng thí nghiệm này sử dụng TensorFlow cho mã mô hình, nhưng các khái niệm này cũng áp dụng được cho các khung máy học khác.

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 để điều chỉnh siêu tham số tự động
  • Định cấu hình và chạy một công việc điều chỉnh siêu thông số trên giao diện người dùng Vertex AI
  • Định cấu hình và khởi chạy công việc điều chỉnh siêu thông số bằng SDK Python của Vertex AI

Tổng chi phí để chạy phòng thí nghiệm này trên Google Cloud là khoảng 3 USD.

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

Phòng thí nghiệm này sử dụng sản phẩm AI mới nhất có trên Google Cloud. Vertex AI tích hợp các giải pháp học máy trên Google Cloud vào 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à mô hình tuỳ chỉnh có thể truy cập được thông qua các dịch vụ riêng biệt. Dịch vụ mới 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. Nếu bạn có ý kiến phản hồi, vui lòng xem trang hỗ trợ.

Vertex AI có nhiều sản phẩm nhằm hỗ trợ quy trình học máy toàn diện. Phòng thí nghiệm này sẽ tập trung vào các sản phẩm được làm nổi bật dưới đây: Đào tạoBàn làm việc.

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

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

Bạn cần một dự án Google Cloud Platform đã bật tính năng thanh toán để chạy lớp học lập trình này. Để tạo một dự án, hãy làm theo hướng dẫn tại đây.

Bước 1: Bật Compute Engine API

Chuyển đến Compute Engine rồi chọn Enable (Bật) nếu bạn chưa bật tính năng này. Bạn sẽ cần có gói này để tạo thực thể sổ tay.

Bước 2: Bật Container Registry API

Chuyển đến Sổ đăng ký vùng chứa và chọn Bật nếu bạn chưa chọn. Bạn sẽ dùng mã này để tạo một vùng chứa cho công việc huấn luyện tuỳ chỉnh.

Bước 3: Bật Vertex AI API

Chuyển đến phần Vertex AI trong Cloud Console rồi nhấp vào Bật Vertex AI API.

Trang tổng quan Vertex AI

Bước 4: Tạo một thực thể Vertex AI Workbench

Trong mục Vertex AI trên Cloud Console, hãy nhấp vào Workbench:

Trình đơn Vertex AI

Bật API Notebooks nếu chưa bật.

Notebook_api

Sau khi bật, hãy nhấp vào SÁCH QUẢN LÝ SÁCH:

Notebooks_UI

Sau đó, chọn SÁCH LƯU Ý MỚI.

new_notebook

Đặt tên cho sổ tay của bạn, sau đó nhấp vào Cài đặt nâng cao.

create_notebook

Trong phần Advanced Settings (Cài đặt nâng cao), hãy bật chế độ tắt ở trạng thái rảnh và đặt số phút là 60 phút. Điều này có nghĩa là sổ tay của bạn sẽ tự động tắt khi không được sử dụng, do đó bạn không phải chịu các chi phí không cần thiết.

idle_timeout

Trong phần Bảo mật, chọn "Bật thiết bị đầu cuối" nếu chưa được bật.

enable_terminal

Bạn có thể giữ nguyên mọi chế độ cài đặt nâng cao khác.

Tiếp theo, hãy nhấp vào Tạo. Quá trình cung cấp thực thể này sẽ mất vài phút.

Sau khi tạo phiên bản, hãy chọn Open JupyterLab.

open_jupyterlab

Vào lần đầu tiên sử dụng một phiên bản mới, bạn sẽ được yêu cầu xác thực. Hãy làm theo các bước trong giao diện người dùng để thực hiện việc này.

xác thực

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

Mô hình mà bạn sẽ huấn luyện và điều chỉnh trong phòng thí nghiệm này là một mô hình phân loại hình ảnh được huấn luyện dựa trên tập dữ liệu ngựa hoặc người từ Tập dữ liệu TensorFlow.

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

Để bắt đầu, trên trình đơn Trình chạy, hãy mở cửa sổ dòng lệnh trong thực thể sổ tay của bạn:

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

Tạo một thư mục mới có tên là horses_or_humans và cd vào thư mục đó:

mkdir horses_or_humans
cd horses_or_humans

Bước 1: Tạo một Dockerfile

Bước đầu tiên trong việc chứa mã là tạo Dockerfile. Trong Dockerfile, bạn sẽ thêm tất cả các lệnh cần thiết để chạy hình ảnh. Thao tác này sẽ cài đặt tất cả các thư viện cần thiết, bao gồm cả thư viện CloudML Hypertune, và thiết lập điểm truy cập cho mã huấn luyện.

Trên Terminal, hãy tạo một Dockerfile trống:

touch Dockerfile

Mở Dockerfile và sao chép nội dung sau đây vào đó:

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

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"]

Dockerfile này sử dụng hình ảnh Docker GPU cho TensorFlow Enterprise 2.7 của Deep Learning Container. Các vùng chứa học sâu trên Google Cloud được cài đặt sẵn nhiều khung phổ biến của công nghệ học máy và khoa học dữ liệu. Sau khi tải hình ảnh đó xuống, Dockerfile này sẽ thiết lập điểm nhập cho mã huấn luyện. Bạn chưa tạo các tệp này – trong bước tiếp theo, bạn sẽ thêm mã để huấn luyện và điều chỉnh mô hình.

Bước 2: Thêm mã huấn luyện mô hình

Trên cửa sổ dòng lệnh, hãy chạy lệnh sau để tạo thư mục cho mã huấn luyện và một tệp Python nơi bạn sẽ thêm mã:

mkdir trainer
touch trainer/task.py

Bây giờ, bạn sẽ có những nội dung sau trong thư mục horses_or_humans/:

+ Dockerfile
+ trainer/
    + task.py

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

import tensorflow as tf
import tensorflow_datasets as tfds
import argparse
import hypertune

NUM_EPOCHS = 10


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 preprocess_data(image, label):
  '''Resizes and scales images.'''

  image = tf.image.resize(image, (150,150))
  return tf.cast(image, tf.float32) / 255., label


def create_dataset():
  '''Loads Horses Or Humans dataset and preprocesses data.'''

  data, info = tfds.load(name='horses_or_humans', as_supervised=True, with_info=True)

  # Create train dataset
  train_data = data['train'].map(preprocess_data)
  train_data  = train_data.shuffle(1000)
  train_data  = train_data.batch(64)

  # Create validation dataset
  validation_data = data['test'].map(preprocess_data)
  validation_data  = validation_data.batch(64)

  return train_data, validation_data


def create_model(num_units, learning_rate, momentum):
  '''Defines and compiles model.'''

  inputs = tf.keras.Input(shape=(150, 150, 3))
  x = tf.keras.layers.Conv2D(16, (3, 3), activation='relu')(inputs)
  x = tf.keras.layers.MaxPooling2D((2, 2))(x)
  x = tf.keras.layers.Conv2D(32, (3, 3), activation='relu')(x)
  x = tf.keras.layers.MaxPooling2D((2, 2))(x)
  x = tf.keras.layers.Conv2D(64, (3, 3), activation='relu')(x)
  x = tf.keras.layers.MaxPooling2D((2, 2))(x)
  x = tf.keras.layers.Flatten()(x)
  x = tf.keras.layers.Dense(num_units, activation='relu')(x)
  outputs = tf.keras.layers.Dense(1, activation='sigmoid')(x)
  model = tf.keras.Model(inputs, outputs)
  model.compile(
      loss='binary_crossentropy',
      optimizer=tf.keras.optimizers.SGD(learning_rate=learning_rate, momentum=momentum),
      metrics=['accuracy'])
  return model


def main():
  args = get_args()
  train_data, validation_data = create_dataset()
  model = create_model(args.num_units, args.learning_rate, args.momentum)
  history = model.fit(train_data, epochs=NUM_EPOCHS, validation_data=validation_data)

  # 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=NUM_EPOCHS)


if __name__ == "__main__":
    main()

Trước khi tạo vùng chứa, hãy xem xét kỹ hơn về mã. Có một vài 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 này nhập thư viện hypertune. Lưu ý rằng Dockerfile ở Bước 1 đã bao gồm các hướng dẫn để cài đặt thư viện này.
  2. Hàm get_args() xác định một đối số dòng lệnh cho mỗi 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 vui lòng thử nghiệm với các đơn vị khác. Sau đó, giá trị được truyền vào các đối số đó sẽ đượ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 model.fit của keras trả về một đối tượng History. Thuộc tính History.history là một bản ghi gồm các giá trị chỉ số và giá trị tổn thất huấn luyện trong các khoảng thời gian bắt đầu của hệ thống liên tiếp. Nếu bạn chuyển dữ liệu xác thực đến model.fit, thuộc tính History.history cũng sẽ bao gồm tổn thất xác thực và các giá trị chỉ số. Ví dụ: nếu bạn đã huấn luyện một mô hình cho 3 khoảng thời gian bắt đầu của hệ thống 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ẽ có dạng như trong 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 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, bạn cần 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 mình thích cho hyperparameter_metric_tag, nhưng 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 3: Tạo vùng chứa

Trên cửa sổ dòng lệnh, hãy chạy lệnh sau để xác định một biến env cho dự án của bạn, nhớ thay thế your-cloud-project bằng mã dự án của bạn:

PROJECT_ID='your-cloud-project'

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

IMAGE_URI="gcr.io/$PROJECT_ID/horse-human:hypertune"

Định cấu hình Docker

gcloud auth configure-docker

Sau đó, hãy tạo vùng chứa bằng cách chạy lệnh sau từ gốc của thư mục horses_or_humans:

docker build ./ -t $IMAGE_URI

Cuối cùng, hãy đẩy địa chỉ email này đến Google Container Registry:

docker push $IMAGE_URI

Với vùng chứa được đẩy vào Sổ đăng ký vùng chứa, giờ đây bạn đã sẵn sàng bắt đầu công việc điều chỉnh siêu tham số mô hình tùy chỉnh.

5. Chạy lệnh điều chỉnh siêu tham số trên Vertex AI

Phòng thí nghiệm này sử dụng chương trình huấn luyện tuỳ chỉnh thông qua một vùng chứa tuỳ chỉnh trên Google Container Registry, nhưng bạn cũng có thể chạy công việc điều chỉnh siêu thông số bằng vùng chứa tạo sẵn của Vertex AI.

Để bắt đầu, hãy chuyển đến phần Đào tạo trong phần Vertex của Cloud Console:

Trình đơn uCAIP

Bước 1: Thiết lập công việc huấn luyện

Nhấp vào Tạo để nhập thông số cho công việc điều chỉnh siêu tham số của bạn.

  • Trong mục Tập dữ liệu, hãy chọn Không có tập dữ liệu được quản lý
  • Sau đó, hãy chọn Đào tạo tuỳ chỉnh (nâng cao) làm phương pháp đào tạo của bạn rồi nhấp vào Tiếp tục.
  • Nhập horses-humans-hyptertune (hoặc bất kỳ tên nào mà bạn muốn gọi cho mô hình của mình) cho Tên mô hình
  • Nhấp vào Tiếp tục

Trong bước Cài đặt vùng chứa, hãy chọn Vùng chứa tuỳ chỉnh:

Lựa chọn về vùng chứa tuỳ chỉnh

Trong hộp đầu tiên (Hình ảnh vùng chứa), hãy nhập giá trị của biến IMAGE_URI từ mục trước đó. Thuộc tính này phải là: gcr.io/your-cloud-project/horse-human:hypertune, với tên dự án của riêng bạn. Để trống các trường còn lại, rồi nhấp vào Tiếp tục.

Bước 2: Định cấu hình công việc điều chỉnh siêu thông số

Chọn Bật tính năng điều chỉnh siêu thông số.

Siêu tham số

Định cấu hình siêu tham số

Tiếp theo, bạn cần thêm các siêu tham số mà bạn đặt làm đối số dòng lệnh vào mã xử lý ứng dụng huấn luyện. Khi thêm một siêu tham số, trước tiên bạn cần cung cấp tên. Tên này phải khớp với tên đối số mà bạn đã truyền vào argparse.

learning_rate_name

Sau đó, bạn chọn Loại cũng như các giới hạn cho các giá trị mà dịch vụ điều chỉnh sẽ thử. 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. Nếu chọn Phân loại hoặc Rời rạc, bạn cần cung cấp các giá trị.

learning_rate_typelearning_rate_name

Đối với các loại Số nguyên và Kép, bạn cũng cần cung cấp giá trị Tỷ lệ.

learning_rate_scale

Sau khi thêm siêu tham số learning_rate, hãy thêm các tham số cho momentumnum_units.

momentum_config

numneruons_config

Định cấu hình chỉ số

Sau khi thêm siêu tham số, tiếp theo bạn sẽ cung cấp chỉ số bạn muốn tối ưu hoá cũng như mục tiêu. Giá trị này phải giống với hyperparameter_metric_tag mà bạn đặt trong ứng dụng huấn luyện.

metric_config

Dịch vụ điều chỉnh Siêu thông số Vertex AI sẽ chạy nhiều phiên bản thử của ứng dụng huấn luyện bằng các giá trị được định cấu hình ở các bước trước. Bạn sẽ cần đặt giới hạn trên về số lượt dùng thử mà dịch vụ sẽ chạy. Nhiều thử nghiệm hơn thường dẫn đến kết quả tốt hơn, nhưng sẽ có điểm giảm dần lợi nhuận. Sau đó, các thử nghiệm bổ sung 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 số lượng phiên bản thử nhỏ hơn và nắm được tác động của siêu tham số đã chọn trước khi mở rộng quy mô thử nghiệm.

Bạn cũng cần đặt giới hạn trên cho số lượt thử song song. Việc tăng số lượng phiên bản thử song song sẽ làm giảm khoảng thời gian cần thiết để chạy công việc điều chỉnh siêu tham số; tuy nhiên, nó có thể làm giảm hiệu quả của công việc nói chung. Điều này là do chiến lược điều chỉnh mặc định sử dụng kết quả của các lần thử trước để thông báo việc chỉ định giá trị trong các lần thử tiếp theo. Nếu bạn chạy quá nhiều phiên bản thử song song, sẽ có các phiên bản thử bắt đầu mà không thu được lợi ích từ kết quả của các phiên bản thử vẫn đang chạy.

Để minh hoạ, bạn có thể đặt số lượt thử là 15 và số lượt thử song song tối đa là 3. Bạn có thể thử nghiệm với các số khác nhau, nhưng điều này có thể dẫn đến thời gian điều chỉnh lâu hơn và chi phí cao hơn.

trial_config

Bước cuối cùng là chọn Mặc định làm thuật toán tìm kiếm. Thuật toán này sẽ sử dụng Google Vizier để thực hiện tối ưu hoá Bayes cho việc tinh chỉnh siêu tham số. Bạn có thể tìm hiểu thêm về thuật toán này tại đây.

algorithm_config

Nhấp vào Tiếp tục.

Bước 3: Định cấu hình điện toán

Trong phần Tính toán và định giá, hãy giữ nguyên khu vực đã chọn và định cấu hình Nhóm nhân viên 0 như sau.

Loại máy

Nhấp vào Bắt đầu huấn luyện để bắt đầu công việc điều chỉnh siêu tham số. Trong phần Đào tạo trên bảng điều khiển của bạn, bên dưới thẻ HYPERParameters TUNING JOBS, bạn sẽ thấy các lệnh như sau:

Công việc trong siêu thông số

Khi hoàn tất, bạn có thể nhấp vào tên công việc và xem kết quả thử nghiệm điều chỉnh.

Đầu ra siêu tham số

🎉 Xin chúc mừng! 🎉

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

  • Triển khai một công việc điều chỉnh siêu tham số cho mã huấn luyện được cung cấp trong một vùng chứa tuỳ chỉnh. Bạn đã sử dụng một mô hình TensorFlow trong ví dụ này, nhưng bạn có thể huấn luyện một mô hình được xây dựng với bất kỳ khung nào bằng cách sử dụng các vùng chứa tuỳ chỉnh.

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

6. [Không bắt buộc] Sử dụng Vertex SDK

Phần trước đã trình bày cách khởi chạy công việc điều chỉnh siêu tham số qua giao diện người dùng. Trong phần này, bạn sẽ thấy một cách khác để gửi công việc điều chỉnh siêu tham số là sử dụ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

Để khởi chạy công việc điều chỉnh siêu thông số, trước tiên, bạn cần xác định các thông số sau. 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": "gcr.io/{PROJECT_ID}/horse-human:hypertune"
    }
}]


# Dictionary representing metrics 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'}

# 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)
}

Tiếp theo, hãy tạo một CustomJob. Bạn cần thay thế {YOUR_BUCKET} bằng một bộ chứa trong dự án để chạy thử.

# Replace YOUR_BUCKET
my_custom_job = aiplatform.CustomJob(display_name='horses-humans-sdk-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='horses-humans-sdk-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()

7. Dọn dẹp

Vì đã định cấu hình sổ tay hết thời gian chờ sau 60 phút ở trạng thái rảnh, nên chúng ta không cần phải lo lắng về việc tắt thực thể. Nếu bạn 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 thực thể

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

Xoá bộ nhớ