Vertex AI: Penyesuaian hyperparameter yang terdistribusi

1. Ringkasan

Di lab ini, Anda akan mempelajari cara menggunakan Vertex AI untuk penyesuaian hyperparameter dan pelatihan yang terdistribusi. Meskipun lab ini menggunakan TensorFlow sebagai kode model, konsepnya juga berlaku untuk framework ML lainnya.

Yang Anda pelajari

Anda akan mempelajari cara:

  • Melatih model menggunakan pelatihan yang terdistribusi pada container kustom
  • Meluncurkan beberapa uji coba kode pelatihan Anda untuk penyesuaian hyperparameter otomatis

Total biaya untuk menjalankan lab ini di Google Cloud adalah sekitar $6 USD.

2. Pengantar Vertex AI

Lab ini menggunakan penawaran produk AI terbaru yang tersedia di Google Cloud. Vertex AI mengintegrasikan penawaran ML di Google Cloud ke dalam pengalaman pengembangan yang lancar. Sebelumnya, model yang dilatih dengan AutoML dan model kustom dapat diakses melalui layanan terpisah. Penawaran baru ini menggabungkan kedua model ini menjadi satu API, beserta produk baru lainnya. Anda juga dapat memigrasikan project yang sudah ada ke Vertex AI. Jika Anda memiliki masukan, harap lihat halaman dukungan.

Vertex AI mencakup banyak produk yang berbeda untuk mendukung alur kerja ML secara menyeluruh. Lab ini akan berfokus pada Pelatihan dan Workbench.

Ringkasan produk Vertex

3. Ringkasan Kasus Penggunaan

Di lab ini, Anda akan menggunakan penyesuaian hyperparameter untuk menemukan parameter yang optimal untuk model klasifikasi image yang dilatih di set data kuda atau manusia dari Set Data TensorFlow.

Penyesuaian Hyperparameter

Penyesuaian hyperparameter dengan Pelatihan Vertex AI berfungsi dengan menjalankan beberapa uji coba aplikasi pelatihan Anda dengan nilai untuk hyperparameter yang dipilih, yang ditetapkan sesuai batas yang Anda tentukan. Vertex AI melacak hasil dari setiap uji coba dan melakukan penyesuaian untuk uji coba berikutnya.

Untuk menggunakan penyesuaian hyperparameter dengan Pelatihan Vertex AI, ada dua perubahan yang perlu Anda lakukan pada kode pelatihan:

  1. Tentukan argumen command line dalam modul pelatihan utama untuk setiap hyperparameter yang ingin Anda sesuaikan.
  2. Gunakan nilai yang diteruskan dalam argumen tersebut untuk menetapkan hyperparameter yang sesuai dalam kode aplikasi Anda.

Pelatihan yang Terdistribusi

Jika Anda memiliki satu GPU, TensorFlow akan menggunakan akselerator ini untuk mempercepat pelatihan model tanpa perlu melakukan upaya lain. Namun, jika Anda ingin mendapatkan peningkatan tambahan dari penggunaan beberapa GPU, Anda harus menggunakan tf.distribute, yang merupakan modul TensorFlow untuk menjalankan komputasi dalam beberapa perangkat.

Lab ini menggunakan tf.distribute.MirroredStrategy, yang dapat Anda tambahkan ke aplikasi pelatihan hanya dengan beberapa perubahan kode. Strategi ini akan membuat salinan model di setiap GPU pada mesin Anda. Update gradien berikutnya akan berlangsung secara sinkron. Artinya, setiap GPU menghitung penerusan maju dan mundur melalui model pada bagian data input yang berbeda. Gradien yang dihitung dari setiap bagian tersebut kemudian digabungkan di semua GPU dan dirata-ratakan dalam proses yang dikenal sebagai all-reduce. Parameter model diupdate menggunakan gradien rata-rata ini.

Anda tidak perlu mengetahui detailnya untuk menyelesaikan lab ini, tetapi jika ingin mempelajari lebih lanjut cara kerja pelatihan terdistribusi di TensorFlow, lihat video di bawah ini:

4. Menyiapkan lingkungan Anda

Anda memerlukan project Google Cloud Platform dengan penagihan yang diaktifkan untuk menjalankan codelab ini. Untuk membuat project, ikuti petunjuk di sini.

Langkah 1: Aktifkan Compute Engine API

Buka Compute Engine dan pilih Aktifkan jika belum diaktifkan.

Langkah 2: Aktifkan Container Registry API

Buka Container Registry dan pilih Aktifkan jika belum melakukannya. Anda akan menggunakannya untuk membuat container tugas pelatihan kustom.

