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

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

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

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

.

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

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

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

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

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

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

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

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

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

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

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

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

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

Notebook में टर्मिनल खोलना

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

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} को उस Cloud Storage बकेट से बदलना होगा जहां आपने Lab 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 एट्रिब्यूट में, पुष्टि न होने का डेटा और मेट्रिक की वैल्यू भी शामिल होंगी. उदाहरण के लिए, अगर आपने पुष्टि करने वाले डेटा के साथ तीन एपिसोड के लिए मॉडल को ट्रेन किया है और मेट्रिक के तौर पर 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 में, आप इमेज को चलाने के लिए ज़रूरी सभी कमांड शामिल करेंगे. इससे सभी ज़रूरी लाइब्रेरी इंस्टॉल हो जाएंगी और ट्रेनिंग कोड के लिए एंट्री पॉइंट सेट अप हो जाएगा.

अपने टर्मिनल से, flowers-hptune डायरेक्ट्री के रूट में एक खाली Dockerfile बनाएं:

touch Dockerfile

अब आपको अपनी flowers-hptune/ डायरेक्ट्री में ये चीज़ें दिखनी चाहिए:

+ Dockerfile
+ trainer/
    + task.py

Dockerfile खोलें और इसमें नीचे दिया गया कोड कॉपी करें. आपको पता चलेगा कि यह 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

Docker कॉन्फ़िगर करना

gcloud auth configure-docker \
    us-central1-docker.pkg.dev

इसके बाद, अपनी flower-hptune डायरेक्ट्री के रूट से, कंटेनर बनाने के लिए यह कमांड चलाएं:

docker build ./ -t $IMAGE_URI

आखिर में, उसे Artifact Registry में भेजें:

docker push $IMAGE_URI

आर्टफ़ैक्ट रजिस्ट्री में कंटेनर को पुश करने के बाद, अब ट्रेनिंग जॉब शुरू की जा सकती है.

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

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

आपको {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. साफ़-सफ़ाई सेवा

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

इंस्टेंस को बंद करना

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

स्टोरेज मिटाना