Cloud AI Platform पर PyTorch मॉडल को ट्यून करने वाली ट्रेनिंग और हाइपर पैरामीटर

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

इस लैब में, आपको Google Cloud पर मशीन लर्निंग का पूरा वर्कफ़्लो बताया जाएगा. इसके लिए, आपको PyTorch का इस्तेमाल करके अपना मॉडल बनाना होगा. Cloud AI Platform Notebooks एनवायरमेंट की मदद से, आपको हाइपर पैरामीटर ट्यूनिंग के साथ एआई प्लैटफ़ॉर्म ट्रेनिंग पर चलाने के लिए, अपनी ट्रेनिंग के काम को पैकेज करने का तरीका पता चलेगा.

आपने क्या सीखा

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

  • AI Platform Notebooks इंस्टेंस बनाना
  • PyTorch मॉडल बनाएं
  • AI Platform की ट्रेनिंग में हाइपर पैरामीटर ट्यूनिंग की मदद से, अपने मॉडल को ट्रेनिंग दें

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

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

इस कोडलैब को चलाने के लिए, आपके पास Google Cloud Platform का ऐसा प्रोजेक्ट होना चाहिए जिसमें बिलिंग की सुविधा चालू हो. प्रोजेक्ट बनाने के लिए, यहां दिए गए निर्देशों का पालन करें.

पहला चरण: Cloud AI Platform मॉडल API को चालू करना

अपने Cloud Console के एआई प्लैटफ़ॉर्म मॉडल सेक्शन पर जाएं और अगर यह पहले से चालू नहीं है, तो 'चालू करें' पर क्लिक करें.

d0d38662851c6af3.png

दूसरा चरण: Compute Engine API चालू करना

Compute Engine पर जाएं और अगर यह पहले से चालू नहीं है, तो चालू करें को चुनें. आपको अपना notebook इंस्टेंस बनाने के लिए इसकी ज़रूरत होगी.

तीसरा चरण: AI Platform Notebooks का इंस्टेंस बनाना

अपने Cloud Console के AI Platform Notebooks सेक्शन पर जाएं और नया इंस्टेंस पर क्लिक करें. इसके बाद, नया PyTorch इंस्टेंस टाइप (GPs के बिना) चुनें:

892b7588f940d145.png

डिफ़ॉल्ट विकल्पों का इस्तेमाल करें या अगर आप चाहें, तो इसे कोई कस्टम नाम दें और फिर बनाएं पर क्लिक करें. इंस्टेंस बनाने के बाद, JupyterLab खोलें को चुनें:

63d2cf44801c2df5.png

इसके बाद, लॉन्चर से Python 3 Notebook का इंस्टेंस खोलें:

de4c86c6c7f9438f.png

आप शुरू करने के लिए तैयार हैं!

पांचवां चरण: Python पैकेज इंपोर्ट करना

अपनी नोटबुक के पहले सेल में, नीचे दिए गए इंपोर्ट जोड़ें और सेल को चलाएं. इसे सबसे ऊपर दिए गए मेन्यू में मौजूद राइट ऐरो बटन को दबाकर या command-enter दबाकर इसे चलाया जा सकता है:

import datetime
import numpy as np
import os
import pandas as pd
import time

आपको दिखेगा कि हम यहां PyTorch को इंपोर्ट नहीं कर रहे हैं. इसकी वजह यह है कि हम ट्रेनिंग का काम AI Platform की ट्रेनिंग पर कर रहे हैं, न कि हमारे Notebook इंस्टेंस से.

3. ट्रेनिंग जॉब के लिए पैकेज बनाएं

AI Platform की ट्रेनिंग के लिए ट्रेनिंग प्रोग्राम चलाने के लिए, हमें Notebooks इंस्टेंस में लोकल लेवल पर पैकेज किया गया ट्रेनिंग कोड चाहिए. साथ ही, अपने काम के लिए ऐसेट सेव करने के लिए Cloud Storage बकेट की ज़रूरत होगी. सबसे पहले, हम एक स्टोरेज बकेट बनाएंगे. अगर आपके पास पहले से कोई चरण है, तो इस चरण को छोड़ा जा सकता है.

पहला चरण: हमारे मॉडल के लिए Cloud Storage बकेट बनाना

आइए, सबसे पहले कुछ ऐसे एनवायरमेंट वैरिएबल तय करते हैं जिनका इस्तेमाल हम कोडलैब के बाकी हिस्से में करेंगे. नीचे दी गई वैल्यू में, अपने Google Cloud प्रोजेक्ट का नाम और उस क्लाउड स्टोरेज बकेट का नाम डालें जिसे आपको बनाना है (यह दुनिया भर में अलग होना चाहिए):

# Update these to your own GCP project, model, and version names
GCP_PROJECT = 'your-gcp-project'
BOCKET_URL = 'gs://storage_bucket_name'

अब हम एक स्टोरेज बकेट बनाने के लिए तैयार हैं. इसे हम ट्रेनिंग जॉब शुरू करने पर पॉइंट करेंगे.

बकेट बनाने के लिए, अपनी नोटबुक में इस gsutil कमांड को चलाएं:

!gsutil mb $BUCKET_URL

दूसरा चरण: Python पैकेज के लिए शुरुआती फ़ाइलें बनाना

AI Platform पर ट्रेनिंग जॉब चलाने के लिए, हमें अपने कोड को Python पैकेज के तौर पर कॉन्फ़िगर करना होगा. इसमें हमारी रूट डायरेक्ट्री में एक setup.py फ़ाइल होती है, जो किसी भी बाहरी पैकेज डिपेंडेंसी के बारे में बताती है. साथ ही, इसमें हमारे पैकेज (यहां हम इसे trainer/ कहेंगे) के नाम वाली एक सबडायरेक्ट्री और इस सबडायरेक्ट्री में एक खाली __init__.py फ़ाइल होती है.

सबसे पहले, आइए अपनी setup.py फ़ाइल लिखें. हम अपने इंस्टेंस में फ़ाइल सेव करने के लिए, iPython %%writefile Magic का इस्तेमाल कर रहे हैं. यहां हमने तीन बाहरी लाइब्रेरी तय की हैं जिनका इस्तेमाल हम अपने ट्रेनिंग कोड में करेंगे: PyTorch, Scikit-learn, और Pandas:

%%writefile setup.py
from setuptools import find_packages
from setuptools import setup

REQUIRED_PACKAGES = ['torch>=1.5', 'scikit-learn>=0.20', 'pandas>=1.0']

setup(
    name='trainer',
    version='0.1',
    install_requires=REQUIRED_PACKAGES,
    packages=find_packages(),
    include_package_data=True,
    description='My training application package.'
)

अब अपनी ट्रेनर/ डायरेक्ट्री और उसमें मौजूद खाली init.py फ़ाइल बनाते हैं. Python इस फ़ाइल का इस्तेमाल यह पता लगाने के लिए करता है कि यह एक पैकेज है:

!mkdir trainer
!touch trainer/__init__.py

अब हम ट्रेनिंग जॉब बनाने के लिए तैयार हैं.

4. डेटासेट की झलक देखना

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

पहला चरण: BigQuery नेटिविटी डेटासेट डाउनलोड करना

आपके लिए Cloud Storage में उपलब्ध कराए गए डेटासेट के वर्शन को Pandas DataFrame में डाउनलोड करें और उसकी झलक देखें.

natality = pd.read_csv('https://storage.googleapis.com/ml-design-patterns/natality.csv')
natality.head()

इस डेटासेट में सिर्फ़ 1,00,000 से कम पंक्तियां हैं. हम बच्चे के जन्म के वज़न का अनुमान लगाने के लिए, इन पांच सुविधाओं का इस्तेमाल करेंगे: मां और पिता की उम्र, गर्भधारण के हफ़्ते, मां का वज़न में बढ़ोतरी होना, और बच्चे के लिंग को बूलियन के तौर पर दिखाया जाएगा.

5. हाइपर पैरामीटर ट्यूनिंग के साथ ट्रेनिंग का काम तय करना

हम अपने द्वारा पहले बनाई गई ट्रेनर/ सबडायरेक्ट्री के अंदर, अपनी ट्रेनिंग स्क्रिप्ट को Model.py नाम की फ़ाइल में लिखेंगे. हमारी ट्रेनिंग का टास्क, AI Platform की ट्रेनिंग पर किया जाएगा. साथ ही, यह एआई प्लैटफ़ॉर्म की हाइपर पैरामीटर ट्यूनिंग सेवा का इस्तेमाल करेगा, ताकि बेज़ियन ऑप्टिमाइज़ेशन का इस्तेमाल करने वाले हमारे मॉडल के लिए सबसे सही हाइपर पैरामीटर का पता लगाया जा सके.

पहला चरण: ट्रेनिंग स्क्रिप्ट बनाना

सबसे पहले, हमारी ट्रेनिंग स्क्रिप्ट की मदद से Python फ़ाइल बनाते हैं. इसके बाद, हम यह देखेंगे कि इसमें क्या हो रहा है. इस %%writefile निर्देश को चलाने से स्थानीय Python फ़ाइल पर मॉडल कोड लिख दिया जाएगा:

%%writefile trainer/model.py
import argparse
import hypertune
import numpy as np
import pandas as pd
import torch
import torch.nn as nn
import torch.optim as optim

from sklearn.utils import shuffle
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import normalize

def get_args():
    """Argument parser.
    Returns:
        Dictionary of arguments.
    """
    parser = argparse.ArgumentParser(description='PyTorch MNIST')
    parser.add_argument('--job-dir',  # handled automatically by AI Platform
                        help='GCS location to write checkpoints and export ' \
                             'models')
    parser.add_argument('--lr',  # Specified in the config file
                        type=float,
                        default=0.01,
                        help='learning rate (default: 0.01)')
    parser.add_argument('--momentum',  # Specified in the config file
                        type=float,
                        default=0.5,
                        help='SGD momentum (default: 0.5)')
    parser.add_argument('--hidden-layer-size',  # Specified in the config file
                        type=int,
                        default=8,
                        help='hidden layer size')
    args = parser.parse_args()
    return args

