1. סקירה כללית
בשיעור ה-Lab הזה תלמדו איך להשתמש ב-Vertex AI – פלטפורמת למידת המכונה המנוהלת החדשה של Google Cloud – כדי לפתח תהליכי עבודה מקצה לקצה ללמידת מכונה. תלמדו איך לעבור מנתונים גולמיים למודל שנפרס, ונותנים את הסדנה מוכנה לפיתוח והפקה של פרויקטי למידת מכונה משלכם באמצעות Vertex AI. בשיעור ה-Lab הזה נשתמש ב-Cloud Shell כדי לפתח תמונת Docker מותאמת אישית, כדי להדגים קונטיינרים מותאמים אישית לאימון באמצעות Vertex AI.
אנחנו משתמשים כאן ב-TensorFlow כקוד המודל, אבל אפשר להחליף אותו בקלות במסגרת אחרת.
מה לומדים
נסביר לכם איך:
- פיתוח קוד לאימון מודלים ויצירת קונטיינרים באמצעות Cloud Shell
- שליחת משימה לאימון מודלים בהתאמה אישית ל-Vertex AI
- פורסים את המודל המאומן בנקודת קצה ומשתמשים בנקודת הקצה הזו כדי לקבל חיזויים
העלות הכוללת של הפעלת שיעור ה-Lab הזה ב-Google Cloud היא כ-$2.
2. מבוא ל-Vertex AI
בשיעור ה-Lab הזה נעשה שימוש במוצר ה-AI החדש ביותר שזמין ב-Google Cloud. Vertex AI משלב את הצעות למידת המכונה ב-Google Cloud ליצירת חוויית פיתוח חלקה. בעבר, ניתן היה לגשת למודלים שעברו אימון באמצעות AutoML ומודלים בהתאמה אישית דרך שירותים נפרדים. המוצר החדש משלב את כל ממשקי ה-API האלה בממשק API אחד, לצד מוצרים חדשים אחרים. תוכלו גם להעביר פרויקטים קיימים ל-Vertex AI. יש לך משוב? אפשר למצוא אותו בדף התמיכה.
ב-Vertex יש הרבה כלים שונים שיעזרו לכם בכל שלב בתהליך העבודה של למידת המכונה, כפי שאתם יכולים לראות בתרשים הבא. נתמקד בשימוש בהדרכה וב-Prediction של Vertex, שהודגשו בהמשך.
3. הגדרת הסביבה
הגדרת סביבה בקצב אישי
נכנסים למסוף Cloud ויוצרים פרויקט חדש או עושים שימוש חוזר בפרויקט קיים. (אם אין לכם עדיין חשבון Gmail או חשבון Google Workspace, עליכם ליצור חשבון).
חשוב לזכור את מזהה הפרויקט, שם ייחודי לכל הפרויקטים ב-Google Cloud (השם שלמעלה כבר תפוס ולא מתאים לכם, סליחה).
בשלב הבא צריך להפעיל את החיוב במסוף Cloud כדי להשתמש במשאבים של Google Cloud.
מעבר ב-Codelab הזה לא אמור לעלות הרבה, אם בכלל. חשוב לבצע את כל ההוראות בקטע 'ניקוי' שמסביר איך להשבית משאבים כדי שלא תצברו חיובים מעבר למדריך הזה. משתמשים חדשים ב-Google Cloud זכאים להצטרף לתוכנית תקופת ניסיון בחינם בשווי 1,200 ש"ח.
שלב 1: הפעלת Cloud Shell
בשיעור ה-Lab הזה תלמדו במסגרת סשן של Cloud Shell, שהוא תרגום פקודות שמתארח במכונה וירטואלית שפועלת בענן של Google. באותה מידה תוכלו להריץ את הקטע הזה באופן מקומי במחשב שלכם, אבל השימוש ב-Cloud Shell מאפשר לכולם ליהנות מחוויה שניתן לשחזר בסביבה עקבית. אחרי שיעור ה-Lab, אתם יכולים לנסות שוב את הקטע הזה במחשב.
הפעלת Cloud Shell
בצד שמאל למעלה ב-Cloud Console, לוחצים על הלחצן שלמטה כדי Activate Cloud Shell (הפעלה של Cloud Shell):
אם לא הפעלתם את Cloud Shell בעבר, יוצג לכם מסך ביניים (בחלק הנגלל) שמתאר מהו. במקרה כזה, לוחצים על המשך (וזה לא יקרה שוב). כך נראה המסך החד-פעמי:
ההקצאה וההתחברות ל-Cloud Shell נמשכת כמה דקות.
במכונה הווירטואלית הזו משולבת כל כלי הפיתוח שדרושים לכם. יש בה ספריית בית בנפח מתמיד של 5GB והיא פועלת ב-Google Cloud, מה שמשפר משמעותית את ביצועי הרשת והאימות. אם לא את כולן, ניתן לבצע חלק גדול מהעבודה ב-Codelab הזה באמצעות דפדפן או Chromebook.
אחרי ההתחברות ל-Cloud Shell, אתם אמורים לראות שכבר בוצע אימות ושהפרויקט כבר מוגדר למזהה הפרויקט שלכם.
מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שהאימות בוצע:
gcloud auth list
פלט הפקודה
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שהפקודה ב-gcloud יודעת על הפרויקט שלכם:
gcloud config list project
פלט הפקודה
[core] project = <PROJECT_ID>
אם היא לא נמצאת שם, תוכלו להגדיר אותה באמצעות הפקודה הבאה:
gcloud config set project <PROJECT_ID>
פלט הפקודה
Updated property [core/project].
ב-Cloud Shell יש כמה משתני סביבה, כולל GOOGLE_CLOUD_PROJECT
שמכיל את השם של הפרויקט הנוכחי שלנו ב-Cloud. נשתמש בו במקומות שונים בשיעור ה-Lab הזה. כדי לראות את זה, מריצים את:
echo $GOOGLE_CLOUD_PROJECT
שלב 2: הפעלת ממשקי API
בשלבים הבאים תראו איפה השירותים האלה נחוצים (ולמה), אבל בינתיים, מריצים את הפקודה הזו כדי לתת לפרויקט גישה לשירותים Compute Engine, Container Registry ו-Vertex AI:
gcloud services enable compute.googleapis.com \
containerregistry.googleapis.com \
aiplatform.googleapis.com
אמורה ליצור מסר מוצלח שדומה להודעה הזו:
Operation "operations/acf.cc11852d-40af-47ad-9d59-477a12847c9e" finished successfully.
שלב 3: יצירת קטגוריה של Cloud Storage
כדי להריץ משימת אימון על Vertex AI, אנחנו זקוקים לקטגוריית אחסון לאחסון נכסי המודלים שנשמרו. כדי ליצור קטגוריה, מריצים את הפקודות הבאות בטרמינל של Cloud Shell:
BUCKET_NAME=gs://$GOOGLE_CLOUD_PROJECT-bucket
gsutil mb -l us-central1 $BUCKET_NAME
שלב 4: כינוי ל-Python 3
הקוד בשיעור ה-Lab הזה משתמש ב-Python 3. כדי לוודא שאתם משתמשים ב-Python 3 כשאתם מריצים את הסקריפטים שתיצרו בשיעור ה-Lab הזה, תוכלו ליצור כינוי על ידי הרצת הפקודה הבאה ב-Cloud Shell:
alias python=python3
המודל שנלמד ונציג בשיעור ה-Lab הזה מבוסס על המדריך הזה ממסמכי TensorFlow. המדריך משתמש במערך הנתונים של Auto MPG מ-Kaggle כדי לחזות את צריכת הדלק של רכב.
4. יצירת קונטיינרים של קוד אימון
נשלח את משימת האימון הזו ל-Vertex על ידי הצבת קוד האימון שלנו בקונטיינר של Docker, והעברת הקונטיינר הזה אל Google Container Registry. כך אנחנו יכולים לאמן מודל שנוצר באמצעות כל מסגרת.
שלב 1: מגדירים קבצים
כדי להתחיל, מהטרמינל ב-Cloud Shell, מריצים את הפקודות הבאות כדי ליצור את הקבצים שדרושים לקונטיינר ב-Docker:
mkdir mpg
cd mpg
touch Dockerfile
mkdir trainer
touch trainer/train.py
עכשיו אמורה להיות לכם ספריית mpg/
שנראית כך:
+ Dockerfile
+ trainer/
+ train.py
כדי לצפות בקבצים ולערוך אותם נשתמש בעורך הקוד המובנה של Cloud Shell. אפשר לעבור בין העורך לבין הטרמינל בלחיצה על הלחצן בסרגל התפריטים הימני העליון ב-Cloud Shell:
שלב 2: יוצרים קובץ Docker
כדי ליצור קונטיינרים לקוד שלנו, קודם ניצור קובץ Docker. בקובץ ה-Docker נכלול את כל הפקודות הנדרשות כדי להריץ את קובץ האימג' שלנו. הוא יתקין את כל הספריות שבהן אנחנו משתמשים ויגדיר את נקודת הכניסה לקוד האימון שלנו.
מעורך הקבצים של Cloud Shell, פותחים את ספריית mpg/
ולוחצים לחיצה כפולה כדי לפתוח את קובץ ה-Docker:
לאחר מכן מעתיקים את הפרטים הבאים לקובץ הזה:
FROM gcr.io/deeplearning-platform-release/tf2-cpu.2-3
WORKDIR /
# Copies the trainer code to the docker image.
COPY trainer /trainer
# Sets up the entry point to invoke the trainer.
ENTRYPOINT ["python", "-m", "trainer.train"]
קובץ ה-Docker הזה משתמש בתמונת Docker של TensorFlow Enterprise 2.3 ללמידה עמוקה. בקונטיינרים של למידה עמוקה (Deep Learning) ב-Google Cloud מותקנים מראש הרבה מסגרות נפוצות של למידת מכונה ומדעי נתונים. הפלטפורמה שבה אנחנו משתמשים כוללת את TF Enterprise 2.3, Pandas, Scikit-learn ועוד. אחרי שמורידים את התמונה, קובץ ה-Docker הזה מגדיר את נקודת הכניסה לקוד האימון שלנו, שאותו נוסיף בשלב הבא.
שלב 3: מוסיפים קוד לאימון המודלים
אחר כך, פותחים את הקובץ train.py
בעורך Cloud Shell ומעתיקים את הקוד שלמטה (לפי המדריך במסמכי TensorFlow).
# This will be replaced with your bucket name after running the `sed` command in the tutorial
BUCKET = "BUCKET_NAME"
import numpy as np
import pandas as pd
import pathlib
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
print(tf.__version__)
"""## The Auto MPG dataset
The dataset is available from the [UCI Machine Learning Repository](https://archive.ics.uci.edu/ml/).
### Get the data
First download the dataset.
"""
"""Import it using pandas"""
dataset_path = "https://storage.googleapis.com/io-vertex-codelab/auto-mpg.csv"
dataset = pd.read_csv(dataset_path, na_values = "?")
dataset.tail()
"""### Clean the data
The dataset contains a few unknown values.
"""
dataset.isna().sum()
"""To keep this initial tutorial simple drop those rows."""
dataset = dataset.dropna()
"""The `"origin"` column is really categorical, not numeric. So convert that to a one-hot:"""
dataset['origin'] = dataset['origin'].map({1: 'USA', 2: 'Europe', 3: 'Japan'})
dataset = pd.get_dummies(dataset, prefix='', prefix_sep='')
dataset.tail()
"""### Split the data into train and test
Now split the dataset into a training set and a test set.
We will use the test set in the final evaluation of our model.
"""
train_dataset = dataset.sample(frac=0.8,random_state=0)
test_dataset = dataset.drop(train_dataset.index)
"""### Inspect the data
Have a quick look at the joint distribution of a few pairs of columns from the training set.
Also look at the overall statistics:
"""
train_stats = train_dataset.describe()
train_stats.pop("mpg")
train_stats = train_stats.transpose()
train_stats
"""### Split features from labels
Separate the target value, or "label", from the features. This label is the value that you will train the model to predict.
"""
train_labels = train_dataset.pop('mpg')
test_labels = test_dataset.pop('mpg')
"""### Normalize the data
Look again at the `train_stats` block above and note how different the ranges of each feature are.
It is good practice to normalize features that use different scales and ranges. Although the model *might* converge without feature normalization, it makes training more difficult, and it makes the resulting model dependent on the choice of units used in the input.
Note: Although we intentionally generate these statistics from only the training dataset, these statistics will also be used to normalize the test dataset. We need to do that to project the test dataset into the same distribution that the model has been trained on.
"""
def norm(x):
return (x - train_stats['mean']) / train_stats['std']
normed_train_data = norm(train_dataset)
normed_test_data = norm(test_dataset)
"""This normalized data is what we will use to train the model.
Caution: The statistics used to normalize the inputs here (mean and standard deviation) need to be applied to any other data that is fed to the model, along with the one-hot encoding that we did earlier. That includes the test set as well as live data when the model is used in production.
## The model
### Build the model
Let's build our model. Here, we'll use a `Sequential` model with two densely connected hidden layers, and an output layer that returns a single, continuous value. The model building steps are wrapped in a function, `build_model`, since we'll create a second model, later on.
"""
def build_model():
model = keras.Sequential([
layers.Dense(64, activation='relu', input_shape=[len(train_dataset.keys())]),
layers.Dense(64, activation='relu'),
layers.Dense(1)
])
optimizer = tf.keras.optimizers.RMSprop(0.001)
model.compile(loss='mse',
optimizer=optimizer,
metrics=['mae', 'mse'])
return model
model = build_model()
"""### Inspect the model
Use the `.summary` method to print a simple description of the model
"""
model.summary()
"""Now try out the model. Take a batch of `10` examples from the training data and call `model.predict` on it.
It seems to be working, and it produces a result of the expected shape and type.
### Train the model
Train the model for 1000 epochs, and record the training and validation accuracy in the `history` object.
Visualize the model's training progress using the stats stored in the `history` object.
This graph shows little improvement, or even degradation in the validation error after about 100 epochs. Let's update the `model.fit` call to automatically stop training when the validation score doesn't improve. We'll use an *EarlyStopping callback* that tests a training condition for every epoch. If a set amount of epochs elapses without showing improvement, then automatically stop the training.
You can learn more about this callback [here](https://www.tensorflow.org/api_docs/python/tf/keras/callbacks/EarlyStopping).
"""
model = build_model()
EPOCHS = 1000
# The patience parameter is the amount of epochs to check for improvement
early_stop = keras.callbacks.EarlyStopping(monitor='val_loss', patience=10)
early_history = model.fit(normed_train_data, train_labels,
epochs=EPOCHS, validation_split = 0.2,
callbacks=[early_stop])
# Export model and save to GCS
model.save(BUCKET + '/mpg/model')
אחרי שמעתיקים את הקוד שלמעלה לקובץ mpg/trainer/train.py
, חוזרים ל-Terminal ב-Cloud Shell ומריצים את הפקודה הבאה כדי להוסיף לקובץ את שם הקטגוריה שלכם:
sed -i "s|BUCKET_NAME|$BUCKET_NAME|g" trainer/train.py
שלב 4: פיתוח ובדיקה של הקונטיינר באופן מקומי
ב-Terminal, מריצים את הפקודה הבאה כדי להגדיר משתנה עם ה-URI של קובץ האימג' של הקונטיינר ב-Google Container Registry:
IMAGE_URI="gcr.io/$GOOGLE_CLOUD_PROJECT/mpg:v1"
לאחר מכן, יוצרים את הקונטיינר על ידי הרצת הפקודה הבאה מהרמה הבסיסית (root) של הספרייה mpg
:
docker build ./ -t $IMAGE_URI
לאחר יצירת הקונטיינר, מעבירים אותו ל-Google Container Registry:
docker push $IMAGE_URI
כדי לוודא שהתמונה שלכם הועברה ל-Container Registry, אמור להופיע משהו כזה כשמנווטים אל הקטע Container Registry במסוף:
בעקבות העברת הקונטיינר שלנו ל-Container Registry, אנחנו מוכנים להתחיל משימה לאימון מודלים מותאמים אישית.
5. הרצת משימת אימון על Vertex AI
ב-Vertex יש שתי אפשרויות למודלים לאימון:
- AutoML: אימון מודלים באיכות גבוהה עם מומחיות בלמידת מכונה ובמאמץ מינימלי.
- הדרכה מותאמת אישית: אפשר להריץ אפליקציות אימון מותאמות אישית בענן באמצעות אחד מקונטיינרים מוכנים מראש של Google Cloud או להשתמש בקונטיינרים משלכם.
בשיעור ה-Lab הזה נשתמש באימון מותאם אישית באמצעות מאגר מותאם אישית משלנו ב-Google Container Registry. כדי להתחיל, עוברים לקטע Training בקטע Vertex במסוף Cloud:
שלב 1: מתחילים את משימת האימון
לוחצים על יצירה כדי להזין את הפרמטרים של משימת האימון והמודל שנפרס:
- בקטע מערך נתונים, בוחרים באפשרות אין מערך נתונים מנוהל.
- לאחר מכן בוחרים באפשרות אימון מותאם אישית (למתקדמים) כשיטת האימון ולוחצים על המשך.
- מזינים
mpg
(או כל שם אחר שרוצים לקרוא למודל) בשדה שם המודל - לוחצים על המשך.
בשלב Container settings (הגדרות מאגר תגים), בוחרים באפשרות CustomContainer (מאגר מותאם אישית):
בתיבה הראשונה (Container image), לוחצים על Browse ומוצאים את מאגר התגים שהעברתם ל-Container Registry. הוא אמור להיראות כך:
משאירים את שאר השדות ריקים ולוחצים על Continue (המשך).
לא נשתמש בכוונון היפר-פרמטרים במדריך הזה, לכן משאירים את תיבת הכוונון 'הפעלת היפר-פרמטרים' לא מסומנת ולוחצים על המשך.
בקטע Compute andpricing, משאירים את האזור שנבחר כפי שהוא ובוחרים באפשרות n1-standard-4 בתור סוג המכונה:
המודל שבהדגמה הזאת מתאמן במהירות ולכן אנחנו משתמשים במכונה מסוג קטן יותר.
בשלב מאגר חיזוי, בוחרים באפשרות ללא מאגר חיזוי:
6. פריסה של נקודת קצה (endpoint) של מודל
בשלב הזה ניצור נקודת קצה (endpoint) בשביל המודל שעבר אימון. אנחנו יכולים להשתמש בהם כדי לקבל חיזויים במודל שלנו באמצעות Vertex AI API. לשם כך, יצרנו גרסה של נכסי המודל המאומן שיוצאו, שיהיו זמינים בקטגוריה ציבורית של GCS.
בארגון, מקובל יש צוות אחד או אדם אחד שאחראי על בניית המודל, וצוות אחר שאחראי על הפריסה שלו. השלבים שמתוארים כאן יראו לכם איך לקחת מודל שכבר אומן ולפרוס אותו לצורך חיזוי.
כאן נשתמש ב-Vertex AI SDK כדי ליצור מודל, לפרוס אותו בנקודת קצה ולקבל חיזוי.
שלב 1: מתקינים את Vertex SDK
בטרמינל של Cloud Shell, מריצים את הפקודה הבאה כדי להתקין את Vertex AI SDK:
pip3 install google-cloud-aiplatform --upgrade --user
אנחנו יכולים להשתמש ב-SDK הזה כדי לקיים אינטראקציה עם חלקים שונים ושונים ב-Vertex.
שלב 2: יצירת מודל ופריסה של נקודת הקצה
בשלב הבא ניצור קובץ Python ונשתמש ב-SDK כדי ליצור משאב של מודל ונפרס אותו בנקודת קצה (endpoint). בעורך הקבצים ב-Cloud Shell, בוחרים באפשרות File ואז בוחרים באפשרות New File (קובץ חדש):
נותנים לקובץ שם: deploy.py
. פותחים את הקובץ הזה בעורך ומעתיקים את הקוד הבא:
from google.cloud import aiplatform
# Create a model resource from public model assets
model = aiplatform.Model.upload(
display_name="mpg-imported",
artifact_uri="gs://io-vertex-codelab/mpg-model/",
serving_container_image_uri="gcr.io/cloud-aiplatform/prediction/tf2-cpu.2-3:latest"
)
# Deploy the above model to an endpoint
endpoint = model.deploy(
machine_type="n1-standard-4"
)
אחר כך, חוזרים ל-Terminal ב-Cloud Shell, cd
חזרה ל-Root dir, ומריצים את סקריפט Python שיצרתם כרגע:
cd ..
python3 deploy.py | tee deploy-output.txt
בזמן שהמשאבים נוצרים, העדכונים יופיעו בטרמינל. ההפעלה תימשך 10-15 דקות. כדי לוודא פעולה תקינה, עוברים לקטע Models במסוף ב-Vertex AI:
לוחצים על mgp-Import (נקודת הקצה) של המודל שנוצר.
בטרמינל של Cloud Shell יופיע משהו כמו היומן הבא בסיום הפריסה של נקודת הקצה:
Endpoint model deployed. Resource name: projects/your-project-id/locations/us-central1/endpoints/your-endpoint-id
יש להשתמש באפשרות הזו בשלב הבא כדי לקבל חיזוי לגבי הקצה הקצה שנפרס.
שלב 3: קבלת תחזיות על נקודת הקצה שנפרסה
בעורך Cloud Shell, יוצרים קובץ חדש בשם predict.py
:
פותחים את predict.py
ומדביקים בו את הקוד הבא:
from google.cloud import aiplatform
endpoint = aiplatform.Endpoint(
endpoint_name="ENDPOINT_STRING"
)
# A test example we'll send to our model for prediction
test_mpg = [1.4838871833555929,
1.8659883497083019,
2.234620276849616,
1.0187816540094903,
-2.530890710602246,
-1.6046416850441676,
-0.4651483719733302,
-0.4952254087173721,
0.7746763768735953]
response = endpoint.predict([test_mpg])
print('API response: ', response)
print('Predicted MPG: ', response.predictions[0][0])
חוזרים לטרמינל ומזינים את הטקסט הבא כדי להחליף את ENDPOINT_STRING
בקובץ החיזוי בנקודת קצה משלכם:
ENDPOINT=$(cat deploy-output.txt | sed -nre 's:.*Resource name\: (.*):\1:p' | tail -1)
sed -i "s|ENDPOINT_STRING|$ENDPOINT|g" predict.py
עכשיו הגיע הזמן להריץ את הקובץ predict.py
כדי לקבל חיזוי מנקודת הקצה של המודל שנפרס:
python3 predict.py
התגובה מה-API אמורה להופיע ביומן, יחד עם צריכת הדלק החזויה לחיזוי הבדיקה.
🎉 כל הכבוד! 🎉
למדתם איך להשתמש ב-Vertex AI כדי:
- כדי לאמן מודל, מספקים את קוד האימון בקונטיינר בהתאמה אישית. השתמשתם במודל TensorFlow בדוגמה הזו, אבל אפשר לאמן מודל שנוצר עם כל מסגרת באמצעות קונטיינרים מותאמים אישית.
- פריסה של מודל TensorFlow באמצעות קונטיינר שפותח מראש כחלק מתהליך האימון שבו השתמשתם.
- יצירת נקודת קצה למודל ויצירה של חיזוי.
כדי לקבל מידע נוסף על החלקים השונים ב-Vertex AI, אתם יכולים לעיין במסמכי העזרה. כדי לראות את התוצאות של משימת האימון שהתחלתם בשלב 5, מנווטים לסעיף האימון במסוף Vertex.
7. הסרת המשאבים
כדי למחוק את נקודת הקצה שפרסתם, עוברים לקטע Endpoints במסוף Vertex ולוחצים על סמל המחיקה:
כדי למחוק את קטגוריית האחסון, באמצעות תפריט הניווט במסוף Cloud, עוברים אל Storage (אחסון), בוחרים את הקטגוריה ולוחצים על סמל המחיקה: