Vertex AI: Dağıtılmış hiperparametre ayarı

1. Genel Bakış

Bu laboratuvarda, hiperparametre ayarlama ve dağıtılmış eğitim için Vertex AI'ı nasıl kullanacağınızı öğreneceksiniz. Bu laboratuvarda model kodu için TensorFlow kullanılsa da kavramlar diğer makine öğrenimi çerçeveleri için de geçerlidir.

Öğrenecekleriniz

Öğrenecekleriniz:

  • Özel bir container'da dağıtılmış eğitimi kullanarak model eğitme
  • Otomatik hiperparametre ayarlama için eğitim kodunuzun birden fazla denemesini başlatma

Bu laboratuvarı Google Cloud'da çalıştırmanın toplam maliyeti yaklaşık 6 ABD dolarıdır.

2. Vertex AI'a giriş

Bu laboratuvarda, Google Cloud'da sunulan en yeni yapay zeka ürünü kullanılmaktadır. Vertex AI, Google Cloud'daki makine öğrenimi tekliflerini sorunsuz bir geliştirme deneyimi için entegre eder. Daha önce, AutoML ile eğitilmiş modeller ve özel modeller ayrı hizmetler üzerinden erişilebiliyordu. Yeni teklif, diğer yeni ürünlerle birlikte bu iki ürünü tek bir API'de birleştirir. Mevcut projeleri de Vertex AI'a taşıyabilirsiniz. Geri bildiriminiz varsa lütfen destek sayfasına göz atın.

Vertex AI, uçtan uca makine öğrenimi iş akışlarını desteklemek için birçok farklı ürün içerir. Bu laboratuvarda Eğitim ve Workbench üzerinde durulacaktır.

Vertex ürününe genel bakış

3. Kullanım Alanına Genel Bakış

Bu laboratuvarda, TensorFlow Datasets'teki horses or humans veri kümesinde eğitilmiş bir görüntü sınıflandırma modeli için optimum parametreleri bulmak üzere hiperparametre ayarlamayı kullanacaksınız.

Hiperparametre Ayarı

Vertex AI Training ile hiperparametre ayarlama, seçtiğiniz hiperparametrelerin değerleriyle eğitim uygulamanızın birden fazla denemesini çalıştırarak çalışır. Bu değerler, belirttiğiniz sınırlar içinde ayarlanır. Vertex AI, her denemenin sonuçlarını takip eder ve sonraki denemeler için ayarlamalar yapar.

Vertex AI Training ile hiperparametre ayarlamayı kullanmak için eğitim kodunuzda yapmanız gereken iki değişiklik vardır:

  1. Ayarlamak istediğiniz her hiperparametre için ana eğitim modülünüzde bir komut satırı bağımsız değişkeni tanımlayın.
  2. Uygulamanızın kodunda ilgili hiperparametreleri ayarlamak için bu bağımsız değişkenlerde iletilen değeri kullanın.

Dağıtılmış Eğitim

Tek bir GPU'nuz varsa TensorFlow, model eğitimini hızlandırmak için bu hızlandırıcıyı kullanır ve sizin tarafınızdan ek bir işlem yapılması gerekmez. Ancak birden fazla GPU kullanarak ek bir artış elde etmek istiyorsanız TensorFlow'un birden fazla cihazda hesaplama çalıştırma modülü olan tf.distribute'yı kullanmanız gerekir.

Bu laboratuvarda, eğitim uygulamalarınıza yalnızca birkaç kod değişikliğiyle ekleyebileceğiniz tf.distribute.MirroredStrategy kullanılır. Bu strateji, makinenizdeki her GPU'da modelin bir kopyasını oluşturur. Sonraki gradyan güncellemeleri eşzamanlı olarak gerçekleşir. Bu, her GPU'nun giriş verilerinin farklı bir bölümünde model üzerinden ileri ve geri geçişleri hesapladığı anlamına gelir. Bu dilimlerin her birinden hesaplanan gradyanlar daha sonra tüm GPU'larda toplanır ve all-reduce olarak bilinen bir süreçte ortalaması alınır. Model parametreleri, bu ortalama gradyanlar kullanılarak güncellenir.

Bu laboratuvarı tamamlamak için ayrıntıları bilmeniz gerekmez. Ancak TensorFlow'da dağıtılmış eğitimin işleyiş şekli hakkında daha fazla bilgi edinmek istiyorsanız aşağıdaki videoyu izleyin:

4. Ortamınızı ayarlama

Bu codelab'i çalıştırmak için faturalandırmanın etkin olduğu bir Google Cloud Platform projesine ihtiyacınız vardır. Proje oluşturmak için buradaki talimatları uygulayın.

1. adım: Compute Engine API'yi etkinleştirin

Compute Engine'e gidin ve henüz etkinleştirilmemişse Etkinleştir'i seçin.

2. adım: Container Registry API'yi etkinleştirin

Container Registry'ye gidin ve henüz etkin değilse Etkinleştir'i seçin. Bu dosyayı, özel eğitim işiniz için bir kapsayıcı oluşturmak üzere kullanacaksınız.

3. adım: Vertex AI API'yi etkinleştirin

Cloud Console'unuzun Vertex AI bölümüne gidin ve Vertex AI API'yi etkinleştir'i tıklayın.

Vertex AI kontrol paneli

4. adım: Vertex AI Workbench örneği oluşturma

Cloud Console'unuzun Vertex AI bölümünde Workbench'i tıklayın:

Vertex AI menüsü

Henüz etkinleştirilmemişse Notebooks API'yi etkinleştirin.

Notebook_api

Etkinleştirildikten sonra YÖNETİLEN NOT DEFTERLERİ'ni tıklayın:

Notebooks_UI

Ardından YENİ NOT DEFTERİ'ni seçin.

new_notebook

Not defterinize bir ad verin ve Gelişmiş Ayarlar'ı tıklayın.

create_notebook

Gelişmiş Ayarlar'da boşta kalma durumunda kapatma özelliğini etkinleştirin ve süreyi 60 dakika olarak ayarlayın. Bu sayede, gereksiz maliyetlere yol açmamak için not defteriniz kullanılmadığında otomatik olarak kapatılır.

idle_timeout

Güvenlik bölümünde, henüz etkinleştirilmemişse "Terminali etkinleştir"i seçin.

enable-terminal

Diğer tüm gelişmiş ayarları olduğu gibi bırakabilirsiniz.

Ardından Oluştur'u tıklayın. Örneğin sağlanması birkaç dakika sürer.

Örnek oluşturulduktan sonra Open JupyterLab'i (JupyterLab'i aç) seçin.

open_jupyterlab

Yeni bir örneği ilk kez kullandığınızda kimlik doğrulamanız istenir. Bunun için kullanıcı arayüzündeki adımları uygulayın.

kimlik doğrulamak

5. Eğitim kodu yazma

Başlamak için Başlatıcı menüsünden not defteri örneğinizde bir Terminal penceresi açın:

launcher_terminal

vertex-codelab adlı yeni bir dizin oluşturun ve bu dizine gidin.

mkdir vertex-codelab
cd vertex-codelab

Eğitim kodu için bir dizin ve kodu ekleyeceğiniz bir Python dosyası oluşturmak üzere aşağıdakileri çalıştırın:

mkdir trainer
touch trainer/task.py

vertex-codelab dizininizde artık şunlar olmalıdır:

+ trainer/
    + task.py

Ardından, yeni oluşturduğunuz task.py dosyasını açın ve aşağıdaki kodun tamamını yapıştırın.

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

Kodu daha ayrıntılı bir şekilde inceleyelim ve dağıtılmış eğitim ile hiperparametre ayarlamaya özgü bileşenleri inceleyelim.

Dağıtılmış Eğitim

  1. main() işlevinde MirroredStrategy nesnesi oluşturulur. Ardından, model değişkenlerinizi stratejinin kapsamına dahil edersiniz. Bu adım, TensorFlow'a hangi değişkenlerin GPU'lar arasında yansıtılması gerektiğini söyler.
  2. Grup boyutu num_replicas_in_sync ile ölçeklendirilir. TensorFlow'da eşzamanlı veri paralelliği stratejileri kullanırken grup boyutunu ölçeklendirmek en iyi uygulamadır. Daha fazla bilgiyi buradan edinebilirsiniz.

