Vertex AI: 초매개변수 조정

1. 개요

이 실습에서는 Vertex AI를 사용하여 TensorFlow 모델의 초매개변수 조정 작업을 실행합니다. 이 실습에서는 모델 코드에 TensorFlow를 사용하지만 다른 ML 프레임워크에도 개념이 적용됩니다.

학습 내용

다음 작업을 수행하는 방법을 배우게 됩니다.

  • 자동화된 초매개변수 미세 조정을 위한 학습 애플리케이션 코드 수정
  • Vertex AI UI에서 초매개변수 조정 작업 구성 및 시작
  • Vertex AI Python SDK로 초매개변수 조정 작업을 구성하고 실행합니다.

Google Cloud에서 이 실습을 진행하는 데 드는 총 비용은 약 $3(USD)입니다.

2 Vertex AI 소개

이 실습에서는 Google Cloud에서 제공되는 최신 AI 제품을 사용합니다. Vertex AI는 Google Cloud 전반의 ML 제품을 원활한 개발 환경으로 통합합니다. 이전에는 AutoML로 학습된 모델과 커스텀 모델은 별도의 서비스를 통해 액세스할 수 있었습니다. 새 서비스는 다른 신제품과 함께 두 가지 모두를 단일 API로 결합합니다. 기존 프로젝트를 Vertex AI로 마이그레이션할 수도 있습니다. 피드백이 있는 경우 지원 페이지를 참조하세요.

Vertex AI에는 엔드 투 엔드 ML 워크플로를 지원하는 다양한 제품이 포함되어 있습니다. 이 실습에서는 학습Workbench와 같이 아래에 강조표시된 제품에 중점을 둡니다.

Vertex 제품 개요

3. 환경 설정

이 Codelab을 실행하려면 결제가 사용 설정된 Google Cloud Platform 프로젝트가 필요합니다. 프로젝트를 만들려면 여기의 안내를 따르세요.

1단계: Compute Engine API 사용 설정

Compute Engine으로 이동하고 아직 사용 설정되지 않았다면 사용 설정을 선택합니다. 노트북 인스턴스를 만드는 데 필요합니다.

2단계: Container Registry API 사용 설정

Container Registry로 이동하여 아직 사용 설정되지 않은 경우 사용 설정을 선택합니다. 이를 사용하여 커스텀 학습 작업을 위한 컨테이너를 만들 수 있습니다.

3단계: Vertex AI API 사용 설정

Cloud Console의 Vertex AI 섹션으로 이동하고 Vertex AI API 사용 설정을 클릭합니다.

Vertex AI 대시보드

4단계: Vertex AI Workbench 인스턴스 만들기

Cloud Console의 Vertex AI 섹션에서 Workbench를 클릭합니다.

Vertex AI 메뉴

Notebooks API를 아직 사용 설정하지 않은 경우 사용 설정합니다.

노트북_API

사용 설정한 후 노트북 관리를 클릭합니다.

노트북_UI

그런 다음 새 노트북을 선택합니다.

새 노트북

노트북 이름을 지정한 후 고급 설정을 클릭합니다.

노트북_만들기

고급 설정에서 유휴 종료를 사용 설정하고 분 시간을 60으로 설정합니다. 따라서 노트북을 사용하지 않을 때는 자동으로 종료되므로 불필요한 비용이 발생하지 않습니다.

idle_timeout

'터미널 사용 설정'이 아직 사용 설정되지 않은 경우 보안에서 선택합니다.

enable_terminal

다른 고급 설정은 모두 그대로 둘 수 있습니다.

그런 다음 만들기를 클릭합니다. 인스턴스를 프로비저닝하는 데 몇 분 정도 걸립니다.

인스턴스가 생성되면 JupyterLab 열기를 선택합니다.

open_jupyterlab

새 인스턴스를 처음 사용할 때 인증하라는 메시지가 표시됩니다. UI의 단계를 따릅니다.

인증

4. 학습 애플리케이션 코드 컨테이너화

