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

1. Tổng quan

Trong phòng thí nghiệm này, bạn sẽ sử dụng Vertex AI để chạy công việc điều chỉnh siêu tham số trong Vertex AI Training.

Phòng thí nghiệm này nằm trong loạt video Nguyên mẫu để phát hành công khai. Hãy nhớ hoàn tất lớp học lập trình trước trước khi dùng thử bài tập 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 để điều chỉnh siêu tham số tự động
  • Đị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 1 đô la.

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.

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

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

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

Bạn sẽ gửi công việc đào tạo này cho Vertex AI bằng cách đặt mã ứng dụng huấn luyện của mình vào vùng chứa Docker và đẩy vùng chứa này vào Google Artifact Registry. Khi 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, từ trình đơn Trình chạy của sổ tay Workbench mà bạn đã tạo trong các phòng thí nghiệm trước, hãy mở một cửa sổ dòng lệnh.

Mở cửa sổ dòng 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 và cd vào thư mục đó:

mkdir flowers-hptune
cd flowers-hptune

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ã bên dưới.

mkdir trainer
touch trainer/task.py

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

+ 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.

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 Phòng thí nghiệm 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 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.
  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 thông 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 2: Tạo một Dockerfile

Để chứa mã, bạn cần tạo một Dockerfile. Trong Dockerfile, bạn sẽ thêm tất cả các lệnh cần thiết để chạy hình ảnh. Thư viện này sẽ cài đặt tất cả thư viện cần thiết 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 trong thư mục gốc của thư mục flowers-hptune:

touch Dockerfile

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

+ Dockerfile
+ trainer/
    + task.py

Mở Dockerfile và sao chép nội dung sau đây vào đó. Bạn sẽ nhận thấy rằng thao tác này gần giống với Dockerfile mà chúng ta đã sử dụng trong phòng thí nghiệm đầu tiên, ngoại trừ bây giờ 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: 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 kho lưu trữ trong Artifact Registry. Chúng ta sẽ sử dụng kho lưu trữ đã tạo trong phòng thí nghiệm đầ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 của bạn 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 tạo vùng chứa bằng cách chạy lệnh sau từ gốc của thư mục flower-hptune:

docker build ./ -t $IMAGE_URI

Cuối cùng, đẩy tệp này vào Artifact Registry:

docker push $IMAGE_URI

Với vùng chứa được đẩy vào Artifact Registry, giờ đây bạn đã sẵn sàng bắt đầu công việc đào tạo.

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 cách 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

Để 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. Lớp này sẽ 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ó hai 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à 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 bạn đã chỉ định cho đối số dòng lệnh cho mỗi siêu tham số và giá trị từ điển là thông số kỹ thuật của tham số.

Đối với mỗi siêu tham số, bạn cần xác định 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ử. Siêu tham số có thể thuộc loại Kép, Số nguyên, Phân loại hoặc Rời rạc. 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ị. Đố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ệ. Bạn có thể tìm hiểu thêm về cách chọn thang đo phù hợp 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, là 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ố phổ biến dùng để chạy công việc của bạn trong mỗi lần thử đ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 số đối số cần lưu ý:

  • max_trial_count: 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 lợi nhuận giảm dầ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 nhỏ thử nghiệm và tìm hiểu tác động của siêu tham số đã chọn trước khi mở rộng quy mô.
  • parallel_trial_count: Nếu bạn sử dụng bản dùng thử 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 phiên bản thử song song sẽ giúp giảm thời gian thực hiện công việc điều chỉnh siêu tham số cần thiết; 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.
  • 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ó). Lựa chọn mặc định áp dụng phương pháp tối ưu hoá Bayes để tìm kiếm không gian của các giá trị siêu tham số có thể có 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ể xem tiến trình công việc của mình.

hp_job

Sau khi hoàn tất, bạn có thể xem kết quả của từng thử nghiệm và nhóm giá trị nào hoạt động hiệu quả nhất.

hp_results

🎉 Xin chúc mừng! 🎉

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

  • Chạy 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 này.

6. 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ớ