def train_model(args):
    # Get the data
    natality = pd.read_csv('https://storage.googleapis.com/ml-design-patterns/natality.csv')
    natality = natality.dropna()
    natality = shuffle(natality, random_state = 2)
    natality.head()

    natality_labels = natality['weight_pounds']
    natality = natality.drop(columns=['weight_pounds'])


    train_size = int(len(natality) * 0.8)
    traindata_natality = natality[:train_size]
    trainlabels_natality = natality_labels[:train_size]

    testdata_natality = natality[train_size:]
    testlabels_natality = natality_labels[train_size:]

    # Normalize and convert to PT tensors
    normalized_train = normalize(np.array(traindata_natality.values), axis=0)
    normalized_test = normalize(np.array(testdata_natality.values), axis=0)

    train_x = torch.Tensor(normalized_train)
    train_y = torch.Tensor(np.array(trainlabels_natality))

    test_x = torch.Tensor(normalized_test)
    test_y = torch.Tensor(np.array(testlabels_natality))

    # Define our data loaders
    train_dataset = torch.utils.data.TensorDataset(train_x, train_y)
    train_dataloader = torch.utils.data.DataLoader(train_dataset, batch_size=128, shuffle=True)

    test_dataset = torch.utils.data.TensorDataset(test_x, test_y)
    test_dataloader = torch.utils.data.DataLoader(test_dataset, batch_size=128, shuffle=False)

    # Define the model, while tuning the size of our hidden layer
    model = nn.Sequential(nn.Linear(len(train_x[0]), args.hidden_layer_size),
                          nn.ReLU(),
                          nn.Linear(args.hidden_layer_size, 1))
    criterion = nn.MSELoss()

    # Tune hyperparameters in our optimizer
    optimizer = optim.SGD(model.parameters(), lr=args.lr, momentum=args.momentum)
    epochs = 20
    for e in range(epochs):
        for batch_id, (data, label) in enumerate(train_dataloader):
            optimizer.zero_grad()
            y_pred = model(data)
            label = label.view(-1,1)
            loss = criterion(y_pred, label)
            
            loss.backward()
            optimizer.step()


    val_mse = 0
    num_batches = 0
    # Evaluate accuracy on our test set
    with torch.no_grad():
        for i, (data, label) in enumerate(test_dataloader):
            num_batches += 1
            y_pred = model(data)
            mse = criterion(y_pred, label.view(-1,1))
            val_mse += mse.item()


    avg_val_mse = (val_mse / num_batches)

    # Report the metric we're optimizing for to AI Platform's HyperTune service
    # In this example, we're mimizing error on our test set
    hpt = hypertune.HyperTune()
    hpt.report_hyperparameter_tuning_metric(
        hyperparameter_metric_tag='val_mse',
        metric_value=avg_val_mse,
        global_step=epochs        
    )

def main():
    args = get_args()
    print('in main', args)
    train_model(args)

if __name__ == '__main__':
    main()

ट्रेनिंग जॉब में दो फ़ंक्शन होते हैं, जिनमें सबसे ज़्यादा काम होता है.

  • get_args(): यह ट्रेनिंग जॉब बनाते समय, पास किए जाने वाले कमांड लाइन आर्ग्युमेंट को पार्स करता है. इनमें वे हाइपर पैरामीटर भी शामिल होते हैं जिन्हें हम AI Platform को ऑप्टिमाइज़ करना चाहते हैं. इस उदाहरण में, हमारे आर्ग्युमेंट की सूची में सिर्फ़ वे हाइपर पैरामीटर शामिल हैं जिन्हें हम ऑप्टिमाइज़ करेंगे – हमारे मॉडल की लर्निंग रेट, मोमेंट, और हमारी छिपी हुई लेयर में मौजूद न्यूरॉन की संख्या.
  • train_model(): यहां हम डेटा को Pandas DataFrame में डाउनलोड करते हैं, उसे नॉर्मलाइज़ करते हैं, और उसे PyTorch Tensors में बदलते हैं. इसके बाद, हम अपना मॉडल तय करते हैं. अपना मॉडल बनाने के लिए, हम PyTorch nn.Sequential API का इस्तेमाल कर रहे हैं. इससे हमें अपने मॉडल को लेयर के स्टैक के तौर पर तय करने में मदद मिलती है:
model = nn.Sequential(nn.Linear(len(train_x[0]), args.hidden_layer_size),
                      nn.ReLU(),
                      nn.Linear(args.hidden_layer_size, 1))

ध्यान दें कि हम अपने मॉडल की छिपी हुई लेयर के साइज़ की हार्डकोड करने के बजाय, इस हाइपर पैरामीटर को बना रहे हैं. AI Platform हमारे लिए बेहतर होगा. इसके बारे में ज़्यादा जानकारी अगले सेक्शन में मिलेगी.

दूसरा चरण: AI Platform की हाइपर पैरामीटर ट्यूनिंग सेवा का इस्तेमाल करना