이 실습에서 학습시킬 모델은말 또는 인간 데이터 세트 보낸 사람TensorFlow 데이터 세트 가 있는지 진단합니다.

학습 애플리케이션 코드를 Docker 컨테이너에 넣고 이 컨테이너를 Google Container Registry에 푸시하여 이 초매개변수 조정 작업을 Vertex AI에 제출합니다. 이 접근 방식을 사용하면 임의의 프레임워크로 빌드된 모델의 초매개변수를 미세 조정할 수 있습니다.

시작하려면 런처 메뉴에서 노트북 인스턴스의 터미널 창을 엽니다.

노트북에서 터미널 열기

horses_or_humans라는 새 디렉터리를 만들고 여기에 cd합니다.

mkdir horses_or_humans
cd horses_or_humans

1단계: Dockerfile 만들기

코드 컨테이너화의 첫 단계는 Dockerfile을 만드는 것입니다. Dockerfile에는 이미지를 실행하는 데 필요한 모든 명령어가 포함됩니다. CloudML Hypertune 라이브러리를 포함하여 필요한 모든 라이브러리를 설치하고 학습 코드의 진입점을 설정합니다.

터미널에서 빈 Dockerfile을 만듭니다.

touch Dockerfile

Dockerfile을 열고 다음을 복사합니다.

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은 Deep Learning Container TensorFlow Enterprise 2.7 GPU Docker 이미지를 사용합니다. Google Cloud의 딥 러닝 컨테이너에는 다양한 일반 ML 및 데이터 과학 프레임워크가 사전 설치되어 있습니다. 이 이미지를 다운로드한 후 이 Dockerfile은 학습 코드의 진입점을 설정합니다. 아직 파일을 만들지 않았습니다. 다음 단계에서는 모델 학습 및 조정을 위한 코드를 추가합니다.

2단계: 모델 학습 코드 추가

터미널에서 다음을 실행하여 학습 코드 디렉터리와 코드를 추가할 Python 파일을 만듭니다.

mkdir trainer
touch trainer/task.py

이제 horses_or_humans/ 디렉터리에 다음이 포함됩니다.

+ Dockerfile
+ trainer/
    + task.py

다음으로, 방금 만든 task.py 파일을 열고 아래 코드를 복사합니다.

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()

컨테이너를 빌드하기 전에 코드를 자세히 살펴보겠습니다. 초매개변수 조정 서비스를 사용하는 것과 관련된 몇 가지 구성요소가 있습니다.

  1. 스크립트가 hypertune 라이브러리를 가져옵니다. 1단계의 Dockerfile에 이 라이브러리 pip 설치 안내가 포함되어 있습니다.
  2. get_args() 함수는 조정하려는 각 초매개변수의 명령줄 인수를 정의합니다. 이 예에서 조정하려는 초매개변수는 학습률, 옵티마이저의 모멘텀 값, 모델의 마지막 히든 레이어의 단위 수이지만 다른 실험을 자유롭게 진행할 수 있습니다. 그런 다음 이러한 인수에 전달된 값은 코드에 상응하는 초매개변수를 설정하는 데 사용됩니다.
  3. main() 함수 끝부분에서 hypertune 라이브러리를 사용하여 최적화하려는 측정항목을 정의합니다. TensorFlow에서 keras model.fit 메서드는 History 객체를 반환합니다. History.history 속성은 연속된 에포크의 학습 손실 값 및 측정항목 값에 대한 레코드입니다. 유효성 검사 데이터를 model.fit에 전달하면 History.history 속성에 유효성 검사 손실 및 측정항목 값도 포함됩니다. 예를 들어 검증 데이터로 3에포크의 모델을 학습시키고 accuracy를 측정항목으로 제공한 경우 History.history 속성은 다음 사전과 비슷하게 표시됩니다.
{
 "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
 ]

초매개변수 조정 서비스가 모델의 검증 정확성을 극대화하는 값을 검색하도록 하려면 측정항목을 val_accuracy 목록의 마지막 항목 (또는 NUM_EPOCS - 1)으로 정의합니다. 그런 다음 이 측정항목을 HyperTune의 인스턴스에 전달합니다. hyperparameter_metric_tag에 원하는 문자열을 선택할 수 있지만 초매개변수 조정 작업을 시작할 때 나중에 문자열을 다시 사용해야 합니다.

3단계: 컨테이너 빌드

터미널에서 다음을 실행하여 프로젝트의 env 변수를 정의하고 your-cloud-project를 프로젝트의 ID로 바꿉니다.

PROJECT_ID='your-cloud-project'

Google Container Registry에서 컨테이너 이미지의 URI로 변수를 정의합니다.

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

그런 다음 horses_or_humans 디렉터리의 루트에서 다음을 실행하여 컨테이너를 빌드합니다.

docker build ./ -t $IMAGE_URI

마지막으로 Google Container Registry로 푸시합니다.

docker push $IMAGE_URI

컨테이너가 Container Registry로 푸시되었으므로 이제 커스텀 모델 초매개변수 조정 작업을 시작할 수 있습니다.

5 Vertex AI에서 초매개변수 조정 작업 실행

이 실습에서는 Google Container Registry의 커스텀 컨테이너를 통해 커스텀 학습을 사용하지만, Vertex AI 사전 빌드된 컨테이너를 사용하여 초매개변수 조정 작업을 실행할 수도 있습니다.

시작하려면 Cloud Console의 Vertex 섹션에 있는 학습 섹션으로 이동합니다.

uCAIP 메뉴

1단계: 학습 작업 구성

만들기를 클릭하여 초매개변수 조정 작업의 매개변수를 입력합니다.

  • 데이터 세트에서 관리형 데이터 세트 없음을 선택합니다.
  • 그런 다음 학습 방법으로 커스텀 학습 (고급)을 선택하고 계속을 클릭합니다.
  • 모델 이름horses-humans-hyptertune (또는 모델을 호출하려는 이름)를 입력합니다.
  • 계속을 클릭합니다.

컨테이너 설정 단계에서 커스텀 컨테이너를 선택합니다.

커스텀 컨테이너 옵션

첫 번째 상자 (컨테이너 이미지)에 이전 섹션의 IMAGE_URI 변수 값을 입력합니다. 프로젝트 이름이 gcr.io/your-cloud-project/horse-human:hypertune여야 합니다. 나머지 필드는 비워 두고 Continue를 클릭합니다.

2단계: 초매개변수 조정 작업 구성

초매개변수 미세 조정 사용을 선택합니다.

초매개변수

초매개변수 구성

그런 다음 학습 애플리케이션 코드에서 명령줄 인수로 설정한 초매개변수를 추가해야 합니다. 초매개변수를 추가할 때 먼저 이름을 제공해야 합니다. argparse에 전달한 인수 이름과 일치해야 합니다.

학습_률_이름

그런 다음 조정 서비스에서 사용해 볼 값의 경계와 유형을 선택합니다. 더블 또는 정수 유형을 선택한 경우 최솟값과 최댓값을 제공해야 합니다. 범주형 또는 개별을 선택한 경우 값을 제공해야 합니다.

학습_비율_유형학습_률_이름

double 및 정수 유형의 경우 확장 값도 제공해야 합니다.

학습_률_배율

learning_rate 초매개변수를 추가한 후 momentumnum_units용 매개변수를 추가합니다.

모멘텀_구성

numneruons_config

측정항목 구성

초매개변수를 추가한 후 최적화하려는 측정항목과 목표를 제공합니다. 이 값은 학습 애플리케이션에 설정한 hyperparameter_metric_tag와 동일해야 합니다.

측정항목_구성

Vertex AI 초매개변수 조정 서비스는 이전 단계에서 구성한 값으로 학습 애플리케이션의 여러 시도를 실행합니다. 서비스를 실행할 시도 횟수의 상한선을 설정해야 합니다. 일반적으로 더 많은 시도를 하면 더 좋은 결과를 얻게 되나, 그 후의 시도를 최적화하려는 측정항목에 미치는 효과가 거의 없거나 전혀 없는 경우도 있어 수익이 감소할 수 있습니다. 적은 수의 시도로 시작하고 많은 시도로 확장하기 전에 선택한 초매개변수에 미치는 영향을 파악하는 것이 좋습니다.

또한 병렬 시도 횟수의 상한선을 설정해야 합니다. 병렬 시도 수를 늘리면 초매개변수 조정 작업의 실행 시간이 줄어듭니다. 그러나 작업 효율성이 전반적으로 감소할 수 있습니다. 이는 기본 조정 전략에서 이전 시도 결과를 사용하여 후속 시도에서 값을 할당하기 때문입니다. 너무 많은 시도를 동시에 실행하는 경우 여전히 시도되는 시도의 이점 없이 시작됩니다.

시연을 위해 시도 횟수를 15회로 설정하고 최대 병렬 시도 횟수를 3회로 설정할 수 있습니다. 다양한 수치로 실험할 수 있지만 이 경우 조정 시간이 길어지고 비용이 증가할 수 있습니다.

체험판_구성

마지막 단계는 Google Vizier를 사용하여 초매개변수 조정을 위해 Bayesian 최적화를 실행하는 검색 알고리즘으로 기본값을 선택하는 것입니다. 여기에서 이 알고리즘에 대해 자세히 알아보세요.

알고리즘_구성

계속을 클릭합니다.

3단계: 컴퓨팅 구성

컴퓨팅 및 가격 책정에서 선택한 리전을 그대로 두고 작업자 풀 0을 다음과 같이 구성합니다.

머신 유형

학습 시작을 클릭하여 초매개변수 조정 작업을 시작합니다. Console의 학습 섹션에서 작업 조정 탭 아래에 다음과 같이 표시됩니다.

초매개변수 작업

작업이 완료되면 작업 이름을 클릭하여 시도 결과를 확인할 수 있습니다.

초매개변수 출력

🎉 수고하셨습니다. 🎉

지금까지 Vertex AI를 사용하여 다음을 하는 방법을 배웠습니다.

  • 커스텀 컨테이너에 제공된 학습 코드의 초매개변수 조정 작업을 실행합니다. 이 예시에서 TensorFlow 모델을 사용했지만 커스텀 컨테이너를 사용하여 모든 프레임워크로 빌드된 모델을 학습시킬 수 있습니다.

Vertex의 다양한 부분에 관한 자세한 내용은 문서를 참고하세요.

6. [선택사항] Vertex SDK 사용

이전 섹션에서는 UI를 통해 초매개변수 조정 작업을 실행하는 방법을 설명했습니다. 이 섹션에서는 Vertex Python API를 사용하여 초매개변수 조정 작업을 제출하는 다른 방법을 알아봅니다.

런처에서 TensorFlow 2 노트북을 만듭니다.

새 노트북

Vertex AI SDK를 가져옵니다.

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

초매개변수 조정 작업을 시작하려면 먼저 다음 사양을 정의해야 합니다. image_uri{PROJECT_ID}를 프로젝트로 바꿔야 합니다.

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

다음으로 CustomJob을 만듭니다. 스테이징을 위해 {YOUR_BUCKET}을 프로젝트의 버킷으로 바꿔야 합니다.

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

그런 다음 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 정리

노트북이 유휴 시간 60분 후에 타임아웃되도록 구성했으므로 인스턴스를 종료할 필요가 없습니다. 인스턴스를 수동으로 종료하려면 콘솔의 Vertex AI Workbench 섹션에서 Stop 버튼을 클릭합니다. 노트북을 완전히 삭제하려면 삭제 버튼을 클릭합니다.

인스턴스 중지

스토리지 버킷을 삭제하려면 Cloud Console의 탐색 메뉴를 사용하여 스토리지로 이동하여 버킷을 선택하고 삭제를 클릭합니다.

저장용량 삭제