1. 總覽
在這個研究室中,您將使用 Vertex AI 在 Vertex AI 訓練中執行超參數調整工作。
這個研究室是「Prototype to Production」系列影片的一部分。試用本研究室前,請務必完成上一個研究室。歡迎觀看相關系列影片,瞭解更多資訊:
。
課程內容
您將學習下列內容:
- 針對自動化超參數調整修改訓練應用程式程式碼
- 使用 Vertex AI Python SDK 設定及啟動超參數調整工作
在 Google Cloud 中執行這個研究室的總費用約為 $1 美元。
2. Vertex AI 簡介
這個研究室使用 Google Cloud 最新的 AI 產品服務。Vertex AI 將 Google Cloud 中的機器學習產品整合到流暢的開發體驗中。先前使用 AutoML 訓練的模型和自訂模型,都能透過不同的服務存取。這項新產品會與其他新產品一起合併為一個 API。您也可以將現有專案遷移至 Vertex AI。
Vertex AI 提供許多不同的產品,可支援端對端機器學習工作流程。本研究室將著重介紹下列產品:訓練和 Workbench
3. 設定環境
完成「使用 Vertex AI 訓練自訂模型」研究室中的步驟,完成環境設定作業。
4. 將訓練應用程式程式碼容器化
您必須將訓練應用程式程式碼放入 Docker 容器,並將這個容器推送至 Google Artifact Registry,藉此將這項訓練工作提交至 Vertex AI。這樣一來,您就可以訓練和調整透過任何架構建構的模型。
首先,請在先前研究室建立的 Workbench 筆記本的啟動器選單中,開啟終端機視窗。
步驟 1:編寫訓練程式碼
建立名為 flowers-hptune
的新目錄,並使用 cd 加入該目錄:
mkdir flowers-hptune
cd flowers-hptune
執行下列指令,為訓練程式碼建立目錄,以及建立以下程式碼的 Python 檔案。
mkdir trainer
touch trainer/task.py
現在 flowers-hptune/
目錄中應會顯示以下內容:
+ trainer/
+ task.py
接著,開啟剛剛建立的 task.py
檔案,並複製以下程式碼。
請將 BUCKET_ROOT
中的 {your-gcs-bucket}
替換成您在 Lab 1 中儲存花卉資料集的 Cloud Storage 值區。
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()
建構容器之前,讓我們先進一步瞭解程式碼。使用超參數調整服務有幾個專門的元件。
- 指令碼會匯入
hypertune
程式庫。 - 函式
get_args()
會為您要調整的每個超參數定義指令列引數。在這個範例中,要調整的超參數包括學習率、最佳化工具中的動量值,以及模型最後一個隱藏層中的單位數量,不過您可以自由測試其他參數。接著,系統會使用這些引數中傳送的值,在程式碼中設定對應的超參數。 - 在
main()
函式的結尾,hypertune
程式庫是用來定義您要最佳化的指標。在 TensorFlow 中,keras 的model.fit
方法會傳回History
物件。History.history
屬性是連續訓練週期的訓練損失值和指標值記錄。如果將驗證資料傳遞至model.fit
,History.history
屬性也會包含驗證損失和指標值。舉例來說,假設您使用驗證資料來訓練三個訓練週期的模型,並將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
挑選任何喜歡的字串,但稍後當您啟動超參數調整工作時,就需要再次使用該字串。
步驟 2:建立 Dockerfile
如要將程式碼容器化,您必須建立 Dockerfile。而 Dockerfile 包含執行映像檔所需的所有指令。其會安裝所有必要的程式庫,並設定訓練程式碼的進入點。
在終端機中,於 flowers-hptune
目錄的根目錄中建立空白的 Dockerfile:
touch Dockerfile
現在 flowers-hptune/
目錄中應會顯示以下內容:
+ Dockerfile
+ trainer/
+ task.py
開啟 Dockerfile,並將下列內容複製到該檔案中。您會發現這與我們在第一個研究室中使用的 Dockerfile 幾乎相同,差別在於我們現在會安裝 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"]
步驟 3:建構容器
在終端機執行下列指令,定義專案的環境變數;請務必將 your-cloud-project
替換為您的專案 ID:
PROJECT_ID='your-cloud-project'
在 Artifact Registry 中定義存放區。我們會使用在第一個研究室中建立的存放區
REPO_NAME='flower-app'
使用 Google Artifact Registry 中容器映像檔的 URI 定義變數:
IMAGE_URI=us-central1-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/flower_image_hptune:latest
設定 Docker
gcloud auth configure-docker \
us-central1-docker.pkg.dev
接著,從 flower-hptune
目錄的根目錄執行下列指令,以建構容器:
docker build ./ -t $IMAGE_URI
最後,將其推送至 Artifact Registry:
docker push $IMAGE_URI
將容器推送至 Artifact Registry 後,您就能開始執行訓練工作。
5. 使用 SDK 執行超參數調整工作
在本節中,您將瞭解如何使用 Vertex Python API 設定及提交超參數調整工作。
在 Launcher 中建立 TensorFlow 2 筆記本。
匯入 Vertex AI SDK。
from google.cloud import aiplatform
from google.cloud.aiplatform import hyperparameter_tuning as hpt
如要啟動超參數調整工作,您必須先定義 worker_pool_specs
,這會指定機器類型和 Docker 映像檔。下列規格定義一部搭載兩個 NVIDIA Tesla V100 GPU 的機器。
您需要將 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": "us-central1-docker.pkg.dev/{PROJECT_ID}/flower-app/flower_image_hptune:latest"
}
}]
接著,定義 parameter_spec
,這是一個字典,用來指定您要最佳化的參數。字典鍵是您指派給每個超參數指令列引數的字串,而字典值則是參數規格。
對於每個超參數,您必須定義類型以及調整服務將嘗試的值邊界。超參數可以是雙數、整數、類別或離散類型。如果選取雙精度浮點數或整數,就必須提供最小值和最大值。如果您選取「類別」或「離散」,就需要提供這些值。對於 Double 和 Integer 類型,您還需要提供資源調度值。如要進一步瞭解如何挑選最適當的比例,請觀看這部影片。
# 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)
}
最後一個要定義的規格是 metric_spec
,此字典代表要最佳化的指標。字典鍵是您在訓練應用程式程式碼中設定的 hyperparameter_metric_tag
,而值則是最佳化目標。
# 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'}
定義規格後,您將建立 CustomJob,這個通用規格會在每個超參數調整試驗上執行工作。
您需要將 {YOUR_BUCKET}
替換為先前建立的值區。
# Replace YOUR_BUCKET
my_custom_job = aiplatform.CustomJob(display_name='flowers-hptune-job',
worker_pool_specs=worker_pool_specs,
staging_bucket='gs://{YOUR_BUCKET}')
接著,請建立並執行 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()
請注意以下引數:
- max_trial_count:您必須設定服務執行的試驗數量上限。測試量越多,成效通常就越好,但效益會因此下滑,若經過額外試驗,對要最佳化的指標幾乎或完全沒有影響。最佳做法是先從少量試驗著手,然後瞭解所選超參數的影響程度,再向上擴充。
- parallel_trial_count:如果使用平行試驗,該服務會佈建多個訓練處理叢集。如增加平行試驗數量,就能縮短超參數調整工作的執行時間。但會降低工作整體效率。這是因為預設調整策略會根據先前試驗的結果,在後續試驗中指派值。
- search_algorithm:您可以將搜尋演算法設為格狀、隨機或預設 (無)。預設選項會套用貝葉斯最佳化功能,以搜尋可能的超參數值空間 (這是建議使用的演算法)。請參閱這裡的文章,進一步瞭解這個演算法。
您可以在控制台中查看工作的進度。
實驗結束後,您可以查看每個試驗的結果,以及哪一組值的成效最佳。
🎉 恭喜!🎉
您已瞭解如何使用 Vertex AI 執行下列作業:
- 執行自動化超參數調整工作
如要進一步瞭解 Vertex 的其他部分,請參閱說明文件。
6. 清除
因為我們設定了筆記本在 60 分鐘閒置後逾時,所以我們不必擔心如何關閉執行個體。如要手動關閉執行個體,請前往控制台的「Vertex AI Workbench」專區,然後按一下「Stop」按鈕。如想完全刪除筆記本,請按一下「刪除」按鈕。
如要刪除 Storage 值區,請使用 Cloud 控制台中的導覽選單前往「Storage」(儲存空間)、選取值區,然後點選「Delete」(刪除):