अलग-अलग हाइपर पैरामीटर वैल्यू को मैन्युअल तरीके से आज़माने और हर बार अपने मॉडल को फिर से ट्रेनिंग देने के बजाय, हम Cloud AI Platform की हाइपर पैरामीटर ऑप्टिमाइज़ेशन सेवा का इस्तेमाल करेंगे. अगर हम हाइपर पैरामीटर आर्ग्युमेंट के साथ ट्रेनिंग जॉब को सेट अप करते हैं, तो AI Platform बायज़ियन ऑप्टिमाइज़ेशन का इस्तेमाल करके, हमारे बताए गए हाइपर पैरामीटर के लिए सबसे सही वैल्यू का पता लगाएगा.

हाइपर पैरामीटर ट्यूनिंग में, एक ट्रायल में हमारे मॉडल का एक ट्रेनिंग रन शामिल होता है, जिसमें हाइपर पैरामीटर वैल्यू के खास कॉम्बिनेशन होते हैं. हम कितने ट्रायल चलाए जाते हैं, इसके आधार पर AI Platform पूरे हो चुके ट्रायल के नतीजों का इस्तेमाल करके, आने वाले समय में चुने जाने वाले हाइपर पैरामीटर को ऑप्टिमाइज़ करेगा. हाइपर पैरामीटर ट्यूनिंग को कॉन्फ़िगर करने के लिए, जब हम ऑप्टिमाइज़ किए जा रहे हर हाइपर पैरामीटर पर कुछ डेटा के साथ ट्रेनिंग शुरू करते हैं, तो हमें एक कॉन्फ़िगरेशन फ़ाइल पास करनी होती है.

इसके बाद, उस कॉन्फ़िगरेशन फ़ाइल को स्थानीय तौर पर बनाएं:

%%writefile config.yaml
trainingInput:
  hyperparameters:
    goal: MINIMIZE
    maxTrials: 10
    maxParallelTrials: 5
    hyperparameterMetricTag: val_mse
    enableTrialEarlyStopping: TRUE
    params:
    - parameterName: lr
      type: DOUBLE
      minValue: 0.0001
      maxValue: 0.1
      scaleType: UNIT_LINEAR_SCALE
    - parameterName: momentum
      type: DOUBLE
      minValue: 0.0
      maxValue: 1.0
      scaleType: UNIT_LINEAR_SCALE
    - parameterName: hidden-layer-size
      type: INTEGER
      minValue: 8
      maxValue: 32
      scaleType: UNIT_LINEAR_SCALE

हर हाइपर पैरामीटर के लिए, हम टाइप, वैल्यू की वह रेंज, और तय करते हैं जिसकी मदद से अलग-अलग ट्रायल के लिए वैल्यू बढ़ाई जा सकती है.

काम की शुरुआत में हम वह मेट्रिक भी तय करते हैं जिसके लिए हम ऑप्टिमाइज़ कर रहे हैं. ध्यान दें कि ऊपर दिए गए train_model() फ़ंक्शन के आखिर में, जब भी कोई ट्रायल पूरा होता है, तब हम AI Platform को इस मेट्रिक की रिपोर्ट करते हैं. यहां हम अपने मॉडल के मीन स्क्वेयर वाली गड़बड़ी को कम कर रहे हैं. इसलिए, हम उन हाइपर पैरामीटर का इस्तेमाल करना चाहते हैं जिनकी वजह से, हमारे मॉडल के लिए मीन स्क्वेयर वाली गड़बड़ी सबसे कम होती है. इस मेट्रिक (val_mse) का नाम, उस नाम से मैच होता है जिसका इस्तेमाल करके, मुफ़्त में आज़माने की अवधि के आखिर में report_hyperparameter_tuning_metric() को कॉल किया जाता है. इस नाम का इस्तेमाल, इसकी शिकायत करने के लिए किया जाता है.

6. AI Platform पर ट्रेनिंग जॉब शुरू करना

इस सेक्शन में, हम AI Platform पर हाइपर पैरामीटर ट्यूनिंग के साथ मॉडल ट्रेनिंग के जॉब की शुरुआत करेंगे.

पहला चरण: एनवायरमेंट के कुछ वैरिएबल तय करना

आइए, सबसे पहले कुछ ऐसे एनवायरमेंट वैरिएबल बनाते हैं जिनका इस्तेमाल हम ट्रेनिंग की शुरुआत में करेंगे. अगर आपको अपना काम किसी दूसरे क्षेत्र में चलाना है, तो नीचे दिया गया 'क्षेत्र' वैरिएबल अपडेट करें:

MAIN_TRAINER_MODULE = "trainer.model"
TRAIN_DIR = os.getcwd() + '/trainer'
JOB_DIR = BUCKET_URL + '/output'
REGION = "us-central1"

AI Platform पर मौजूद ट्रेनिंग की हर जॉब का एक अलग नाम होना चाहिए. टाइमस्टैंप का इस्तेमाल करके, अपने काम के नाम के लिए वैरिएबल तय करने के लिए, यह तरीका अपनाएं:

timestamp = str(datetime.datetime.now().time())
JOB_NAME = 'caip_training_' + str(int(time.time()))

दूसरा चरण: ट्रेनिंग का काम शुरू करें

हम gcloud, यानी Google Cloud सीएलआई का इस्तेमाल करके ट्रेनिंग जॉब बनाएंगे. हम ऊपर बताए गए वैरिएबल का रेफ़रंस देते हुए, इस कमांड को सीधे अपनी नोटबुक में चला सकते हैं:

!gcloud ai-platform jobs submit training $JOB_NAME \
        --scale-tier basic \
        --package-path $TRAIN_DIR \
        --module-name $MAIN_TRAINER_MODULE \
        --job-dir $JOB_DIR \
        --region $REGION \
        --runtime-version 2.1 \
        --python-version 3.7 \
        --config config.yaml

अगर आपका जॉब सही तरीके से बनाया गया है, तो लॉग मॉनिटर करने के लिए अपने AI Platform कंसोल के नौकरियां सेक्शन पर जाएं.

तीसरा चरण: अपने काम को मॉनिटर करें

कंसोल के जॉब सेक्शन में जाकर, उस नौकरी पर क्लिक करें जिसकी जानकारी आपने अभी-अभी शुरू की है:

c184167641bb7ed7.png

ट्रायल शुरू होने पर, आपको हर ट्रायल के लिए चुनी गई हाइपर पैरामीटर वैल्यू दिखेंगी:

787c053ef9110e6b.png

ट्रायल पूरा होने पर, आपकी ऑप्टिमाइज़ेशन मेट्रिक (इस मामले में val_mse) की नतीजे वाली वैल्यू यहां लॉग की जाएगी. इस काम को चलने में 15-20 मिनट लगेंगे और काम खत्म होने पर डैशबोर्ड कुछ इस तरह दिखाई देगा (सटीक मान अलग-अलग होंगे):

47ef6b9b4ecb532c.png

संभावित समस्याओं को डीबग करने और अपने काम पर ज़्यादा बारीकी से नज़र रखने के लिए, जॉब की जानकारी वाले पेज पर लॉग देखें पर क्लिक करें:

18c32dcd36351930.png

आपके मॉडल ट्रेनिंग कोड में मौजूद हर print() स्टेटमेंट यहां दिखेगा. अगर आपको समस्याएं आ रही हैं, तो और प्रिंट स्टेटमेंट जोड़ें और नई ट्रेनिंग जॉब शुरू करें.

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

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

अगर आपको इस notebook का इस्तेमाल जारी रखना है, तो हमारा सुझाव है कि इस्तेमाल में न होने पर इसे बंद कर दें. अपने Cloud Console में Notebook के यूज़र इंटरफ़ेस (यूआई) से, नोटबुक चुनें और फिर बंद करें चुनें:

879147427150b6c7.png

यदि आप इस लैब में बनाए गए सभी संसाधनों को हटाना चाहते हैं, तो इसे रोकने के बजाय बस नोटबुक इंस्टेंस को हटाएं.

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