1. סקירה כללית
בשיעור ה-Lab הזה נשתמש ב-Vertex AI כדי להריץ משימת כוונון היפר-פרמטרים למודל של TensorFlow. בשיעור ה-Lab הזה נעשה שימוש ב-TensorFlow כקוד המודל, אבל המושגים רלוונטיים גם ל-frameworks אחרות של למידת מכונה.
מה לומדים
נסביר לכם איך:
- לשנות קוד של אפליקציה לאימון לצורך כוונון היפר-פרמטרים אוטומטי
- הגדרה והפעלה של משימת כוונון היפר-פרמטרים מממשק המשתמש של Vertex AI
- הגדרה והפעלה של משימת כוונון היפר-פרמטרים באמצעות Vertex AI Python SDK
העלות הכוללת של הפעלת שיעור ה-Lab הזה ב-Google Cloud היא כ-3$.
2. מבוא ל-Vertex AI
בשיעור ה-Lab הזה נעשה שימוש במוצר ה-AI החדש ביותר שזמין ב-Google Cloud. Vertex AI משלב את הצעות למידת המכונה ב-Google Cloud ליצירת חוויית פיתוח חלקה. בעבר, ניתן היה לגשת למודלים שעברו אימון באמצעות AutoML ומודלים בהתאמה אישית דרך שירותים נפרדים. המוצר החדש משלב את כל ממשקי ה-API האלה בממשק API אחד, לצד מוצרים חדשים אחרים. תוכלו גם להעביר פרויקטים קיימים ל-Vertex AI. יש לך משוב? אפשר למצוא אותו בדף התמיכה.
Vertex AI כולל מוצרים רבים ושונים לתמיכה בתהליכי עבודה של למידת מכונה מקצה לקצה. שיעור ה-Lab הזה יתמקד במוצרים שמודגשים בהמשך: הדרכה וWorkbench.
3. הגדרת הסביבה
כדי להריץ את ה-Codelab הזה צריך פרויקט ב-Google Cloud Platform שהחיוב מופעל בו. כדי ליצור פרויקט, יש לפעול לפי ההוראות האלה.
שלב 1: מפעילים את ממשק ה-API של Compute Engine
עוברים אל Compute Engine ובוחרים באפשרות Enable (הפעלה) אם היא לא מופעלת עדיין. תצטרכו את הקישור הזה כדי ליצור מכונה של ה-notebook.
שלב 2: מפעילים את Container Registry API
עוברים אל Container Registry ובוחרים באפשרות Enable אם עדיין לא משתמשים בו. אפשר להשתמש בו כדי ליצור מאגר למשימת האימון המותאמת אישית.
שלב 3: מפעילים את Vertex AI API
עוברים לקטע Vertex AI במסוף Cloud ולוחצים על Enable Vertex AI API.
שלב 4: יצירת מכונה של Vertex AI Workbench
בקטע Vertex AI במסוף Cloud, לוחצים על Workbench:
מפעילים את Notebooks API, אם עדיין לא פועלים.
לאחר ההפעלה, לוחצים על פנקסי רשימות מנוהלים:
לאחר מכן בוחרים פנקס רשימות חדש.
נותנים שם ל-notebook ולוחצים על הגדרות מתקדמות.
בקטע 'הגדרות מתקדמות', מפעילים כיבוי ללא פעילות ומגדירים את מספר הדקות ל-60. כלומר, המחשב יכבה באופן אוטומטי כשהוא לא בשימוש כדי שלא תצברו עלויות מיותרות.
בקטע אבטחה, בוחרים באפשרות 'הפעלת הטרמינל'. אם היא לא מופעלת עדיין.
אפשר להשאיר את כל שאר ההגדרות המתקדמות כפי שהן.
לאחר מכן, לוחצים על יצירה. הקצאה של המכונה תימשך כמה דקות.
אחרי שהמכונה נוצרה, בוחרים באפשרות Open JupyterLab.
בפעם הראשונה שתשתמשו במכונה חדשה, תתבקשו לבצע אימות. כדי לעשות זאת, פועלים לפי השלבים שבממשק המשתמש.
4. יצירת קונטיינרים של קוד אפליקציה לאימון
המודל שתאמנים ויכוונן בשיעור ה-Lab הזה הוא מודל לסיווג תמונות שאומן לפי מערך הנתונים של סוסים או בני אדם ממערכי נתונים של TensorFlow.
עכשיו תשלחו את משימת כוונון ההיפר-פרמטרים ל-Vertex AI באמצעות הצבת הקוד של אפליקציית האימון בקונטיינר של Docker, והעברת הקונטיינר הזה אל Google Container Registry. באמצעות הגישה הזו תוכלו לכוונן היפר-פרמטרים למודל שנוצר באמצעות כל framework.
כדי להתחיל, פותחים חלון Terminal במכונה של ה-notebook מתפריט מרכז האפליקציות:
יוצרים ספרייה חדשה בשם horses_or_humans
ומוסיפים אליה cd:
mkdir horses_or_humans
cd horses_or_humans
שלב 1: יוצרים קובץ Docker
השלב הראשון ביצירת קונטיינרים לקוד הוא יצירת קובץ Docker. בקובץ ה-Docker, יכללו את כל הפקודות הנדרשות להפעלת התמונה. הוא יתקין את כל הספריות הנדרשות, כולל את ספריית CloudML Hypertens, ותגדיר את נקודת הכניסה לקוד האימון.
בטרמינל, יוצרים קובץ Docker ריק:
touch Dockerfile
פותחים את קובץ ה-Docker ומעתיקים אליו את הפקודה הבאה:
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"]
קובץ ה-Docker הזה משתמש בתמונת Docker של TensorFlow Enterprise 2.7 GPU ללמידה עמוקה (Deep Learning). בקונטיינרים של למידה עמוקה (Deep Learning) ב-Google Cloud מותקנים מראש הרבה מסגרות נפוצות של למידת מכונה ומדעי נתונים. אחרי שמורידים את התמונה, קובץ ה-Docker הזה מגדיר את נקודת הכניסה לקוד האימון. עדיין לא יצרת את הקבצים האלה – בשלב הבא צריך להוסיף את הקוד לצורך אימון וכוונון המודל.
שלב 2: מוסיפים קוד לאימון מודלים
בטרמינל, מריצים את הפקודה הבאה כדי ליצור ספרייה לקוד האימון וקובץ Python שאליו מוסיפים את הקוד:
mkdir trainer
touch trainer/task.py
עכשיו אמורים להיות בספרייה horses_or_humans/
הפריטים הבאים:
+ Dockerfile
+ trainer/
+ task.py
אחר כך פותחים את הקובץ task.py
שיצרתם ומעתיקים את הקוד שבהמשך.
import tensorflow as tf
import tensorflow_datasets as tfds
import argparse
import hypertune
NUM_EPOCHS = 10
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():
'''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(64)
# Create validation dataset
validation_data = data['test'].map(preprocess_data)
validation_data = validation_data.batch(64)
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()
train_data, validation_data = create_dataset()
model = create_model(args.num_units, args.learning_rate, args.momentum)
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()
לפני שיוצרים את מאגר התגים, נבחן לעומק את הקוד. יש כמה רכיבים ספציפיים לשימוש בשירות כוונון ההיפר-פרמטרים.
- הסקריפט מייבא את הספרייה
hypertune
. שימו לב שקובץ ה-Docker משלב 1 כלל הוראות להתקנת הספרייה הזו ב-PIP. - הפונקציה
get_args()
מגדירה ארגומנט של שורת פקודה לכל היפר-פרמטר שרוצים לכוונן. בדוגמה הזו, ההיפר-פרמטרים שאמורים להיות כווננו הם קצב הלמידה, ערך התנע בכלי האופטימיזציה ומספר היחידות בשכבה המוסתרת האחרונה של המודל, אבל אתם מוזמנים להתנסות עם אחרים. הערך שמועבר בארגומנטים האלה משמש להגדרת ההיפר-פרמטר התואם בקוד. - בסוף הפונקציה
main()
, הספרייהhypertune
משמשת להגדרת המדד שרוצים לבצע אופטימיזציה. ב-TensorFlow, שיטת kerasmodel.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
, אבל תצטרכו להשתמש במחרוזת שוב מאוחר יותר כשתתחילו את עבודת הכוונון של ההיפר-פרמטר.
שלב 3: יוצרים את המאגר
ב-Terminal, מריצים את הפקודה הבאה כדי להגדיר משתנה env לפרויקט ומקפידים להחליף את your-cloud-project
במזהה הפרויקט:
PROJECT_ID='your-cloud-project'
מגדירים משתנה עם ה-URI של תמונת הקונטיינר ב-Google Container Registry:
IMAGE_URI="gcr.io/$PROJECT_ID/horse-human:hypertune"
הגדרת Docker
gcloud auth configure-docker
לאחר מכן, יוצרים את הקונטיינר על ידי הרצת הפקודה הבאה מהרמה הבסיסית (root) של הספרייה horses_or_humans
:
docker build ./ -t $IMAGE_URI
לסיום, מעבירים אותו ל-Google Container Registry:
docker push $IMAGE_URI
הקונטיינר הועבר ל-Container Registry, ועכשיו אתם מוכנים להתחיל במשימת כוונון של היפר-פרמטרים של מודל מותאם אישית.
5. הרצת משימת כוונון היפר-פרמטרים ב-Vertex AI
בשיעור ה-Lab הזה נעשה שימוש באימון מותאם אישית באמצעות קונטיינר מותאם אישית ב-Google Container Registry, אבל אפשר גם להריץ משימת כוונון של היפר-פרמטרים באמצעות קונטיינר שפותח מראש של Vertex AI.
כדי להתחיל, עוברים לקטע Training בקטע Vertex במסוף Cloud:
שלב 1: הגדרה של משימת האימון
לוחצים על יצירה כדי להזין את הפרמטרים של משימת הכוונון של ההיפר-פרמטרים.
- בקטע מערך נתונים, בוחרים באפשרות אין מערך נתונים מנוהל.
- לאחר מכן בוחרים באפשרות אימון מותאם אישית (למתקדמים) כשיטת האימון ולוחצים על המשך.
- מזינים
horses-humans-hyptertune
(או כל שם אחר שרוצים לקרוא למודל) בשדה שם המודל - לוחצים על המשך.
בשלב Container settings (הגדרות מאגר תגים), בוחרים באפשרות CustomContainer (מאגר מותאם אישית):
בתיבה הראשונה (תמונה של קונטיינר), מזינים את הערך של המשתנה IMAGE_URI
מהקטע הקודם. הוא צריך להיות: gcr.io/your-cloud-project/horse-human:hypertune
, עם שם הפרויקט שלכם. משאירים את שאר השדות ריקים ולוחצים על Continue (המשך).
שלב 2: מגדירים משימת כוונון של היפר-פרמטרים
בוחרים באפשרות הפעלת כוונון היפר-פרמטרים.
הגדרת היפר-פרמטרים
בשלב הבא צריך להוסיף את ההיפר-פרמטרים שהגדרתם כארגומנטים בשורת הפקודה בקוד של אפליקציית האימון. כשמוסיפים היפר-פרמטר, קודם צריך לציין את השם. הוא צריך להיות זהה לשם הארגומנט שהעברת אל argparse
.
לאחר מכן בוחרים את הסוג ואת הגבולות של הערכים ששירות הכוונון ינסה. אם בוחרים בסוג 'כפול' או 'מספר שלם', צריך לציין ערך מינימלי ומקסימלי. אם בוחרים באפשרות 'קטגורית' או 'בדיד', יש לספק את הערכים.
עבור הסוגים Double ו-Integer, צריך גם לציין את ערך ההתאמה.
אחרי שמוסיפים את ההיפר-פרמטר learning_rate
, מוסיפים את הפרמטרים עבור momentum
ו-num_units
.
הגדרת המדד
אחרי שמוסיפים את ההיפר-פרמטרים, צריך לציין גם את המדד שרוצים לבצע אופטימיזציה וגם את היעד. הערך הזה צריך להיות זהה לערך של hyperparameter_metric_tag
שהגדרת באפליקציית האימון.
שירות הכוונון של Vertex AI Hyperparameter יריץ כמה תקופות ניסיון של אפליקציית האימון שלכם עם הערכים שהוגדרו בשלבים הקודמים. צריך לקבוע גבול עליון למספר תקופות הניסיון שהשירות יפעל. לרוב, ניסויים רבים יותר מובילים לתוצאות טובות יותר, אבל חלק מהניסויים הנוספים יצטמצמו. לאחר מכן, לניסויים נוספים תהיה השפעה מועטה על המדד שאתם מנסים לבצע אופטימיזציה, אם בכלל. מומלץ להתחיל עם מספר קטן יותר של ניסויים ולקבל מושג לגבי ההשפעה של ההיפר-פרמטרים שבחרתם לפני הגדלת מספר הניסויים.
צריך גם להגדיר גבול עליון למספר הניסיונות המקבילים. הגדלת מספר הניסויים המקבילים תפחית את משך הזמן שלוקח למשימת הכוונון ההיפר-פרמטרים לרוץ. עם זאת, הוא עלול לפגוע ביעילות של העבודה באופן כללי. הסיבה לכך היא שאסטרטגיית הכוונון שמוגדרת כברירת מחדל משתמשת בתוצאות מניסויים קודמים כדי לשפר את הקצאת הערכים בניסויים הבאים. אם מריצים יותר מדי ניסויים במקביל, יהיו ניסויים שיתחילו ללא התועלת של הניסויים שעדיין פועלים.
למטרות הדגמה, אפשר להגדיר את מספר הניסיונות כ-15 ואת המספר המקסימלי של הניסיונות המקבילים כ-3. אפשר לנסות מספרים שונים, אבל במקרה כזה יכול להיות זמן כוונון ארוך יותר ועלות גבוהה יותר.
השלב האחרון הוא לבחור באפשרות 'ברירת מחדל' כאלגוריתם החיפוש, שישתמש ב-Google Vizier כדי לבצע אופטימיזציה בייסיאנית לכוונון היפר-פרמטרים. מידע נוסף על האלגוריתם הזה
לוחצים על המשך.
שלב 3: הגדרת המחשוב
בקטע Compute andpricing, משאירים את האזור שנבחר כפי שהוא ומגדירים את Worker pool 0 באופן הבא.
לוחצים על התחלת האימון כדי להתחיל את משימת הכוונון של ההיפר-פרמטרים. בקטע 'אימון' במסוף, בכרטיסייה HYPERPARAMETER TUNING JOBS, אמור להופיע משהו כזה:
בסיום התהליך, ניתן יהיה ללחוץ על שם המשימה ולראות את התוצאות של ניסויי הכוונון.
🎉 כל הכבוד! 🎉
למדתם איך להשתמש ב-Vertex AI כדי:
- מפעילים משימת כוונון היפר-פרמטרים לאימון קוד שסופק בקונטיינר מותאם אישית. השתמשתם במודל TensorFlow בדוגמה הזו, אבל אפשר לאמן מודל שנוצר עם כל מסגרת באמצעות קונטיינרים מותאמים אישית.
כדי לקבל מידע נוסף על החלקים השונים ב-Vertex, אתם יכולים לעיין במסמכי העזרה.
6. [אופציונלי] שימוש ב-Vertex SDK
בקטע הקודם ראינו איך להפעיל את משימת הכוונון של ההיפר-פרמטרים דרך ממשק המשתמש. בקטע הזה תוצג דרך חלופית לשלוח את משימת הכוונון של ההיפר-פרמטרים באמצעות Vertex Python API.
במרכז האפליקציות, יוצרים notebook של TensorFlow 2.
מייבאים את Vertex AI SDK.
from google.cloud import aiplatform
from google.cloud.aiplatform import hyperparameter_tuning as hpt
כדי להפעיל את משימת הכוונון של ההיפר-פרמטרים, קודם צריך להגדיר את המפרטים הבאים. צריך להחליף את {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": "gcr.io/{PROJECT_ID}/horse-human:hypertune"
}
}]
# Dictionary 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'}
# 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)
}
בשלב הבא יוצרים CustomJob
. צריך להחליף את {YOUR_BUCKET}
בקטגוריה בפרויקט כדי לבצע Staging.
# Replace YOUR_BUCKET
my_custom_job = aiplatform.CustomJob(display_name='horses-humans-sdk-job',
worker_pool_specs=worker_pool_specs,
staging_bucket='gs://{YOUR_BUCKET}')
לאחר מכן, יוצרים ומפעילים את HyperparameterTuningJob
.
hp_job = aiplatform.HyperparameterTuningJob(
display_name='horses-humans-sdk-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()
7. הסרת המשאבים
בגלל שהגדרנו את ה-notebook להפסקה של הזמן הקצוב לתפוגה אחרי 60 דקות ללא פעילות, אנחנו לא צריכים לדאוג לכיבוי המכונה. כדי לכבות את המכונה באופן ידני, לוחצים על הלחצן Stop (עצירה) בקטע Vertex AI Workbench במסוף. אם אתה רוצה למחוק לגמרי את ה-notebook, לחץ על הלחצן 'מחיקה'.
כדי למחוק את קטגוריית האחסון, באמצעות תפריט הניווט במסוף Cloud, עוברים אל Storage (אחסון), בוחרים את הקטגוריה ולוחצים על סמל המחיקה: