Vertex AI: ضبط المعلَمة الفائقة الموزَّعة

1. نظرة عامة

في هذا التمرين المعملي، ستتعلم كيفية استخدام Vertex AI لضبط معلَمة فائقة والتدريب الموزَّع. يستخدم هذا التمرين المعملي TensorFlow لرمز النموذج، غير أنّ المفاهيم تنطبق على أطر عمل أخرى لتعلُّم الآلة أيضًا.

المعلومات التي تطّلع عليها

وستتعرّف على كيفية:

  • تدريب نموذج باستخدام التدريب الموزَّع على حاوية مخصَّصة
  • يمكنك بدء تجارب متعدّدة لرمز التدريب لضبط المَعلمة الفائقة آليًا.

تبلغ التكلفة الإجمالية لتشغيل هذا التمرين على Google Cloud حوالي $6 دولار أمريكي.

2. مقدّمة عن Vertex AI

يستخدم هذا البرنامج أحدث منتجات الذكاء الاصطناعي المتوفّرة على Google Cloud. تدمج Vertex AI حلول تعلُّم الآلة في Google Cloud ضمن تجربة تطوير سلسة. في السابق، كان الوصول إلى النماذج المدرَّبة باستخدام AutoML والنماذج المخصّصة ممكنًا من خلال خدمات منفصلة. ويدمج العرض الجديد كلاً من واجهة برمجة تطبيقات واحدة مع منتجات جديدة أخرى. يمكنك أيضًا نقل المشاريع الحالية إلى Vertex AI. إذا كان لديك أي ملاحظات، يُرجى الاطّلاع على صفحة الدعم.

يتضمّن Vertex AI العديد من المنتجات المختلفة لدعم سير العمل الشامل لتعلُّم الآلة. سيركّز هذا التمرين المعملي على التدريب وطاولة العمل.

نظرة عامة على منتج Vertex

3- نظرة عامة على حالة الاستخدام

سوف تستخدم في هذا التمرين المعملي ضبط المعلَمة الفائقة لاكتشاف المَعلَمات المثلى لنموذج تصنيف الصور المُدرَّب على مجموعة بيانات الخيول أو البشر من مجموعات بيانات TensorFlow.

ضبط المعلَمة الفائقة

يعمل ضبط المعلَمات الفائقة باستخدام Vertex AI Training من خلال تنفيذ تجارب متعددة لتطبيق التدريب باستخدام قيم للمعلَمات الفائقة التي اختَرتها، مع ضبط حدودها التي تحدّدها. يتتبّع Vertex AI نتائج كل تجربة ويُجري التعديلات اللازمة على المحاولات اللاحقة.

لاستخدام ضبط المعلَمة الفائقة من خلال Vertex AI Training، عليك إجراء تغييرَين على رمز التدريب:

  1. حدِّد وسيطة سطر أوامر في وحدة التدريب الرئيسية لكل معلَمة فائقة تريد ضبطها.
  2. استخدِم القيمة التي تم تمريرها في هذه الوسيطات لضبط المعلَمة الفائقة المقابلة في رمز تطبيقك.

التدريب الموزَّع

إذا كان لديك وحدة معالجة رسومات واحدة، سيستخدم TensorFlow هذا المسرّع لتسريع تدريب النموذج بدون أي جهد إضافي من جانبك. مع ذلك، إذا أردت تعزيز استخدام وحدات معالجة رسومات متعدّدة، يجب استخدام tf.distribute، وهي وحدة TensorFlow لإجراء العمليات الحسابية على أجهزة متعدّدة.

يستخدم هذا التمرين المعملي tf.distribute.MirroredStrategy، الذي يمكنك إضافته إلى تطبيقات التدريب من خلال تغييرات قليلة في الرموز. تنشئ هذه الاستراتيجية نسخة من النموذج في كل وحدة معالجة رسومات في جهازك. وسيتم إجراء تحديثات التدرج اللاحقة بشكل متزامن. وهذا يعني أن كل وحدة معالجة رسومات تحسب التمرير للأمام والخلف عبر النموذج على شريحة مختلفة من بيانات الإدخال. يتم بعد ذلك تجميع التدرجات المحسوبة من كل شريحة من هذه الشرائح على كل وحدات معالجة الرسومات ويتم حساب متوسطها في عملية تُعرف باسم all-reduce. يتم تعديل مَعلمات النموذج باستخدام التدرجات المتوسطة هذه.

لا تحتاج إلى معرفة التفاصيل لإكمال هذا التمرين، ولكن إذا أردت معرفة المزيد من المعلومات حول كيفية عمل التدريب الموزَّع في TensorFlow، يمكنك مشاهدة الفيديو التالي:

4. إعداد البيئة

ستحتاج إلى مشروع Google Cloud Platform مع تفعيل الفوترة لتشغيل هذا الدرس التطبيقي حول الترميز. لإنشاء مشروع، يُرجى اتّباع التعليمات هنا.

الخطوة 1: تفعيل واجهة برمجة تطبيقات Compute Engine

انتقِل إلى Compute Engine واختَر تفعيل إذا لم يسبق لك تفعيله.

الخطوة 2: تفعيل Container Registry API

انتقِل إلى Container Registry واختَر تفعيل إذا لم يسبق لك إجراء ذلك. ستستخدم هذا لإنشاء حاوية لوظيفة التدريب المخصصة.

الخطوة 3: تفعيل Vertex AI API

انتقِل إلى قسم Vertex AI في Cloud Console وانقر على تفعيل Vertex AI API.

لوحة بيانات Vertex AI

الخطوة 4: إنشاء مثيل Vertex AI Workbench

من قسم Vertex AI في Cloud Console، انقر على Workbench:

قائمة Vertex AI

فعِّل Notebooks API إذا لم يسبق لك تفعيلها.

Notebook_api

بعد التفعيل، انقر على المفكرات المُدارة:

Notebooks_UI

ثم اختَر مفكرة جديدة.

new_notebook

أدخِل اسمًا لدفتر الملاحظات، ثم انقر على الإعدادات المتقدمة.

create_notebook

ضمن "الإعدادات المتقدمة"، فعِّل إيقاف التشغيل في وضع عدم النشاط واضبط عدد الدقائق على 60. وهذا يعني أنه سيتم إغلاق دفتر الملاحظات تلقائيًا عندما لا يتم استخدامه، وبذلك لن تتحمل أي تكاليف غير ضرورية.

idle_timeout

ضمن "الأمان"، اختر "تفعيل الوحدة الطرفية". إذا لم يكن مفعّلاً من قبل.

تفعيل الجهاز الطرفي

ويمكنك ترك جميع الإعدادات المتقدّمة الأخرى كما هي.

بعد ذلك، انقر على إنشاء. ستستغرق عملية توفير المثيل بضع دقائق.

بعد إنشاء المثيل، اختَر فتح JupyterLab.

open_jupyterlab

عند استخدام مثيل جديد لأول مرة، سيُطلب منك المصادقة. اتّبِع الخطوات في واجهة المستخدم لإجراء ذلك.

مصادقة

5- كتابة رمز التدريب

للبدء، من قائمة "مشغّل التطبيقات"، افتح نافذة المحطة الطرفية في مثيل ورقة الملاحظات:

launcher_terminal

أنشِئ دليلاً جديدًا باسم vertex-codelab وأضِفه إلى القرص المضغوط.

mkdir vertex-codelab
cd vertex-codelab

نفِّذ ما يلي لإنشاء دليل لرمز التدريب وملف Python حيث ستضيف الرمز:

mkdir trainer
touch trainer/task.py

من المفترض أن يكون لديك الآن ما يلي في دليل vertex-codelab:

+ trainer/
    + task.py

بعد ذلك، افتح ملف task.py الذي أنشأته والصق كل الرموز البرمجية أدناه.

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

لنلقِ نظرة أعمق على الرمز ونفحص المكونات الخاصة بالتدريب الموزَّع وضبط المعلَمة الفائقة.

التدريب الموزَّع

  1. في الدالة main()، يتم إنشاء الكائن MirroredStrategy. بعد ذلك، يمكنك إنشاء متغيرات النموذج في نطاق الاستراتيجية. تُحدِّد هذه الخطوة TensorFlow المتغيّرات التي يجب عكسها على وحدات معالجة الرسومات.
  2. يتم زيادة حجم الدُفعة باستخدام num_replicas_in_sync. إنّ توسيع نطاق حجم الدفعة هو من أفضل الممارسات عند استخدام استراتيجيات موازية البيانات المتزامنة في TensorFlow. يمكنك الاطّلاع على المزيد من المعلومات.

