प्रोटोटाइप से प्रोडक्शन के लिए: हाइपर पैरामीटर ट्यूनिंग

1. खास जानकारी

इस लैब में, Vertex AI की ट्रेनिंग पर हाइपर पैरामीटर ट्यूनिंग जॉब चलाने के लिए, आपको Vertex AI का इस्तेमाल करना होगा.

यह लैब, प्रोडक्शन का प्रोटोटाइप वीडियो सीरीज़ का हिस्सा है. इस लैब को आज़माने से पहले, पिछला लैब पूरा करना न भूलें. ज़्यादा जानने के लिए, इससे जुड़ी वीडियो सीरीज़ देखें:

.

आपको ये सब सीखने को मिलेगा

आपको, इनके बारे में जानकारी मिलेगी:

  • अपने-आप हाइपर पैरामीटर ट्यूनिंग के लिए, ट्रेनिंग ऐप्लिकेशन कोड में बदलाव करें
  • Vertex AI Python SDK की मदद से, हाइपर पैरामीटर ट्यूनिंग जॉब को कॉन्फ़िगर और लॉन्च करना

Google Cloud पर इस लैब को चलाने की कुल लागत करीब $1 है.

2. Vertex AI के बारे में जानकारी

यह लैब, Google Cloud पर उपलब्ध एआई (AI) प्रॉडक्ट के सबसे नए वर्शन का इस्तेमाल करती है. Vertex AI, Google Cloud के सभी मशीन लर्निंग प्लैटफ़ॉर्म को आसानी से डेवलप करने के लिए इंटिग्रेट करता है. पहले, AutoML और कस्टम मॉडल की मदद से ट्रेन किए गए मॉडल अलग-अलग सेवाओं से ऐक्सेस किए जा सकते थे. नई सेवा में, एक एपीआई से नए प्रॉडक्ट और इन दोनों का इस्तेमाल किया जा सकता है. आपके पास मौजूदा प्रोजेक्ट को Vertex AI पर माइग्रेट करने का विकल्प भी है.

Vertex AI में कई तरह के प्रॉडक्ट शामिल हैं, जो मशीन लर्निंग के वर्कफ़्लो को मैनेज करने में मदद करते हैं. यह लैब, यहां हाइलाइट किए गए प्रॉडक्ट पर फ़ोकस करेगी: ट्रेनिंग और वर्कबेंच

Vertex प्रॉडक्ट की खास जानकारी

3. अपना एनवायरमेंट सेट अप करें

अपना एनवायरमेंट सेट अप करने के लिए, Vertex AI की मदद से कस्टम मॉडल की ट्रेनिंग लैब में दिए गए चरणों को पूरा करें.

4. ट्रेनिंग ऐप्लिकेशन कोड को कंटेनर में बदलें

आपको इस ट्रेनिंग जॉब को Vertex AI में सबमिट करने के लिए, अपने ट्रेनिंग ऐप्लिकेशन कोड को Docker कंटेनर में डालना होगा. इसके बाद, इस कंटेनर को Google Artifact Registry में भेजना होगा. इस तरीके का इस्तेमाल करके, किसी भी फ़्रेमवर्क के साथ बनाए गए मॉडल को ट्रेनिंग दी जा सकती है और उसे बेहतर बनाया जा सकता है.

शुरू करने के लिए, पिछली लैब में बनाई गई वर्कबेंच नोटबुक के लॉन्चर मेन्यू से टर्मिनल विंडो खोलें.

टर्मिनल को नोटबुक में खोलें

पहला चरण: ट्रेनिंग कोड लिखना

flowers-hptune नाम की एक नई डायरेक्ट्री बनाएं और उसमें सीडी लें:

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} को Cloud Storage बकेट से बदलना होगा, जहां आपने लैब 1 में फूलों का डेटासेट सेव किया था.

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

कंटेनर बनाने से पहले, आइए कोड को गहराई से समझें. हाइपर पैरामीटर ट्यूनिंग सेवा के इस्तेमाल के लिए कुछ कॉम्पोनेंट खास तौर पर उपलब्ध होते हैं.

  1. स्क्रिप्ट, hypertune लाइब्रेरी को इंपोर्ट करती है.
  2. get_args() फ़ंक्शन, ऐसे हर हाइपर पैरामीटर के लिए कमांड लाइन आर्ग्युमेंट तय करता है जिसे आपको ट्यून करना है. इस उदाहरण में, जिन हाइपर पैरामीटर को ट्यून किया जाएगा वे लर्निंग रेट, ऑप्टिमाइज़र में मोमेंटम वैल्यू, और मॉडल की आखिरी छिपी लेयर में यूनिट की संख्या हैं, लेकिन दूसरे लोगों के साथ बेझिझक एक्सपेरिमेंट किया जा सकता है. इसके बाद, उन आर्ग्युमेंट में पास की गई वैल्यू का इस्तेमाल, कोड में उससे जुड़े हाइपर पैरामीटर को सेट करने के लिए किया जाता है.
  3. main() फ़ंक्शन के आखिर में, hypertune लाइब्रेरी का इस्तेमाल उस मेट्रिक को तय करने के लिए किया जाता है जिसे आपको ऑप्टिमाइज़ करना है. TensorFlow में, keras model.fit तरीका एक History ऑब्जेक्ट दिखाता है. History.history एट्रिब्यूट, एक के बाद एक चलने वाले epoch का इस्तेमाल करके, ट्रेनिंग में हुई कमी की वैल्यू और मेट्रिक की वैल्यू का रिकॉर्ड है. अगर आपने पुष्टि करने के लिए डेटा को model.fit पर पास किया है, तो History.history एट्रिब्यूट में, पुष्टि न होने का डेटा और मेट्रिक की वैल्यू भी शामिल होंगी. उदाहरण के लिए, अगर आपने तीन epoch के लिए एक मॉडल को ट्रेनिंग दी है. इसमें, पुष्टि करने वाला डेटा इस्तेमाल किया गया है और 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 के लिए अपनी पसंद की कोई भी स्ट्रिंग चुनी जा सकती है. हालांकि, हाइपर पैरामीटर ट्यूनिंग जॉब को बंद करने पर, आपको इस स्ट्रिंग का फिर से इस्तेमाल करना होगा.

दूसरा चरण: Dockerfile बनाएं

अपने कोड को कंटेनर में रखने के लिए, आपको Dockerfile बनाना होगा. Dockerfile में, आप इमेज को चलाने के लिए ज़रूरी सभी कमांड शामिल करेंगे. यह सभी ज़रूरी लाइब्रेरी को इंस्टॉल करेगा और ट्रेनिंग कोड के लिए एंट्री पॉइंट सेट अप करेगा.

अपने Terminal से, अपनी 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"]

तीसरा चरण: कंटेनर बनाना

अपने प्रोजेक्ट के लिए env वैरिएबल तय करने के लिए, अपने Terminal से, इसे चलाएं और your-cloud-project को अपने प्रोजेक्ट के आईडी से बदलना न भूलें:

PROJECT_ID='your-cloud-project'

Artifact Registry में, डेटा स्टोर करने की सुविधा के बारे में बताना. हम पहले लैब में बनाए गए रेपो का इस्तेमाल करेंगे.

REPO_NAME='flower-app'

Google Artifact Registry में, अपनी कंटेनर इमेज के यूआरआई के साथ वैरिएबल तय करें:

IMAGE_URI=us-central1-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/flower_image_hptune:latest

डॉकर कॉन्फ़िगर करें

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 का इस्तेमाल करके, हाइपर पैरामीटर ट्यूनिंग जॉब को कॉन्फ़िगर और सबमिट करने का तरीका बताया गया है.

लॉन्चर से, TensorFlow 2 नोटबुक बनाएं.

new_notebook

Vertex AI SDK टूल इंपोर्ट करें.

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

हाइपर पैरामीटर ट्यूनिंग जॉब को लॉन्च करने के लिए, आपको पहले worker_pool_specs तय करना होगा. इससे मशीन टाइप और Docker इमेज की जानकारी मिलती है. नीचे दिए गए स्पेसिफ़िकेशन में, दो NVIDIA Tesla V100 जीपीयू के साथ एक मशीन के बारे में बताया गया है.