Hiperparametre Ayarı

  1. Komut dosyası, hypertune kitaplığını içe aktarır. Daha sonra kapsayıcı görüntüsünü oluştururken bu kitaplığı yüklediğimizden emin olmamız gerekir.
  2. get_args() işlevi, ayarlamak istediğiniz her hiperparametre için bir komut satırı bağımsız değişkeni tanımlar. Bu örnekte, ayarlanacak hiperparametreler öğrenme hızı, optimize edicideki momentum değeri ve modelin son gizli katmanındaki birim sayısıdır. Ancak diğerleriyle de deneme yapabilirsiniz. Bu bağımsız değişkenlerde iletilen değer, daha sonra kodda ilgili hiperparametreleri ayarlamak için kullanılır (ör. learning_rate = args.learning_rate ayarlanır).
  3. main() işlevinin sonunda, optimize etmek istediğiniz metriği tanımlamak için hypertune kitaplığı kullanılır. TensorFlow'da Keras model.fit yöntemi, History nesnesini döndürür. History.history özelliği, eğitim kaybı değerlerinin ve metrik değerlerinin ardışık dönemlerdeki kaydıdır. Doğrulama verilerini model.fit öğesine iletirseniz History.history özelliği, doğrulama kaybını ve metrik değerlerini de içerir. Örneğin, doğrulama verileriyle üç dönem boyunca bir modeli eğittiyseniz ve metrik olarak accuracy sağladıysanız History.history özelliği aşağıdaki sözlüğe benzer görünür.
{
 "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
 ]

Hiperparametre ayarlama hizmetinin, modelin doğrulama doğruluğunu en üst düzeye çıkaran değerleri bulmasını istiyorsanız metriği val_accuracy listesinin son girişi (veya NUM_EPOCS - 1) olarak tanımlarsınız. Ardından, bu metriği HyperTune örneğine iletin. hyperparameter_metric_tag için istediğiniz dizeyi seçebilirsiniz ancak hiperparametre ayarlama işini başlattığınızda bu dizeyi tekrar kullanmanız gerekir.

6. Kodu container mimarisine alma

Kodunuzu kapsayıcılaştırmanın ilk adımı Dockerfile oluşturmaktır. Dockerfile'da, görüntüyü çalıştırmak için gereken tüm komutları eklersiniz. Bu işlem, gerekli tüm kitaplıkları yükler ve eğitim kodu için giriş noktasını ayarlar.

1. adım: Dockerfile yazın

Terminalinizde vertex-codelab dizininde olduğunuzdan emin olun ve boş bir Dockerfile oluşturun:

touch Dockerfile

vertex-codelab dizininizde artık şunlar olmalıdır:

+ Dockerfile
+ trainer/
    + task.py

Dockerfile'ı açın ve aşağıdakileri kopyalayın:

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"]

Bu Dockerfile, Deep Learning Container TensorFlow Enterprise 2.7 GPU Docker görüntüsünü kullanır. Google Cloud'daki Deep Learning Containers'da birçok yaygın makine öğrenimi ve veri bilimi çerçevesi önceden yüklenmiş olarak gelir. Bu görüntüyü indirdikten sonra bu Dockerfile, eğitim kodu için giriş noktasını ayarlar.

2. adım: Kapsayıcıyı oluşturun

Terminalinizde, projeniz için bir ortam değişkeni tanımlamak üzere aşağıdakileri çalıştırın. your-cloud-project yerine projenizin kimliğini yazdığınızdan emin olun:

PROJECT_ID='your-cloud-project'

Google Container Registry'deki container görüntünüzün URI'siyle bir değişken tanımlayın:

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

Docker'ı yapılandırma

gcloud auth configure-docker

Ardından, vertex-codelab dizininizin kökünden aşağıdaki komutu çalıştırarak kapsayıcıyı oluşturun:

docker build ./ -t $IMAGE_URI

Son olarak, Google Container Registry'ye aktarın:

docker push $IMAGE_URI

3. adım: Cloud Storage paketi oluşturun

Eğitim işimizde, hazırlama paketinin yolunu ileteceğiz.

Projenizde yeni bir paket oluşturmak için Terminalinizde aşağıdakileri çalıştırın.

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

7. Hiperparametre ayarlama işini başlatma

1. adım: Hiperparametre ayarlama ile özel eğitim işi oluşturun

Başlatıcıdan yeni bir TensorFlow 2 not defteri açın.

new_notebook

Vertex AI Python SDK'sını içe aktarın.

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

Hiperparametre ayarlama işini başlatmak için önce makine türünü ve Docker görüntüsünü belirten worker_pool_specs tanımlamanız gerekir. Aşağıdaki spesifikasyon, iki NVIDIA Tesla V100 GPU'ya sahip bir makineyi tanımlar.

image_uri içindeki {PROJECT_ID} yerine projenizi yazmanız gerekir.

# 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"
    }
}]

Ardından, optimize etmek istediğiniz parametreleri belirten bir sözlük olan parameter_spec değerini tanımlayın. Sözlük anahtarı, her hiperparametre için komut satırı bağımsız değişkenine atadığınız dizedir. Sözlük değeri ise parametre spesifikasyonudur.

Her hiperparametre için Tür'ü ve ayarlama hizmetinin deneyeceği değerlerin sınırlarını tanımlamanız gerekir. Hiperparametreler; Double, Integer, Categorical veya Discrete türünde olabilir. Çift veya Tam Sayı türünü seçerseniz minimum ve maksimum değer sağlamanız gerekir. Kategorik veya Ayrı seçeneğini belirlerseniz değerleri sağlamanız gerekir. Çift ve Tam Sayı türleri için ölçekleme değerini de sağlamanız gerekir. En iyi ölçeği seçme hakkında daha fazla bilgiyi bu videoda bulabilirsiniz.

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

Tanımlanacak son özellik, optimize edilecek metriği temsil eden bir sözlük olan metric_spec'dır. Sözlük anahtarı, eğitim uygulama kodunuzda ayarladığınız hyperparameter_metric_tag, değer ise optimizasyon hedefidir.

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

Özellikler tanımlandıktan sonra, işinizi her bir hiperparametre ayarlama denemesinde çalıştırmak için kullanılacak ortak özellik olan CustomJob oluşturursunuz.

{YOUR_BUCKET} ifadesini daha önce oluşturduğunuz paketle değiştirmeniz gerekir.

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

Ardından, HyperparameterTuningJob oluşturup çalıştırın.

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

Dikkat edilmesi gereken birkaç nokta vardır:

  • max_trial_count: Hizmetin çalıştıracağı deneme sayısına bir üst sınır koymanız gerekir. Daha fazla deneme genellikle daha iyi sonuçlar verir ancak ek denemelerin, optimize etmeye çalıştığınız metrik üzerinde çok az etkisi olacağı veya hiç etkisi olmayacağı bir nokta vardır. Daha az sayıda denemeyle başlayıp ölçeği büyütmeden önce seçtiğiniz hiperparametrelerin ne kadar etkili olduğunu anlamak en iyi uygulamadır.
  • parallel_trial_count: Paralel denemeler kullanıyorsanız hizmet, birden fazla eğitim işleme kümesi sağlar. Paralel deneme sayısını artırmak, hiperparametre ince ayarı işinin çalışması için gereken süreyi azaltır ancak işin genel etkinliğini düşürebilir. Bunun nedeni, varsayılan ayarlama stratejisinin sonraki denemelerde değer ataması hakkında bilgi vermek için önceki denemelerin sonuçlarını kullanmasıdır.
  • search_algorithm: Arama algoritmasını grid, random veya default (None) olarak ayarlayabilirsiniz. Varsayılan seçenek, olası hiperparametre değerleri alanında arama yapmak için Bayes optimizasyonunu uygular ve önerilen algoritmadır. Bu algoritma hakkında daha fazla bilgiyi burada bulabilirsiniz.

İş başladıktan sonra, HYPERPARAMETER TUNING JOBS (Hiperparametre ayarlama işleri) sekmesindeki kullanıcı arayüzünde durumu takip edebilirsiniz.

HP_job

İş tamamlandıktan sonra, hiperparametre değerlerinin en iyi kombinasyonunu bulmak için denemelerinizin sonuçlarını görüntüleyebilir ve sıralayabilirsiniz.

HP_results

🎉 Tebrikler! 🎉

Vertex AI'ı kullanarak şunları yapmayı öğrendiniz:

  • Dağıtılmış eğitimle hiperparametre ayarlama işi çalıştırma

Vertex AI'ın farklı bölümleri hakkında daha fazla bilgi edinmek için belgelere göz atın.

8. Temizleme

Not defterini 60 dakika boşta kaldıktan sonra zaman aşımına uğrayacak şekilde yapılandırdığımız için örneği kapatmamız gerekmez. Örneği manuel olarak kapatmak istiyorsanız konsolun Vertex AI Workbench bölümündeki Durdur düğmesini tıklayın. Not defterini tamamen silmek isterseniz Sil düğmesini tıklayın.

delete

Cloud Console'unuzdaki gezinme menüsünü kullanarak depolama paketini silmek için Storage'a gidin, paketinizi seçin ve Sil'i tıklayın:

Depolama alanını silme