Langkah 3: Aktifkan Vertex AI API

Buka bagian Vertex AI di Cloud Console Anda, lalu klik Aktifkan Vertex AI API.

Dasbor Vertex AI

Langkah 4: Buat instance Vertex AI Workbench

Dari bagian Vertex AI di Cloud Console Anda, klik Workbench:

Menu Vertex AI

Aktifkan Notebooks API jika belum diaktifkan.

Notebook_api

Setelah diaktifkan, klik NOTEBOOK TERKELOLA:

Notebooks_UI

Kemudian, pilih NOTEBOOK BARU.

new_notebook

Beri nama notebook Anda, lalu klik Setelan Lanjutan.

create_notebook

Di bagian Setelan Lanjutan, aktifkan penonaktifan tidak ada aktivitas dan setel jumlah menit ke 60. Artinya, notebook Anda akan otomatis dinonaktifkan saat tidak digunakan agar tidak menimbulkan biaya tambahan.

idle_timeout

Di bagian Keamanan, pilih "Aktifkan terminal" jika belum diaktifkan.

enable-terminal

Anda dapat membiarkan semua setelan lanjutan lainnya apa adanya.

Selanjutnya, klik Buat. Instance akan memerlukan waktu beberapa menit untuk disediakan.

Setelah instance dibuat, pilih Buka JupyterLab.

open_jupyterlab

Saat pertama kali menggunakan instance baru, Anda akan diminta untuk mengautentikasi. Ikuti langkah-langkah di UI untuk melakukannya.

autentikasi

5. Menulis kode pelatihan

Untuk memulai, dari menu Peluncur, buka jendela Terminal di instance notebook Anda:

launcher_terminal

Buat direktori baru bernama vertex-codelab dan cd ke dalamnya.

mkdir vertex-codelab
cd vertex-codelab

Jalankan perintah berikut guna membuat direktori untuk kode pelatihan dan file Python tempat Anda akan menambahkan kodenya:

mkdir trainer
touch trainer/task.py

Sekarang Anda akan memiliki kode berikut di direktori vertex-codelab Anda:

+ trainer/
    + task.py

Selanjutnya, buka file task.py yang baru saja Anda buat dan tempelkan semua kode di bawah.

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