ضبط المعلَمة الفائقة

  1. يستورد النص البرمجي مكتبة hypertune. في وقت لاحق عندما ننشئ صورة الحاوية، سنحتاج إلى التأكد من تثبيت هذه المكتبة.
  2. تحدّد الدالة get_args() وسيطة سطر أوامر لكل معلَمة فائقة تريد ضبطها. في هذا المثال، تكون المعلَمات الفائقة التي سيتم ضبطها هي معدّل التعلّم وقيمة الزخم في أداة التحسين وعدد الوحدات في آخر طبقة مخفية من النموذج، ولكن لا تتردد في تجربة معلَمات أخرى. ويتم بعد ذلك استخدام القيمة التي تم تمريرها في هذه الوسيطات لضبط المعلَمة الفائقة المقابلة في الرمز (مثل ضبط learning_rate = args.learning_rate)
  3. في نهاية الدالة main()، يتم استخدام مكتبة hypertune لتحديد المقياس الذي تريد تحسينه. في TensorFlow، تعرض طريقة Keras model.fit كائن History. تمثّل السمة History.history سجلاً لقيم خسارة التدريب وقيم المقاييس في الفترات المتتالية. إذا مررت بيانات التحقق من الصحة إلى 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
 ]

إذا كنت تريد أن تكتشف خدمة ضبط المعلَمات الفائقة القيم التي تزيد من دقة التحقّق من صحة النموذج إلى أقصى حد، يمكنك تحديد المقياس باعتباره الإدخال الأخير (أو NUM_EPOCS - 1) في قائمة val_accuracy. بعد ذلك، مرِّر هذا المقياس إلى مثيل HyperTune. يمكنك اختيار أي سلسلة تريدها لـ hyperparameter_metric_tag، ولكنك ستحتاج إلى استخدام السلسلة مرة أخرى لاحقًا عند بدء مهمة ضبط المعلَمة الفائقة.

6- رمز الحاوية

الخطوة الأولى في احتواء التعليمة البرمجية هي إنشاء ملف Dockerfile. في الملف الشامل ستضمّن جميع الأوامر اللازمة لتشغيل الصورة. ستقوم بتثبيت جميع المكتبات الضرورية وإعداد نقطة الدخول لرمز التدريب.

الخطوة 1: كتابة ملف Dockerfile

من تطبيق Terminal، تأكَّد من أنّك في الدليل vertex-codelab وأنشِئ ملفًا Dock فارغًا:

touch Dockerfile

من المفترض أن يكون لديك الآن ما يلي في دليل vertex-codelab:

+ Dockerfile
+ trainer/
    + task.py

افتح الملف الشامل وانسخ ما يلي إليه:

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

يستخدم هذا الملف الشامل صورة Deep Learning Container TensorFlow Enterprise 2.7 GPU Docker. تأتي حاويات التعلّم المتعمق على Google Cloud مع العديد من أُطر العمل الشائعة لتعلُّم الآلة وعلوم البيانات والمثبَّتة مسبقًا. بعد تنزيل تلك الصورة، يُعِدّ هذا الملف الشامل نقطة الدخول لرمز التدريب.

الخطوة 2: إنشاء الحاوية

من "المحطة الطرفية"، شغِّل ما يلي لتحديد متغيّر env لمشروعك، مع الحرص على استبدال your-cloud-project بمعرّف مشروعك:

PROJECT_ID='your-cloud-project'

حدد متغيرًا باستخدام معرف الموارد المنتظم (URI) لصورة الحاوية في Google Container Registry:

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

إعداد Docker

gcloud auth configure-docker

بعد ذلك، أنشِئ الحاوية عن طريق تنفيذ ما يلي من جذر الدليل vertex-codelab:

docker build ./ -t $IMAGE_URI

أخيرًا، انشره في Google Container Registry:

docker push $IMAGE_URI

الخطوة 3: إنشاء حزمة على Cloud Storage

في المهمة التدريبية، سننتقل إلى مجموعة مرحلية.

شغِّل ما يلي في Terminal لإنشاء حزمة جديدة في مشروعك.

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

7. بدء مهمة ضبط المعلَمة الفائقة

الخطوة 1: إنشاء مهمة تدريب مخصّصة باستخدام ضبط معلَمة فائقة

افتح ورقة ملاحظات TensorFlow 2 جديدة من مشغِّل التطبيقات.

new_notebook

استورِد حزمة تطوير برامج Vertex AI Python.

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

لبدء مهمة ضبط المعلَمة الفائقة، عليك أولاً تحديد worker_pool_specs، الذي يحدد نوع الجهاز وصورة Docker. تحدد المواصفات التالية جهازًا واحدًا يحتوي على وحدتي معالجة رسومات NVIDIA Tesla V100.

ستحتاج إلى استبدال {PROJECT_ID} في image_uri بمشروعك.

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

بعد ذلك، حدِّد 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 الذي ضبطته في رمز تطبيق التدريب، والقيمة هي هدف التحسين.

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

بعد تحديد المواصفات، عليك إنشاء CustomJob، وهي المواصفات الشائعة التي سيتم استخدامها لتشغيل مهمتك في كل مرحلة من تجارب ضبط المعلَمة الفائقة.

يجب استبدال السمة {YOUR_BUCKET} بالحزمة التي أنشأتها سابقًا.

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

بعد ذلك، يمكنك إنشاء 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()

هناك بعض الوسيطات التي يجب ملاحظتها:

  • max_trial_count: ستحتاج إلى وضع حد أعلى لعدد التجارب التي سيتم تشغيل الخدمة عليها. وبشكل عام، يؤدي المزيد من التجارب إلى تحقيق نتائج أفضل، ولكن ستكون هناك نقطة انخفاض في العائدات، وبعدها يكون للتجارب الإضافية تأثير ضئيل أو معدوم على المقياس الذي تحاول تحسينه. ومن أفضل الممارسات البدء بعدد أصغر من التجارب والتعرف على مدى تأثير مُخرَجات المعلَمات الفائقة التي اخترتها قبل التوسّع.
  • الموازي_trial_count: إذا كنت تستخدم فترات تجريبية متوازية، توفِّر الخدمة مجموعات معالجة تدريب متعددة. تؤدي زيادة عدد التجارب المتوازية إلى تقليل مقدار الوقت الذي تستغرقه مهمة ضبط المعلَمة الفائقة للتشغيل؛ ومع ذلك، فإنه يمكن أن يقلل من فعالية الوظيفة بشكل عام. ويرجع ذلك إلى أنّ استراتيجية التوليف التلقائية تستخدم نتائج التجارب السابقة لتحديد القيم في المحاولات اللاحقة.
  • خوارزمية البحث: يمكنك ضبط خوارزمية البحث على عرض شبكي أو عشوائي أو تلقائي (بدون). يُطبق الخيار الافتراضي تحسين بايز للبحث في مساحة قيم المعلمات الفائقة المحتملة وهو الخوارزمية الموصى بها. يمكنك معرفة المزيد عن هذه الخوارزمية هنا.

بعد بدء المهمة، ستتمكّن من تتبُّع الحالة في واجهة المستخدم ضمن علامة التبويب ضبط الوظائف HYPERPARAMETER.

HP_job

بمجرد اكتمال المهمة، يمكنك عرض نتائج التجارب وفرزها لاكتشاف أفضل مجموعة من قيم المعلمات الفائقة.

HP_results

🎉 تهانينا. 🎉

لقد تعلمت كيفية استخدام Vertex AI لإجراء ما يلي:

  • تنفيذ مهمة ضبط معلَمة فائقة باستخدام تدريب موزّع

لمزيد من المعلومات حول الأجزاء المختلفة من Vertex AI، يمكنك الاطّلاع على المستندات.

8. تنظيف

لأنّنا ضبطنا ورقة الملاحظات على انتهاء مهلة الحاسب بعد 60 دقيقة من عدم النشاط، لا داعي للقلق بشأن إيقاف تشغيل المثيل. إذا أردت إيقاف المثيل يدويًا، انقر على زر "إيقاف" في قسم Vertex AI Workbench على وحدة التحكّم. إذا كنت ترغب في حذف الدفتر بالكامل، فانقر فوق الزر "Delete" (حذف).

حذف

لحذف "حزمة التخزين"، باستخدام قائمة التنقّل في Cloud Console، انتقِل إلى "مساحة التخزين" واختَر الحزمة وانقر على "حذف":

حذف مساحة التخزين