आपको अपने प्रोजेक्ट के 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 तय करें. यह एक डिक्शनरी है, जिसमें उन पैरामीटर के बारे में बताया जाता है जिन्हें आपको ऑप्टिमाइज़ करना है. डिक्शनरी कुंजी वह स्ट्रिंग होती है जो आपने हर हाइपर पैरामीटर के लिए कमांड लाइन आर्ग्युमेंट को असाइन की होती है. डिक्शनरी की वैल्यू, पैरामीटर की खास जानकारी होती है.

हर हाइपर पैरामीटर के लिए, आपको टाइप और ट्यूनिंग सेवा की ओर से आज़माई जाने वाली वैल्यू की सीमाएं तय करनी होंगी. हाइपर पैरामीटर दो तरह के हो सकते हैं. जैसे, डबल, पूर्णांक, कैटगरी या डिस्क्रीट. अगर आपने टाइप डबल या पूर्णांक चुना है, तो आपको कम से कम और ज़्यादा से ज़्यादा वैल्यू देनी होगी. अगर आपने 'कैटगरी' या 'अलग-अलग' विकल्प चुना है, तो आपको वैल्यू भी देनी होगी. डबल और पूर्णांक टाइप के लिए, आपको स्केलिंग वैल्यू भी देनी होगी. सबसे बढ़िया स्केल चुनने के बारे में ज़्यादा जानने के लिए यह वीडियो देखें.

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

खास जानकारी तय हो जाने के बाद, आपको Custom! बनाना चाहिए. यह वह सामान्य जानकारी है जिसका इस्तेमाल हाइपर पैरामीटर ट्यूनिंग ट्रायल पर आपका काम चलाने के लिए किया जाएगा.

आपको {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: खोज एल्गोरिदम को ग्रिड, रैंडम या डिफ़ॉल्ट (कोई नहीं) पर सेट किया जा सकता है. डिफ़ॉल्ट विकल्प, संभावित हाइपर पैरामीटर वैल्यू के स्पेस को खोजने के लिए बेज़ियन ऑप्टिमाइज़ेशन को लागू करता है. यह सुझाया गया एल्गोरिदम है. इस एल्गोरिदम के बारे में यहां ज़्यादा जानें.

कंसोल में, आपको अपने काम की प्रोग्रेस दिखेगी.

hp_job

इसके खत्म होने पर, आपको हर ट्रायल के नतीजे दिखेंगे. साथ ही, यह भी दिखेगा कि वैल्यू के किस सेट ने सबसे अच्छा परफ़ॉर्म किया.

hp_results

🎉 बधाई हो! 🎉

आपने Vertex AI को इस्तेमाल करने का तरीका जान लिया है, ताकि:

  • अपने-आप काम करने वाले हाइपर पैरामीटर को ट्यून करने का जॉब चलाएं

Vertex के अलग-अलग हिस्सों के बारे में ज़्यादा जानने के लिए, दस्तावेज़ देखें.

6. साफ़-सफ़ाई सेवा

हमने notebook को इस तरह से कॉन्फ़िगर किया है कि उसका समय 60 मिनट बाद बंद हो जाए. इसलिए, हमें इंस्टेंस बंद होने की चिंता करने की ज़रूरत नहीं है. अगर आपको मैन्युअल तरीके से इंस्टेंस शट डाउन करना है, तो कंसोल के Vertex AI Workbench सेक्शन में, 'रोकें' बटन पर क्लिक करें. अगर आपको नोटबुक को पूरी तरह से मिटाना है, तो मिटाएं बटन पर क्लिक करें.

इंस्टेंस रोकें

अपने Cloud Console में नेविगेशन मेन्यू का इस्तेमाल करके, स्टोरेज बकेट मिटाने के लिए स्टोरेज पर जाएं. इसके बाद, अपनी बकेट चुनें और मिटाएं पर क्लिक करें:

स्टोरेज मिटाएं