NUM_EPOCHS = 10
BATCH_SIZE = 64

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(batch_size):
  '''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(batch_size)

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

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

  # Create distribution strategy
  strategy = tf.distribute.MirroredStrategy()

  # Get data
  GLOBAL_BATCH_SIZE = BATCH_SIZE * strategy.num_replicas_in_sync
  train_data, validation_data = create_dataset(GLOBAL_BATCH_SIZE)

  # Wrap variable creation within strategy scope
  with strategy.scope():
    model = create_model(args.num_units, args.learning_rate, args.momentum)

  # Train model
  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()

Mari pelajari lebih lanjut kode tersebut dan periksa komponen khusus untuk pelatihan terdistribusi dan penyesuaian hyperparameter.

Pelatihan yang Terdistribusi

  1. Dalam fungsi main(), objek MirroredStrategy dibuat. Selanjutnya, gabungkan pembuatan variabel model Anda dalam cakupan strategi. Langkah ini memberi tahu TensorFlow terkait variabel mana yang harus dicerminkan di seluruh GPU.
  2. Ukuran tumpukan ditingkatkan skalanya menurut num_replicas_in_sync. Penskalaan ukuran tumpukan adalah praktik terbaik saat menggunakan strategi paralelisme data sinkron di TensorFlow. Anda dapat mempelajari lebih lanjut di sini.

Penyesuaian Hyperparameter

  1. Skrip ini akan mengimpor library hypertune. Setelah mem-build image container, kami perlu memastikan bahwa library ini sudah diinstal.
  2. Fungsi get_args() menentukan argumen command line untuk setiap hyperparameter yang ingin Anda sesuaikan. Dalam contoh ini, hyperparameter yang akan disesuaikan adalah kecepatan pembelajaran, nilai momentum dalam pengoptimal, dan jumlah unit dalam lapisan tersembunyi terakhir dari model, tetapi jangan ragu untuk bereksperimen menggunakan yang lainnya. Nilai yang diteruskan dalam argumen tersebut kemudian akan digunakan untuk menetapkan hyperparameter yang sesuai dalam kode (misalnya, tetapkan learning_rate = args.learning_rate)
  3. Di bagian akhir fungsi main(), library hypertune digunakan untuk menentukan metrik yang ingin Anda optimalkan. Di TensorFlow, metode model.fit Keras akan menampilkan objek History. Atribut History.history adalah data nilai kerugian pelatihan dan nilai metrik pada iterasi pelatihan berturut-turut. Jika Anda meneruskan data validasi ke model.fit, atribut History.history juga akan menyertakan nilai metrik dan kerugian validasi. Misalnya, jika Anda melatih model untuk tiga iterasi pelatihan dengan data validasi dan memberikan accuracy sebagai metrik, atribut History.history akan terlihat mirip dengan kamus berikut.
{
 "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
 ]

Jika Anda ingin layanan penyesuaian hyperparameter menemukan nilai yang memaksimalkan akurasi validasi model, Anda perlu menentukan metrik sebagai entri terakhir (atau NUM_EPOCS - 1) dari daftar val_accuracy. Kemudian, teruskan metrik ini ke instance HyperTune. Anda dapat memilih string apa pun yang diinginkan untuk hyperparameter_metric_tag, tetapi Anda harus menggunakan string tersebut lagi saat memulai tugas penyesuaian hyperparameter.

6. Mem-build kode dalam container

Langkah pertama untuk mem-build kode dalam container adalah membuat Dockerfile. Dalam Dockerfile, Anda akan menyertakan semua perintah yang diperlukan untuk menjalankan image. Tindakan ini akan menginstal semua library yang diperlukan dan menyiapkan titik entri untuk kode pelatihan.

Langkah 1: Menulis Dockerfile

Dari Terminal Anda, pastikan Anda berada di direktori vertex-codelab dan membuat Dockerfile kosong:

touch Dockerfile

Sekarang Anda akan memiliki kode berikut di direktori vertex-codelab Anda:

+ Dockerfile
+ trainer/
    + task.py

Buka Dockerfile dan salin kode berikut ke dalamnya:

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 ini menggunakan image Docker GPU Deep Learning Container TensorFlow Enterprise 2.7. Deep Learning Containers di Google Cloud dilengkapi dengan banyak ML umum dan framework data science yang diiinstal sebelumnya. Setelah mendownload image tersebut, Dockerfile ini akan menyiapkan titik entri untuk kode pelatihan.

Langkah 2: Build container

Dari Terminal Anda, jalankan perintah berikut untuk menentukan variabel env untuk project Anda, pastikan untuk mengganti your-cloud-project dengan ID project Anda:

PROJECT_ID='your-cloud-project'

Tentukan variabel dengan URI image container Anda di Google Container Registry:

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

Konfigurasi Docker

gcloud auth configure-docker

Kemudian, build container dengan menjalankan perintah berikut dari root direktori vertex-codelab Anda:

docker build ./ -t $IMAGE_URI

Terakhir, teruskan ke Google Container Registry:

docker push $IMAGE_URI

Langkah 3: Buat bucket Cloud Storage

Dalam tugas pelatihan, kami akan meneruskan jalur ke bucket staging.

Jalankan perintah berikut di Terminal untuk membuat bucket baru dalam project Anda.

BUCKET_NAME="gs://${PROJECT_ID}-hptune-bucket"
gsutil mb -l us-central1 $BUCKET_NAME

7. Meluncurkan tugas penyesuaian hyperparameter

Langkah 1: Buat tugas pelatihan kustom dengan penyesuaian hyperparameter

Dari peluncur, buka TensorFlow 2 Notebook baru.

new_notebook

Impor Vertex AI Python SDK.

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

Untuk meluncurkan tugas penyesuaian hyperparameter, Anda harus terlebih dahulu menentukan worker_pool_specs, yang akan menentukan jenis mesin dan image Docker. Spesifikasi berikut menentukan satu mesin dengan dua GPU NVIDIA Tesla V100.

Anda harus mengganti {PROJECT_ID} di image_uri dengan project Anda.

# 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": 2
    },
    "replica_count": 1,
    "container_spec": {
        "image_uri": "gcr.io/{PROJECT_ID}/horse-human-codelab:latest"
    }
}]

Selanjutnya, tentukan parameter_spec, yang merupakan kamus untuk menentukan parameter yang ingin Anda optimalkan. Kunci kamus adalah string yang Anda tetapkan ke argumen command line untuk setiap hyperparameter, dan nilai kamus adalah spesifikasi parameternya.

Untuk setiap hyperparameter, Anda harus menentukan Jenis serta batas nilai yang akan dicoba oleh layanan penyesuaian. Hyperparameter dapat berupa jenis Ganda, Bilangan Bulat, Kategoris, atau Diskret. Jika memilih jenis Ganda atau Bilangan Bulat, Anda harus memberikan nilai minimum dan maksimum. Dan jika memilih Kategoris atau Diskret, Anda harus memberikan nilainya. Untuk jenis Ganda dan Bilangan Bulat, Anda juga harus memberikan nilai Penskalaan. Anda dapat mempelajari lebih lanjut cara memilih skala terbaik dalam video ini.

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

Spesifikasi akhir yang ditetapkan adalah metric_spec, yaitu kamus yang mewakili metrik yang akan dioptimalkan. Kunci kamus adalah hyperparameter_metric_tag yang Anda tetapkan dalam kode aplikasi pelatihan, dan nilainya adalah sasaran pengoptimalannya.

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

Setelah spesifikasi ditentukan, Anda akan membuat CustomJob, yaitu spesifikasi umum yang akan digunakan untuk menjalankan tugas Anda pada setiap uji coba penyesuaian hyperparameter.

Anda harus mengganti {YOUR_BUCKET} dengan bucket yang Anda buat sebelumnya.

# Replace YOUR_BUCKET
my_custom_job = aiplatform.CustomJob(display_name='horses-humans',
                              worker_pool_specs=worker_pool_specs,
                              staging_bucket='gs://{YOUR_BUCKET}')

Kemudian, buat dan jalankan HyperparameterTuningJob.

hp_job = aiplatform.HyperparameterTuningJob(
    display_name='horses-humans',
    custom_job=my_custom_job,
    metric_spec=metric_spec,
    parameter_spec=parameter_spec,
    max_trial_count=6,
    parallel_trial_count=2,
    search_algorithm=None)

hp_job.run()

Ada beberapa argumen yang perlu diperhatikan:

  • max_trial_count: Anda harus menetapkan batas maksimal terkait jumlah uji coba yang akan dijalankan oleh layanan tersebut. Lebih banyak uji coba umumnya memberikan hasil yang lebih baik, tetapi akan ada titik penurunan hasil, lalu uji coba tambahan yang dilakukan setelahnya memiliki sedikit hingga tanpa pengaruh pada metrik yang akan Anda optimalkan. Praktik terbaiknya adalah memulai dengan jumlah uji coba yang lebih sedikit dan memahami dampaknya terhadap hyperparameter yang Anda pilih sebelum meningkatkan skalanya.
  • paralel_trial_count: Jika Anda menggunakan uji coba paralel, layanan akan menyediakan beberapa cluster pemrosesan pelatihan. Peningkatan jumlah uji coba paralel akan mengurangi jumlah waktu yang diperlukan untuk menjalankan tugas penyesuaian hyperparameter; namun, cara ini dapat mengurangi efektivitas tugas secara keseluruhan. Ini karena strategi penyesuaian default menggunakan hasil uji coba sebelumnya untuk menentukan penetapan nilai dalam uji coba berikutnya.
  • search_algorithm: Anda dapat menetapkan algoritme penelusuran ke petak, acak, atau default (Tidak ada). Opsi default menerapkan pengoptimalan Bayesian untuk menelusuri ruang dari kemungkinan nilai hyperparameter dan merupakan algoritme yang direkomendasikan. Anda dapat mempelajari lebih lanjut algoritme ini di sini.

Setelah tugas dimulai, Anda dapat melacak statusnya di UI pada tab TUGAS PENYESUAIAN HYPERPARAMETER.

HP_job

Setelah tugas selesai, Anda dapat melihat dan mengurutkan hasil uji coba untuk menemukan kombinasi nilai hyperparameter yang terbaik.

HP_results

🎉 Selamat! 🎉

Anda telah mempelajari cara menggunakan Vertex AI untuk:

  • Menjalankan tugas penyesuaian hyperparameter dengan pelatihan yang terdistribusi

Untuk mempelajari lebih lanjut berbagai bagian Vertex AI, lihat dokumentasinya.

8. Pembersihan

Karena sebelumnya telah mengonfigurasi notebook agar kehabisan waktu setelah 60 menit tidak ada aktivitas, jangan khawatir untuk menonaktifkan instance-nya. Jika Anda ingin menonaktifkan instance secara manual, klik tombol Hentikan di bagian Vertex AI Workbench pada konsol. Jika Anda ingin menghapus notebook secara keseluruhan, klik tombol Hapus.

hapus

Untuk menghapus Bucket Penyimpanan menggunakan menu Navigasi di Cloud Console, jelajahi Penyimpanan, pilih bucket Anda, lalu klik Hapus:

Hapus penyimpanan