النموذج الأوّلي إلى الإنتاج: ضبط المعلَمة الفائقة

1. نظرة عامة

في هذا الدرس التطبيقي، ستستخدم Vertex AI لتنفيذ مهمة ضبط معلَمة فائقة في Vertex AI Training.

يُعد هذا التمرين المعملي جزءًا من سلسلة مقاطع فيديو إنشاء النموذج الأولي إلى الإنتاج. تأكّد من إكمال الدرس التطبيقي السابق قبل تجربته. يمكنك مشاهدة سلسلة الفيديوهات المصاحبة لمعرفة المزيد من المعلومات:

.

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

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

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

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

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

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

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

3- إعداد البيئة

أكمِل الخطوات الواردة في الميزة الاختبارية تدريب النماذج المخصّصة باستخدام Vertex AI لإعداد بيئتك.

4. رمز تطبيق التدريب على Containerize

يمكنك إرسال هذه المهمة التدريبية إلى Vertex AI من خلال وضع رمز تطبيق التدريب في حاوية Docker وإرسالها إلى Google Artifact Registry. باستخدام هذا النهج، يمكنك تدريب وتحسين نموذج تم إنشاؤه باستخدام أي إطار عمل.

للبدء، افتح نافذة طرفية من قائمة "مشغّل التطبيقات" في دفتر ملاحظات Workbench الذي أنشأته في التمارين الاختبارية السابقة.

فتح الوحدة الطرفية في ورقة الملاحظات

الخطوة 1: كتابة رمز التدريب

أنشئ دليلاً جديدًا باسم flowers-hptune وأضِفه إليه:

mkdir flowers-hptune
cd flowers-hptune

قم بتشغيل ما يلي لإنشاء دليل لرمز التدريب وملف Python حيث ستقوم بإضافة الرمز أدناه.

mkdir trainer
touch trainer/task.py

من المفترض أن يكون لديك الآن ما يلي في دليل flowers-hptune/:

+ trainer/
    + task.py

بعد ذلك، افتح ملف task.py الذي أنشأته وانسخ الرمز أدناه.

عليك استخدام حزمة Cloud Storage بدلاً من {your-gcs-bucket} في BUCKET_ROOT، حيث خزّنت مجموعة بيانات الزهور في 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 سجلاً لقيم خسارة التدريب وقيم المقاييس في الفترات المتتالية. إذا مررت بيانات التحقق من الصحة إلى 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، ولكنك ستحتاج إلى استخدام السلسلة مرة أخرى لاحقًا عند بدء مهمة ضبط المعلَمة الفائقة.

الخطوة 2: إنشاء ملف شامل

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

من الوحدة الطرفية، أنشِئ ملف Dockerfile فارغًا في جذر دليل flowers-hptune:

touch Dockerfile

من المفترض أن يكون لديك الآن ما يلي في دليل flowers-hptune/:

+ Dockerfile
+ trainer/
    + task.py

افتح الملف الشامل وانسخ ما يلي إليه. ستلاحظ أن هذا الملف متطابق تقريبًا مع ملف Dockerfile الذي استخدمناه في التمرين المعملي الأول، باستثناء أننا الآن بصدد تثبيت مكتبة cloudml- Hyertune.

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

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

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

PROJECT_ID='your-cloud-project'

تحديد مستودع في Artifact Registry سنستخدم Repo الذي أنشأناه في التمرين المعملي الأول.

REPO_NAME='flower-app'

حدد متغيرًا باستخدام معرف الموارد المنتظم (URI) لصورة الحاوية في 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

بعد إرسال الحاوية إلى Artifact Registry، تصبح جاهزًا لبدء مهمة التدريب.

5- تنفيذ مهمة ضبط المعلَمة الفائقة باستخدام حزمة تطوير البرامج (SDK)

في هذا القسم، ستتعرّف على كيفية إعداد مهمة ضبط المعلَمة الفائقة وإرسالها باستخدام واجهة برمجة تطبيقات Vertex Python.

من "مشغّل التطبيقات"، أنشِئ ورقة ملاحظات TensorFlow 2.

new_notebook

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

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

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

يجب استبدال السمة {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 على وحدة التحكّم. إذا كنت ترغب في حذف الدفتر بالكامل، فانقر فوق الزر "Delete" (حذف).

إيقاف المثيل

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

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