1. סקירה כללית
בשיעור ה-Lab הזה תשתמשו ב-Vertex AI כדי לאמן ולהציג מודל TensorFlow באמצעות קוד בקונטיינר מותאם אישית.
כאן אנחנו משתמשים ב-TensorFlow לקוד המודל, אבל אפשר להחליף אותו בקלות ב-framework אחר.
מה תלמדו
תלמדו איך:
- פיתוח קוד לאימון מודלים ב-Vertex Workbench והעברתו לקונטיינרים
- שליחת משימה מותאמת אישית לאימון מודל ל-Vertex AI
- פריסת המודל המאומן בנקודת קצה, ושימוש בנקודת הקצה הזו כדי לקבל חיזויים
העלות הכוללת להרצת הסדנה הזו ב-Google Cloud היא כ-$1.
2. מבוא ל-Vertex AI
במעבדה הזו נעשה שימוש במוצרי ה-AI החדשים ביותר שזמינים ב-Google Cloud. Vertex AI משלבת את חבילות ה-ML ב-Google Cloud לחוויית פיתוח חלקה. בעבר, היה אפשר לגשת למודלים שהותאמו אישית ולמודלים שהותאמו באמצעות AutoML דרך שירותים נפרדים. המוצר החדש משלב את שניהם ב-API אחד, יחד עם מוצרים חדשים אחרים. תוכלו גם להעביר פרויקטים קיימים ל-Vertex AI. יש לך משוב? אפשר להיכנס לדף התמיכה.
Vertex AI כולל הרבה מוצרים שונים לתמיכה בתהליכי עבודה של למידת מכונה מקצה לקצה. שיעור ה-Lab הזה יתמקד במוצרים המודגשים הבאים: הדרכה, חיזוי ו-Workbench.
3. הגדרת הסביבה
כדי להריץ את הקודלה הזה, צריך פרויקט ב-Google Cloud Platform שבו החיוב מופעל. כדי ליצור פרויקט, יש לפעול לפי ההוראות האלה.
שלב 1: מפעילים את Compute Engine API
עוברים אל Compute Engine ובוחרים באפשרות Enable (הפעלה) אם היא לא מופעלת. תצטרכו את זה כדי ליצור את מכונה של המחברות.
שלב 2: מפעילים את Vertex AI API
עוברים אל הקטע Vertex AI במסוף Cloud ולוחצים על Enable Vertex AI API.
שלב 3: מפעילים את Container Registry API
עוברים אל Container Registry ובוחרים באפשרות Enable (הפעלה) אם היא עדיין לא מסומנת. תשתמשו בו כדי ליצור קונטיינר למשימת האימון בהתאמה אישית.
שלב 4: יצירת מכונה של Vertex AI Workbench
בקטע Vertex AI במסוף Cloud, לוחצים על Workbench:
משם, בתוך notebooks בניהול המשתמשים, לוחצים על New Notebook:
לאחר מכן בוחרים את הגרסה האחרונה של סוג המכונה TensorFlow Enterprise (with LTS) without GPUs:
משתמשים באפשרויות ברירת המחדל ואז לוחצים על יצירה.
המודל שנלמד ונציג בשיעור ה-Lab הזה מבוסס על המדריך הזה ממסמכי TensorFlow. המדריך משתמש במערך הנתונים של Auto MPG מ-Kaggle כדי לחזות את צריכת הדלק של רכב.
4. יצירת קונטיינרים של קוד אימון
כדי לשלוח את משימת האימון הזו ל-Vertex, נשתמש בקונטיינר Docker ונשלח את הקונטיינר הזה ל-Google Container Registry. בעזרת הגישה הזו, אנחנו יכולים לאמן מודל שנוצר בכל מסגרת.
כדי להתחיל, פותחים חלון Terminal במכונה של המחברת בתפריט Launcher:
יוצרים ספרייה חדשה בשם mpg
ונכנסים אליה באמצעות cd:
mkdir mpg
cd mpg
שלב 1: יוצרים קובץ Docker
השלב הראשון ביצירת קונטיינרים לקוד שלנו הוא יצירת קובץ Docker. ב-Dockerfile שלנו נכלול את כל הפקודות הנדרשות להרצת קובץ האימג'. האפליקציה תתקין את כל הספריות שבהן אנחנו משתמשים ותגדיר את נקודת הכניסה לקוד האימון שלנו. בטרמינל, יוצרים קובץ Docker ריק:
touch Dockerfile
פותחים את Dockerfile ומעתיקים אליו את הטקסט הבא:
FROM gcr.io/deeplearning-platform-release/tf2-cpu.2-6
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 מגיעים עם הרבה frameworks נפוצים של מדעי נתונים ולמידת מכונה שהותקנו מראש. הגרסה שבה אנחנו משתמשים כוללת את TF Enterprise 2.3, Pandas, Scikit-learn ועוד. אחרי הורדת התמונה, קובץ ה-Dockerfile מגדיר את נקודת הכניסה לקוד האימון שלנו. עדיין לא יצרנו את הקבצים האלה – בשלב הבא נוסיף את הקוד לאימון ולייצוא של המודל.
שלב 2: יצירת קטגוריה ב-Cloud Storage
במשימת האימון שלנו, נייצא את מודל TensorFlow המאומן שלנו לקטגוריה של Cloud Storage. מערכת Vertex תשתמש בו כדי לקרוא את נכסי המודל שייצאנו ולפרוס את המודל. ב-Terminal, מריצים את הפקודה הבאה כדי להגדיר משתנה סביבה לפרויקט. חשוב להחליף את your-cloud-project
במזהה הפרויקט:
PROJECT_ID='your-cloud-project'
לאחר מכן, מריצים את הפקודה הבאה ב-Terminal כדי ליצור קטגוריה חדשה בפרויקט. הדגל -l
(מיקום) חשוב כי הוא צריך להיות באותו אזור שבו תפרסו נקודת קצה של מודל בהמשך המדריך:
BUCKET_NAME="gs://${PROJECT_ID}-bucket"
gsutil mb -l us-central1 $BUCKET_NAME
שלב 3: מוסיפים את הקוד לאימון המודל
בטרמינל, מריצים את הפקודה הבאה כדי ליצור ספרייה לקוד האימון שלנו וקובץ Python שאליו נוסיף את הקוד:
mkdir trainer
touch trainer/train.py
עכשיו אמורים להופיע הפריטים הבאים בספרייה mpg/ :
+ Dockerfile
+ trainer/
+ train.py
אחר כך פותחים את הקובץ train.py
שיצרתם ומעתיקים את הקוד שלמטה (הקוד מותאם מהמדריך במסמכי TensorFlow).
בתחילת הקובץ, מעדכנים את המשתנה BUCKET
בשם של קטגוריית האחסון שיצרתם בשלב הקודם:
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.
"""
dataset_path = keras.utils.get_file("auto-mpg.data", "http://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data")
dataset_path
"""Import it using pandas"""
column_names = ['MPG','Cylinders','Displacement','Horsepower','Weight',
'Acceleration', 'Model Year', 'Origin']
dataset = pd.read_csv(dataset_path, names=column_names,
na_values = "?", comment='\t',
sep=" ", skipinitialspace=True)
dataset.tail()
# TODO: replace `your-gcs-bucket` with the name of the Storage bucket you created earlier
BUCKET = 'gs://your-gcs-bucket'
"""### 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')
שלב 4: יצירת גרסת build ובדיקה של הקונטיינר באופן מקומי
ב-Terminal, מגדירים משתנה עם ה-URI של קובץ האימג' בקונטיינר ב-Google Container Registry:
IMAGE_URI="gcr.io/$PROJECT_ID/mpg:v1"
לאחר מכן, כדי ליצור את הקונטיינר, מריצים את הפקודה הבאה מהשורש של ספריית mpg
:
docker build ./ -t $IMAGE_URI
מריצים את הקונטיינר במכונה של המחברות כדי לוודא שהוא פועל כמו שצריך:
docker run $IMAGE_URI
תהליך האימון של המודל אמור להסתיים תוך דקה או שתיים, עם רמת דיוק אימות של כ-72% (רמת הדיוק המדויקת עשויה להשתנות). בסיום ההרצה המקומית של הקונטיינר, מעבירים אותו אל Google Container Registry:
docker push $IMAGE_URI
בעקבות העברת הקונטיינר שלנו ל-Container Registry, אנחנו מוכנים להתחיל משימה לאימון מודלים מותאמים אישית.
5. הרצת משימה של אימון ב-Vertex AI
ב-Vertex AI יש שתי אפשרויות לאימון מודלים:
- AutoML: אימון מודלים באיכות גבוהה עם מומחיות ב-ML ובמאמץ מינימלי.
- אימון מותאם אישית: הפעלת אפליקציות אימון בהתאמה אישית בענן באמצעות אחד מהקונטיינרים המוכנים מראש של Google Cloud, או באמצעות קונטיינר משלכם.
במעבדה הזו נשתמש באימון בהתאמה אישית באמצעות קונטיינר בהתאמה אישית שלנו ב-Google Container Registry. כדי להתחיל, עוברים לקטע Models בקטע Vertex במסוף Cloud:
שלב 1: מפעילים את משימה האימון
לוחצים על יצירה כדי להזין את הפרמטרים של משימת האימון והמודל שנפרס:
- בקטע מערך נתונים, בוחרים באפשרות אין מערך נתונים מנוהל.
- לאחר מכן בוחרים באפשרות אימון מותאם אישית (מתקדם) כשיטת האימון ולוחצים על המשך.
- לוחצים על המשך.
בשלב הבא, מזינים mpg
(או כל שם אחר שרוצים לתת למודל) בשדה Model name. לאחר מכן בוחרים באפשרות מאגר מותאם אישית:
בתיבה Container image, לוחצים על Browse ומאתרים את קובץ האימג' של Docker שהעליתם ל-Container Registry. משאירים את שאר השדות ריקים ולוחצים על Continue (המשך).
לא נשתמש בכוונון היפר-פרמטרים במדריך הזה, לכן משאירים את תיבת הכוונון 'הפעלת היפר-פרמטרים' לא מסומנת ולוחצים על המשך.
בקטע Compute and pricing, משאירים את האזור שנבחר כפי שהוא ובוחרים באפשרות n1-standard-4 כסוג המכונה:
משאירים את השדות של המאיץ ריקים ובוחרים באפשרות המשך. מכיוון שהאימון של המודל בדמו הזה מתבצע במהירות, אנחנו משתמשים בסוג מכונה קטן יותר.
בשלב Prediction container, בוחרים באפשרות Pre-built container ואז בוחרים ב-TensorFlow 2.6.
משאירים את הגדרות ברירת המחדל של הקונטיינר שנוצר מראש כפי שהן. בקטע Model directory, מזינים את הקטגוריה ב-GCS עם ספריית המשנה mpg. זהו הנתיב בסקריפט לאימון המודל שבו מייצאים את המודל המאומן:
מערכת Vertex תחפש במיקום הזה במהלך פריסת המודל. עכשיו אתם מוכנים לאימון! לוחצים על Start training כדי להתחיל את משימת האימון. בקטע Training במסוף יופיע משהו כזה:
6. פריסת נקודת קצה של מודל
כשהגדרנו את משימה האימון, צינינו איפה מערכת Vertex AI תצטרך לחפש את נכסי המודל המיוצאים שלנו. כחלק מצינור עיבוד הנתונים לאימון, מערכת Vertex תיצור משאב מודל על סמך נתיב הנכס הזה. משאב המודל עצמו הוא לא מודל שנפרס, אבל ברגע שיש לכם מודל אתם מוכנים לפרוס אותו בנקודת קצה. מידע נוסף על מודלים ונקודות קצה ב-Vertex AI זמין במסמכי העזרה.
בשלב הזה נוצר נקודת קצה (endpoint) למודל המאומן. נוכל להשתמש בזה כדי לקבל תחזיות לגבי המודל שלנו דרך Vertex AI API.
שלב 1: פריסת נקודת קצה
בסיום משימת האימון, אמור להופיע מודל בשם mpg (או השם שהגדרתם לו) בקטע Models במסוף:
כשמשימת האימון שלכם רצה, מערכת Vertex יצרה בשבילכם משאב מודל. כדי להשתמש במודל הזה, צריך לפרוס נקודת קצה. יכולות להיות לכם הרבה נקודות קצה לכל מודל. לוחצים על המודל ואז על פריסה לנקודת קצה.
בוחרים באפשרות Create new endpoint (יצירת נקודת קצה חדשה) ומעניקים לה שם, למשל v1. משאירים את האפשרות Standard (רגילה) מסומנת בקטע Access (גישה) ולוחצים על Continue (המשך).
משאירים את הערך של חלוקת התנועה כ-100, ומזינים 1 לצורך מספר מינימלי של צומתי מחשוב. בקטע Machine type, בוחרים באפשרות n1-standard-2 (או בכל סוג מכונה אחר שרוצים). משאירים את שאר ברירות המחדל מסומנות ולוחצים על המשך. לא נפעיל מעקב אחרי המודל הזה, לכן בשלב הבא לוחצים על פריסה כדי להתחיל את פריסת נקודת הקצה.
פריסה של נקודת הקצה תימשך 10 עד 15 דקות. בסיום הפריסה תקבלו אימייל. בסיום הפריסה של נקודת הקצה, יוצג המסך הבא, שבו מוצגת נקודת קצה אחת שנפרסה במשאב ה-Model:
שלב 2: הצגת תחזיות לפי המודל שנפרס
נקבל תחזיות לגבי המודל המאומן שלנו מ-notebook של Python, באמצעות Vertex Python API. חוזרים למכונה של המחברות ויוצרים מחברת Python 3 מ-Launcher:
ב-notebook, מריצים את הפקודה הבאה בתא כדי להתקין את Vertex AI SDK:
!pip3 install google-cloud-aiplatform --upgrade --user
לאחר מכן מוסיפים תא ביומן כדי לייבא את ה-SDK וליצור הפניה לנקודת הקצה שפרסמתם:
from google.cloud import aiplatform
endpoint = aiplatform.Endpoint(
endpoint_name="projects/YOUR-PROJECT-NUMBER/locations/us-central1/endpoints/YOUR-ENDPOINT-ID"
)
צריך להחליף שני ערכים במחרוזת endpoint_name
שלמעלה במספר הפרויקט ונקודת הקצה. כדי למצוא את מספר הפרויקט, עוברים אל מרכז הבקרה של הפרויקט ומקבלים את הערך של Project Number.
מזהה נקודת הקצה מופיע בקטע 'נקודות קצה' במסוף, כאן:
לבסוף, כדי לבצע חיזוי לנקודת הקצה, מעתיקים את הקוד הבא ומריצים אותו בתא חדש:
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])
בדוגמה הזו כבר יש ערכים מנורמלים, הפורמט שהמודל שלנו מצפה לקבל.
מריצים את התא הזה, ואמור להופיע פלט של תחזית של כ-8 ק"מ לליטר.
🎉 מזל טוב! 🎉
למדתם איך להשתמש ב-Vertex AI כדי:
- אימון מודל על ידי הוספת קוד האימון בקונטיינר בהתאמה אישית. בדוגמה הזו השתמשתם במודל TensorFlow, אבל אפשר לאמן מודל שנוצר בכל מסגרת באמצעות קונטיינרים מותאמים אישית.
- פריסה של מודל TensorFlow באמצעות קונטיינר שפותח מראש כחלק מתהליך האימון שבו השתמשתם.
- יצירת נקודת קצה למודל ויצירה של חיזוי.
מידע נוסף על החלקים השונים של Vertex זמין במסמכי העזרה.
7. הסרת המשאבים
אם אתם רוצים להמשיך להשתמש במחברת שיצרתם במעבדה הזו, מומלץ לכבות אותה כשהיא לא בשימוש. בממשק המשתמש של Workbench במסוף Cloud, בוחרים את המחברות ואז בוחרים באפשרות Stop.
אם רוצים למחוק את המחברות לגמרי, לוחצים על לחצן המחיקה בפינה השמאלית העליונה.
כדי למחוק את נקודת הקצה שפרסמתם, עוברים לקטע Endpoints במסוף Vertex AI, לוחצים על נקודת הקצה שיצרתם ובוחרים באפשרות Undeploy model from endpoint:
כדי למחוק את הקטגוריה של האחסון, עוברים לתפריט הניווט במסוף Cloud, לוחצים על Storage, בוחרים את הקטגוריה ולוחצים על Delete: