다중 목표 최적화

Colab 로고 이 가이드를 Colab에서 노트북으로 실행하기 GitHub 로고GitHub에서 노트북 보기

이 가이드는 AI Platform Optimizer 다중 목표 최적화를 보여줍니다.

목표

목표는 목표 측정항목 y1 = r*sin(theta)minimize합니다.

동시에 목표 측정항목을 y2 = r*cos(theta)maximize합니다.

이를 매개변수 공간에 대해 평가합니다.

  • [0,1]의 r

  • [0, pi/2]의 theta

비용

이 가이드에서는 비용이 청구될 수 있는 Google Cloud 구성요소를 사용합니다.

  • AI Platform Training
  • Cloud Storage

AI Platform Training 가격 책정Cloud Storage 가격 책정에 대해 알아보고 가격 계산기를 사용하여 예상 사용량을 기반으로 비용을 추정해 보세요.

PIP 설치 패키지 및 종속 항목

노트북 환경에 설치되지 않은 추가 종속 항목을 설치합니다.

  • 프레임워크의 최신 GA 버전을 사용합니다.
! pip install -U google-api-python-client
! pip install -U google-cloud
! pip install -U google-cloud-storage
! pip install -U requests
! pip install -U matplotlib

# Restart the kernel after pip installs
import IPython
app = IPython.Application.instance()
app.kernel.do_shutdown(True)

Google Cloud 프로젝트 설정

노트북 환경에 관계없이 다음 단계가 필요합니다.

  1. Google Cloud 프로젝트를 선택하거나 만듭니다.

  2. 프로젝트에 결제가 사용 설정되어 있는지 확인하세요.

  3. AI Platform API를 사용 설정합니다.

  4. 머신에서 로컬로 실행하는 경우 Google Cloud SDK를 설치해야 합니다.

  5. 아래 셀에 프로젝트 ID를 입력합니다. 그런 다음 셀을 실행하여 Cloud SDK가 이 노트북에서 모든 명령어에 적합한 프로젝트를 사용하는지 확인합니다.

참고: Jupyter는 ! 프리픽스가 붙은 행을 셸 명령어로 실행하며 $ 프리픽스가 붙은 Python 변수를 이러한 명령어에 보간합니다.

PROJECT_ID = "[project-id]" #@param {type:"string"}
! gcloud config set project $PROJECT_ID

Google Cloud 계정 인증

AI Platform Notebooks를 사용하는 경우 환경이 이미 인증되었습니다. 이 단계를 건너뛰세요.

import sys

# If you are running this notebook in Colab, run this cell and follow the
# instructions to authenticate your Google Cloud account. This provides access
# to your Cloud Storage bucket and lets you submit training jobs and prediction
# requests.

if 'google.colab' in sys.modules:
    from google.colab import auth as google_auth
    google_auth.authenticate_user()

# If you are running this tutorial in a notebook locally, replace the string
# below with the path to your service account key and run this cell to
# authenticate your Google Cloud account.
else:
    %env GOOGLE_APPLICATION_CREDENTIALS your_path_to_credentials.json

# Log in to your account on Google Cloud
!gcloud auth login

라이브러리 가져오기

import json
import time
import datetime
from googleapiclient import errors

튜토리얼

설정

이 섹션에서는 AI Platform Optimizer API를 호출하기 위한 일부 매개변수와 util 메서드를 정의합니다. 시작하려면 다음 정보를 입력하세요.

# Update to your username
USER = '[user-id]' #@param {type: 'string'}

# These will be automatically filled in.
STUDY_ID = '{}_study_{}'.format(USER, datetime.datetime.now().strftime('%Y%m%d_%H%M%S')) #@param {type: 'string'}
REGION = 'us-central1'
def study_parent():
  return 'projects/{}/locations/{}'.format(PROJECT_ID, REGION)

def study_name(study_id):
  return 'projects/{}/locations/{}/studies/{}'.format(PROJECT_ID, REGION, study_id)

def trial_parent(study_id):
  return study_name(study_id)

def trial_name(study_id, trial_id):
  return 'projects/{}/locations/{}/studies/{}/trials/{}'.format(PROJECT_ID, REGION,
                                                                study_id, trial_id)

def operation_name(operation_id):
  return 'projects/{}/locations/{}/operations/{}'.format(PROJECT_ID, REGION, operation_id)

print('USER: {}'.format(USER))
print('PROJECT_ID: {}'.format(PROJECT_ID))
print('REGION: {}'.format(REGION))
print('STUDY_ID: {}'.format(STUDY_ID))

API 클라이언트 빌드

다음 셀은 Google API 검색 서비스를 사용하여 자동 생성된 API 클라이언트를 빌드합니다. JSON 형식 API 스키마는 Cloud Storage 버킷에서 호스팅됩니다.

from google.cloud import storage
from googleapiclient import discovery

_OPTIMIZER_API_DOCUMENT_BUCKET = 'caip-optimizer-public'
_OPTIMIZER_API_DOCUMENT_FILE = 'api/ml_public_google_rest_v1.json'

def read_api_document():
  client = storage.Client(PROJECT_ID)
  bucket = client.get_bucket(_OPTIMIZER_API_DOCUMENT_BUCKET)
  blob = bucket.get_blob(_OPTIMIZER_API_DOCUMENT_FILE)
  return blob.download_as_string()

ml = discovery.build_from_document(service=read_api_document())
print('Successfully built the client.')

학습 구성 만들기

다음은 계층적 Python 사전으로 빌드된 샘플 학습 구성입니다. 이미 작성되었습니다. 셀을 실행하여 학습을 구성합니다.

# Parameter Configuration
param_r = {
    'parameter': 'r',
    'type' : 'DOUBLE',
    'double_value_spec' : {
        'min_value' : 0,
        'max_value' : 1
    }
}

param_theta = {
    'parameter': 'theta',
    'type' : 'DOUBLE',
    'double_value_spec' : {
        'min_value' : 0,
        'max_value' : 1.57
    }
}

# Objective Metrics
metric_y1 = {
    'metric' : 'y1',
    'goal' : 'MINIMIZE'
}

metric_y2 = {
    'metric' : 'y2',
    'goal' : 'MAXIMIZE'
}

# Put it all together in a study configuration
study_config = {
    'algorithm' : 'ALGORITHM_UNSPECIFIED',  # Let the service choose the `default` algorithm.
    'parameters' : [param_r, param_theta,],
    'metrics' : [metric_y1, metric_y2,],
}

study = {'study_config': study_config}
print(json.dumps(study, indent=2, sort_keys=True))

학습 만들기

다음으로 학습을 만듭니다. 이 학습은 이후 두 목표를 최적화하기 위해 실행됩니다.

# Creates a study
req = ml.projects().locations().studies().create(
    parent=study_parent(), studyId=STUDY_ID, body=study)
try :
  print(req.execute())
except errors.HttpError as e:
  if e.resp.status == 409:
    print('Study already existed.')
  else:
    raise e

측정항목 평가 함수

다음으로 두 가지 목표 측정항목을 평가할 함수를 정의합니다.

import math

# r * sin(theta)
def Metric1Evaluation(r, theta):
  """Evaluate the first metric on the trial."""
  return r * math.sin(theta)

# r * cose(theta)
def Metric2Evaluation(r, theta):
  """Evaluate the second metric on the trial."""
  return r * math.cos(theta)

def CreateMeasurement(trial_id, r, theta):
  print(("=========== Start Trial: [{0}] =============").format(trial_id))

  # Evaluate both objective metrics for this trial
  y1 = Metric1Evaluation(r, theta)
  y2 = Metric2Evaluation(r, theta)
  print('[r = {0}, theta = {1}] => y1 = r*sin(theta) = {2}, y2 = r*cos(theta) = {3}'.format(r, theta, y1, y2))
  metric1 = {'metric': 'y1', 'value': y1}
  metric2 = {'metric': 'y2', 'value': y2}

  # Return the results for this trial
  measurement = {'step_count': 1, 'metrics': [metric1, metric2,]}
  return measurement

시도 실행을 위한 구성 매개변수 설정

client_id - 추천을 요청하는 클라이언트의 식별자입니다. 여러 SuggestTrialsRequests의 client_id가 동일한 경우 시도가 PENDING이면 서비스는 동일한 추천 시도를 반환하고 마지막 추천 시도가 완료되면 새 시도를 제공합니다.

suggestion_count_per_request - 단일 요청에서 요청된 추천(시도) 수입니다.

max_trial_id_to_stop - 중지하기 전에 살펴볼 시도 수입니다. 코드 실행 시간을 줄이려면 4로 설정해야 하므로 수렴을 기대하지 마세요. 수렴의 경우 약 20이 될 수 있습니다. 일반적으로 총 측정기준에 10을 곱하는 것이 좋습니다.

client_id = 'client1' #@param {type: 'string'}
suggestion_count_per_request =  5 #@param {type: 'integer'}
max_trial_id_to_stop =  50 #@param {type: 'integer'}

print('client_id: {}'.format(client_id))
print('suggestion_count_per_request: {}'.format(suggestion_count_per_request))
print('max_trial_id_to_stop: {}'.format(max_trial_id_to_stop))

AI Platform Optimizer 시도 실행

시도를 실행합니다.

trial_id = 0
while trial_id < max_trial_id_to_stop:
  # Requests trials.
  resp = ml.projects().locations().studies().trials().suggest(
    parent=trial_parent(STUDY_ID),
    body={'client_id': client_id, 'suggestion_count': suggestion_count_per_request}).execute()
  op_id = resp['name'].split('/')[-1]

  # Polls the suggestion long-running operations.
  get_op = ml.projects().locations().operations().get(name=operation_name(op_id))
  while True:
      operation = get_op.execute()
      if 'done' in operation and operation['done']:
        break
      time.sleep(1)

  for suggested_trial in get_op.execute()['response']['trials']:
    trial_id = int(suggested_trial['name'].split('/')[-1])
    # Featches the suggested trials.
    trial = ml.projects().locations().studies().trials().get(name=trial_name(STUDY_ID, trial_id)).execute()
    if trial['state'] in ['COMPLETED', 'INFEASIBLE']:
      continue

    # Parses the suggested parameters.
    params = {}
    for param in trial['parameters']:
      if param['parameter'] == 'r':
        r = param['floatValue']
      elif param['parameter'] == 'theta':
        theta = param['floatValue']

    # Evaluates trials and reports measurement.
    ml.projects().locations().studies().trials().addMeasurement(
        name=trial_name(STUDY_ID, trial_id),
        body={'measurement': CreateMeasurement(trial_id, r, theta)}).execute()
    # Completes the trial.
    ml.projects().locations().studies().trials().complete(
        name=trial_name(STUDY_ID, trial_id)).execute()

[실험용] 결과 시각화

이 섹션에서는 위의 학습에 대한 시도를 시각화하는 모듈을 제공합니다.

max_trials_to_annotate = 20

import matplotlib.pyplot as plt
trial_ids = []
y1 = []
y2 = []
resp = ml.projects().locations().studies().trials().list(parent=trial_parent(STUDY_ID)).execute()
for trial in resp['trials']:
  if 'finalMeasurement' in trial:
    trial_ids.append(int(trial['name'].split('/')[-1]))
    metrics = trial['finalMeasurement']['metrics']
    try:
        y1.append([m for m in metrics if m['metric'] == "y1"][0]['value'])
        y2.append([m for m in metrics if m['metric'] == "y2"][0]['value'])
    except:
        pass

fig, ax = plt.subplots()
ax.scatter(y1, y2)
plt.xlabel("y1=r*sin(theta)")
plt.ylabel("y2=r*cos(theta)");
for i, trial_id in enumerate(trial_ids):
  # Only annotates the last `max_trials_to_annotate` trials
  if i > len(trial_ids) - max_trials_to_annotate:
    try:
        ax.annotate(trial_id, (y1[i], y2[i]))
    except:
        pass
plt.gcf().set_size_inches((16, 16))

삭제

이 프로젝트에 사용된 모든 Google Cloud 리소스를 삭제하려면 이 가이드에서 사용한 Google Cloud 프로젝트를 삭제하면 됩니다.