לוגו זפירנט

הטמעת משימת AutoML מותאמת אישית באמצעות אלגוריתמים שנבחרו מראש באמזון SageMaker Automatic Model Tuning | שירותי האינטרנט של אמזון

תאריך:

AutoML מאפשר לך להפיק תובנות מהירות וכלליות מהנתונים שלך ממש בתחילת מחזור החיים של פרויקט למידת מכונה (ML). הבנה מראש אילו טכניקות עיבוד מקדים וסוגי אלגוריתמים מספקים את התוצאות הטובות ביותר מפחיתה את הזמן לפיתוח, אימון ופריסה של המודל הנכון. הוא ממלא תפקיד מכריע בתהליך הפיתוח של כל מודל ומאפשר למדעני נתונים להתמקד בטכניקות ה-ML המבטיחות ביותר. בנוסף, AutoML מספקת ביצועי מודל בסיסי שיכולים לשמש נקודת התייחסות לצוות מדעי הנתונים.

כלי AutoML מחיל שילוב של אלגוריתמים שונים וטכניקות עיבוד מקדים שונות על הנתונים שלך. לדוגמה, הוא יכול לשנות את קנה המידה של הנתונים, לבצע בחירת תכונה חד-משתנית, לבצע PCA ברמות סף שונות של שונות ולהחיל אשכולות. ניתן ליישם טכניקות עיבוד מקדים כאלה בנפרד או לשלב בצנרת. לאחר מכן, כלי AutoML יאמן סוגי מודלים שונים, כגון Linear Regression, Elastic-Net או Random Forest, על גרסאות שונות של מערך הנתונים המעובדים מראש שלך ויבצע אופטימיזציה של היפרפרמטרים (HPO). טייס אוטומטי של אמזון מבטל את ההרמה הכבדה של בניין דגמי ML. לאחר מתן מערך הנתונים, SageMaker Autopilot בוחן אוטומטית פתרונות שונים כדי למצוא את הדגם הטוב ביותר. אבל מה אם אתה רוצה לפרוס את הגרסה המותאמת שלך של זרימת עבודה AutoML?

פוסט זה מראה כיצד ליצור זרימת עבודה AutoML בהתאמה אישית אמזון SageMaker באמצעות אמזון SageMaker כוונון דגם אוטומטי עם קוד לדוגמה זמין ב-a ריפו GitHub.

סקירת פתרונות

במקרה השימוש הזה, נניח שאתה חלק מצוות מדעי נתונים שמפתח מודלים בתחום מיוחד. פיתחת קבוצה של טכניקות עיבוד מוקדם מותאמות אישית ובחרת מספר אלגוריתמים שאתה מצפה בדרך כלל שיעבדו היטב עם בעיית ה-ML שלך. כשאתה עובד על מקרי שימוש חדשים ב-ML, תרצה תחילה לבצע ריצת AutoML באמצעות טכניקות העיבוד המקדים והאלגוריתמים שלך כדי לצמצם את היקף הפתרונות הפוטנציאליים.

עבור דוגמה זו, אינך משתמש במערך נתונים מיוחד; במקום זאת, אתה עובד עם מערך הנתונים של California Housing שממנו תייבא שירות אחסון פשוט של אמזון (אמזון S3). ההתמקדות היא להדגים את היישום הטכני של הפתרון באמצעות SageMaker HPO, שבהמשך ניתן ליישם אותו על כל מערך נתונים ותחום.

התרשים הבא מציג את זרימת העבודה הכוללת של הפתרון.

דיאגרמת ארכיטקטורה המציגה את השלבים המוסברים בסעיף ההליכה הבא.

תנאים מוקדמים

להלן תנאים מוקדמים להשלמת ההדרכה בפוסט זה:

מיישמים את הפתרון

הקוד המלא זמין ב- GitHub ריפו.

השלבים ליישום הפתרון (כפי שמצוין בתרשים זרימת העבודה) הם כדלקמן:

  1. צור מופע מחברת וציין את הדברים הבאים:
    1. בעד סוג מופע מחברת, בחר ml.t3.בינוני.
    2. בעד מסקנות אלסטיות, בחר אף לא אחד.
    3. בעד מזהה פלטפורמה, בחר אמזון לינוקס 2, Jupyter Lab 3.
    4. בעד תפקיד IAM, בחר את ברירת המחדל AmazonSageMaker-ExecutionRole. אם הוא לא קיים, צור חדש AWS זהות וניהול גישה (IAM) תפקיד ולצרף את מדיניות AmazonSageMakerFullAccess IAM.

שים לב שעליך ליצור תפקיד ומדיניות ביצוע בהיקף מינימלי בייצור.

  1. פתח את ממשק JupyterLab עבור מופע המחברת שלך ושבט את המאגר של GitHub.

אתה יכול לעשות זאת על ידי התחלת הפעלת טרמינל חדשה והפעלת ה git clone <REPO> פקודה או באמצעות פונקציונליות ממשק המשתמש, כפי שמוצג בצילום המסך הבא.

כפתור שילוב git של JupyterLab

  1. פתח את automl.ipynb קובץ המחברת, בחר את conda_python3 קרנל, ופעל לפי ההוראות כדי להפעיל את a סט משרות HPO.

כדי להפעיל את הקוד ללא כל שינוי, עליך להגדיל את מכסת השירות עבור ml.m5.large לשימוש בעבודה הדרכה ו מספר המקרים בכל משרות ההדרכה. AWS מאפשרת כברירת מחדל רק 20 עבודות הכשרה מקבילות של SageMaker עבור שתי המכסות. עליך לבקש הגדלת מכסה ל-30 עבור שניהם. בדרך כלל יש לאשר את שני שינויי המכסה תוך מספר דקות. מתייחס מבקש הגדלת מכסה לקבלת מידע נוסף.

דף מכסות שירות של AWS המאפשר לבקש הגדלה בעבודות הכשרה מקבילות מסוג מופע מסוים

אם אינך רוצה לשנות את המכסה, אתה יכול פשוט לשנות את הערך של ה- MAX_PARALLEL_JOBS משתנה בסקריפט (לדוגמה, עד 5).

  1. כל עבודת HPO תשלים סט של עבודת הכשרה ניסויים ומציינים את המודל עם היפרפרמטרים אופטימליים.
  2. נתח את התוצאות ו לפרוס את המודל בעל הביצועים הטובים ביותר.

פתרון זה יגרור עלויות בחשבון AWS שלך. העלות של פתרון זה תהיה תלויה במספר ומשך משרות ההכשרה של HPO. ככל שאלו יעלו, כך גם העלות תגדל. אתה יכול להפחית עלויות על ידי הגבלת זמן ההדרכה והגדרת התצורה TuningJobCompletionCriteriaConfig לפי ההנחיות שנדונו בהמשך הפוסט הזה. למידע על תמחור, עיין ב תמחור SageMaker של אמזון.

בסעיפים הבאים, אנו דנים במחברת ביתר פירוט עם דוגמאות קוד והשלבים לניתוח התוצאות ולבחירת המודל הטוב ביותר.

התקנה ראשונית

בואו נתחיל עם הפעלת ה יבוא והגדרה סעיף ב custom-automl.ipynb מחברת. הוא מתקין ומייבא את כל התלות הנדרשת, מפעיל הפעלה ולקוח של SageMaker, ומגדיר את ברירת המחדל של אזור ודלי S3 לאחסון נתונים.

הכנת נתונים

הורד את מערך הנתונים של California Housing והכן אותו על ידי הפעלת הורד נתונים חלק של המחברת. מערך הנתונים מפוצל למסגרות נתוני אימון ובדיקה ומועלה לדלי ברירת המחדל של הפעלת SageMaker S3.

למערך הנתונים כולו 20,640 רשומות ו-9 עמודות בסך הכל, כולל היעד. המטרה היא לחזות את הערך החציוני של בית (medianHouseValue טור). צילום המסך הבא מציג את השורות העליונות של מערך הנתונים.

חמש השורות העליונות של מסגרת נתוני הדיור בקליפורניה המציגות את מבנה הטבלה

תבנית תסריט הדרכה

זרימת העבודה של AutoML בפוסט זה מבוססת על סקיקיט-לימוד צינורות ואלגוריתמים לעיבוד מקדים. המטרה היא ליצור שילוב גדול של צינורות עיבוד מוקדם ואלגוריתמים שונים כדי למצוא את ההגדרה בעלת הביצועים הטובים ביותר. נתחיל עם יצירת סקריפט הדרכה גנרי, אשר קיים באופן מקומי במופע המחברת. בסקריפט זה, ישנם שני בלוקי הערות ריקים: האחד להזרקת הפרמטרים והשני עבור אובייקט הצינור של מודל ה-preprocessing. הם יוזרקו באופן דינמי עבור כל מועמד למודל עיבוד מקדים. המטרה של סקריפט גנרי אחד היא לשמור על היישום DRY (אל תחזור על עצמך).

#create base script
_script = """
import argparse
import joblib
import os
import numpy as np
import pandas as pd
from sklearn.metrics import mean_squared_error
from sklearn.pipeline import Pipeline, FeatureUnion
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.impute import SimpleImputer
from sklearn.cluster import KMeans
from sklearn.linear_model import ElasticNet
from sklearn.ensemble import RandomForestRegressor
from sklearn.ensemble import GradientBoostingRegressor
###########################
### Inference functions ###
###########################
def model_fn(model_dir):
clf = joblib.load(os.path.join(model_dir, "model.joblib"))
return clf
if __name__ == "__main__":
print("Extracting arguments")
parser = argparse.ArgumentParser()
# Hyperparameters
##### WILL BE INSERTED DYNAMICALLY #####
{}
############################
# Data, model, and output directories
parser.add_argument("--model-dir", type=str, default=os.environ.get("SM_MODEL_DIR"))
parser.add_argument("--train", type=str, default=os.environ.get("SM_CHANNEL_TRAIN"))
parser.add_argument("--test", type=str, default=os.environ.get("SM_CHANNEL_TEST"))
parser.add_argument("--train-file", type=str, default="train.parquet")
parser.add_argument("--test-file", type=str, default="test.parquet")
parser.add_argument("--features", type=str)
parser.add_argument("--target", type=str)
args, _ = parser.parse_known_args()
# Load and prepare data
train_df = pd.read_parquet(os.path.join(args.train, args.train_file))
test_df = pd.read_parquet(os.path.join(args.test, args.test_file))
X_train = train_df[args.features.split()]
X_test = test_df[args.features.split()]
y_train = train_df[args.target]
y_test = test_df[args.target]
# Train model
##### WILL BE INSERTED DYNAMICALLY #####
{}
{}
############################
pipeline = Pipeline([('preprocessor', preprocessor), ('model', model)])
pipeline.fit(X_train, y_train)
# Validate model and print metrics
rmse = mean_squared_error(y_test, pipeline.predict(X_test), squared=False)
print("RMSE: " + str(rmse))
# Persist model
path = os.path.join(args.model_dir, "model.joblib")
joblib.dump(pipeline, path) """
# write _script to file just to have it in hand
with open("script_draft.py", "w") as f:
print(_script, file=f)

צור שילובי עיבוד מקדים ומודלים

השמיים preprocessors המילון מכיל מפרט של טכניקות עיבוד מקדים המיושמות על כל תכונות הקלט של המודל. כל מתכון מוגדר באמצעות א Pipeline או FeatureUnion אובייקט מ-scikit-learn, שמשרשרת יחד טרנספורמציות נתונים בודדות ומערימה אותן יחד. לדוגמה, mean-imp-scale הוא מתכון פשוט המבטיח שהערכים החסרים יזקפו באמצעות ערכים ממוצעים של עמודות מתאימות ושכל התכונות יעברו קנה מידה באמצעות StandardScaler. לעומת זאת, ה mean-imp-scale-pca מתכונים משלבים עוד כמה פעולות:

  1. זקוף ערכים חסרים בעמודות עם הממוצע שלו.
  2. החל קנה מידה של תכונה באמצעות ממוצע וסטיית תקן.
  3. חשב PCA על גבי נתוני הקלט בערך סף שונות שצוין ומיזג אותו יחד עם תכונות הקלט הזקיפות והמותאם.

בפוסט זה, כל תכונות הקלט הן מספריות. אם יש לך יותר סוגי נתונים במערך הקלט שלך, עליך לציין צינור מסובך יותר שבו ענפי עיבוד מקדים שונים מוחלים על ערכות סוגי תכונות שונות.

preprocessors = { "mean-imp-scale": "preprocessor = Pipeline([('imputer', SimpleImputer(strategy='mean')), ('scaler', StandardScaler())])n", "mean-imp-scale-knn": "preprocessor = FeatureUnion([('base-features', Pipeline([('imputer', SimpleImputer(strategy='mean')), ('scaler', StandardScaler())])), ('knn', Pipeline([('imputer', SimpleImputer(strategy='mean')), ('scaler', StandardScaler()), ('knn', KMeans(n_clusters=10))]))])n", "mean-imp-scale-pca": "preprocessor = FeatureUnion([('base-features', Pipeline([('imputer', SimpleImputer(strategy='mean')), ('scaler', StandardScaler())])), ('pca', Pipeline([('imputer', SimpleImputer(strategy='mean')), ('scaler', StandardScaler()), ('pca', PCA(n_components=0.9))]))])n" }

השמיים models המילון מכיל מפרטים של אלגוריתמים שונים שאליהם אתה מתאים את מערך הנתונים. כל סוג דגם מגיע עם המפרט הבא במילון:

  • script_output – מצביע על מיקומו של תסריט האימון המשמש את האומד. שדה זה מתמלא באופן דינמי כאשר models המילון משולב עם ה preprocessors מילון.
  • הכנסות – מגדיר קוד שיוכנס לתוך script_draft.py ובהמשך נשמר תחת script_output. המפתח “preprocessor” נותר ריק בכוונה מכיוון שמיקום זה מלא באחד ממעבדי הקדם כדי ליצור שילובים מרובים של דגם-קדם מעבד.
  • יתר פרמטרים – קבוצה של היפרפרמטרים שעברו אופטימיזציה על ידי עבודת HPO.
  • include_cls_metadata - פרטי תצורה נוספים הנדרשים על ידי SageMaker Tuner מעמד.

דוגמה מלאה של models המילון זמין במאגר GitHub.

models = { "rf": { "script_output": None, "insertions": { # Arguments "arguments" : "parser.add_argument('--n_estimators', type=int, default=100)n"+ " parser.add_argument('--max_depth', type=int, default=None)n"+ " parser.add_argument('--min_samples_leaf', type=int, default=1)n"+ " parser.add_argument('--min_samples_split', type=int, default=2)n"+ " parser.add_argument('--max_features', type=str, default='auto')n", # Model call "preprocessor": None, "model_call" : "model = RandomForestRegressor(n_estimators=args.n_estimators,max_depth=args.max_depth,min_samples_leaf=args.min_samples_leaf,min_samples_split=args.min_samples_split,max_features=args.max_features)n" }, "hyperparameters": { "n_estimators": IntegerParameter(100, 2000, "Linear"), "max_depth": IntegerParameter(1, 100, "Logarithmic"), "min_samples_leaf": IntegerParameter(1, 6, "Linear"), "min_samples_split": IntegerParameter(2, 20, "Linear"), "max_features": CategoricalParameter(["auto", "sqrt", "log2"]), }, "include_cls_metadata": False, }
}

לאחר מכן, בואו נעבור דרך ה preprocessors ו models מילונים וליצור את כל השילובים האפשריים. לדוגמה, אם שלך preprocessors המילון מכיל 10 מתכונים ויש לך 5 הגדרות מודל ב models מילון, מילון הצינורות החדש שנוצר מכיל 50 צינורות מודל קדם-מעבד אשר מוערכים במהלך HPO. שים לב שסקריפטים בודדים של צינורות לא נוצרו עדיין בשלב זה. בלוק הקוד הבא (תא 9) של המחברת Jupyter חוזרת דרך כל האובייקטים של מודל קדם-מעבד ב- pipelines מילון, מוסיף את כל חלקי הקוד הרלוונטיים, ומחזיק גרסה ספציפית לצינור של הסקריפט באופן מקומי במחברת. סקריפטים אלה משמשים בשלבים הבאים בעת יצירת אומדנים בודדים שאתה מחבר לעבודת HPO.

pipelines = {}
for model_name, model_spec in models.items(): pipelines[model_name] = {} for preprocessor_name, preprocessor_spec in preprocessors.items(): pipeline_name = f"{model_name}-{preprocessor_name}" pipelines[model_name][pipeline_name] = {} pipelines[model_name][pipeline_name]["insertions"] = {} pipelines[model_name][pipeline_name]["insertions"]["preprocessor"] = preprocessor_spec pipelines[model_name][pipeline_name]["hyperparameters"] = model_spec["hyperparameters"] pipelines[model_name][pipeline_name]["include_cls_metadata"] = model_spec["include_cls_metadata"] pipelines[model_name][pipeline_name]["insertions"]["arguments"] = model_spec["insertions"]["arguments"] pipelines[model_name][pipeline_name]["insertions"]["model_call"] = model_spec["insertions"]["model_call"] pipelines[model_name][pipeline_name]["script_output"] = f"scripts/{model_name}/script-{pipeline_name}.py"

הגדר אומדנים

כעת תוכל לעבוד על הגדרת SageMaker Estimators שעבודת HPO משתמשת בהם לאחר שהסקריפטים מוכנים. נתחיל ביצירת מחלקה עטיפה המגדירה כמה מאפיינים משותפים לכל האומדנים. זה יורש מה SKLearn class ומציין את התפקיד, ספירת המופעים והסוג, כמו גם אילו עמודות משמשות את הסקריפט כתכונות וכמטרה.

class SKLearnBase(SKLearn): def __init__( self, entry_point=".", # intentionally left blank, will be overwritten in the next function framework_version="1.2-1", role=sm_role, instance_count=1, instance_type="ml.c5.xlarge", hyperparameters={ "features": "medianIncome housingMedianAge totalRooms totalBedrooms population households latitude longitude", "target": "medianHouseValue", }, **kwargs, ): super(SKLearnBase, self).__init__( entry_point=entry_point, framework_version=framework_version, role=role, instance_count=instance_count, instance_type=instance_type, hyperparameters=hyperparameters, **kwargs )

בואו נבנה את estimators מילון על ידי איטרציה של כל הסקריפטים שנוצרו לפני וממוקמים ב- scripts מַדרִיך. אתה יוצר אומדן חדש באמצעות ה- SKLearnBase כיתה, עם שם אומד ייחודי, ואחד מהסקריפטים. שימו לב שה- estimators למילון שתי רמות: הרמה העליונה מגדירה א pipeline_family. זוהי קיבוץ לוגי המבוסס על סוג המודלים שיש להעריך ושווה לאורך ה- models מילון. הרמה השנייה מכילה סוגי קדם-מעבד בודדים בשילוב עם הנתון pipeline_family. קיבוץ לוגי זה נדרש בעת יצירת עבודת HPO.

estimators = {}
for pipeline_family in pipelines.keys(): estimators[pipeline_family] = {} scripts = os.listdir(f"scripts/{pipeline_family}") for script in scripts: if script.endswith(".py"): estimator_name = script.split(".")[0].replace("_", "-").replace("script", "estimator") estimators[pipeline_family][estimator_name] = SKLearnBase( entry_point=f"scripts/{pipeline_family}/{script}", base_job_name=estimator_name, )

הגדר ארגומנטים של טיונר HPO

כדי לייעל את העברת הטיעונים ל-HPO Tuner הכיתה, ה HyperparameterTunerArgs מחלקת הנתונים מאותחלת עם ארגומנטים הנדרשים על ידי מחלקת HPO. זה מגיע עם קבוצת פונקציות, המבטיחות שארגומנטים של HPO מוחזרים בפורמט הצפוי בעת פריסת הגדרות מודל מרובות בו-זמנית.

@dataclass
class HyperparameterTunerArgs: base_job_names: list[str] estimators: list[object] inputs: dict[str] objective_metric_name: str hyperparameter_ranges: list[dict] metric_definition: dict[str] include_cls_metadata: list[bool] def get_estimator_dict(self) -> dict: return {k:v for (k, v) in zip(self.base_job_names, self.estimators)} def get_inputs_dict(self) -> dict: return {k:v for (k, v) in zip(self.base_job_names, [self.inputs]*len(self.base_job_names))} def get_objective_metric_name_dict(self) -> dict: return {k:v for (k, v) in zip(self.base_job_names, [self.objective_metric_name]*len(self.base_job_names))} def get_hyperparameter_ranges_dict(self) -> dict: return {k:v for (k, v) in zip(self.base_job_names, self.hyperparameter_ranges)} def get_metric_definition_dict(self) -> dict: return {k:[v] for (k, v) in zip(self.base_job_names, [self.metric_definition]*len(self.base_job_names))} def get_include_cls_metadata_dict(self) -> dict: return {k:v for (k, v) in zip(self.base_job_names, self.include_cls_metadata)}

בלוק הקוד הבא משתמש בקוד שהוצג קודם לכן HyperparameterTunerArgs מחלקת נתונים. אתה יוצר עוד מילון בשם hp_args וליצור קבוצה של פרמטרי קלט ספציפיים לכל אחד estimator_family מ estimators מילון. טיעונים אלה משמשים בשלב הבא בעת אתחול עבודות HPO עבור כל משפחת מודל.

hp_args = {}
for estimator_family, estimators in estimators.items(): hp_args[estimator_family] = HyperparameterTunerArgs( base_job_names=list(estimators.keys()), estimators=list(estimators.values()), inputs={"train": s3_data_train.uri, "test": s3_data_test.uri}, objective_metric_name="RMSE", hyperparameter_ranges=[pipeline.get("hyperparameters") for pipeline in pipelines[estimator_family].values()], metric_definition={"Name": "RMSE", "Regex": "RMSE: ([0-9.]+).*$"}, include_cls_metadata=[pipeline.get("include_cls_metadata") for pipeline in pipelines[estimator_family].values()], )

צור אובייקטים של מקלט HPO

בשלב זה, אתה יוצר מקלטים בודדים עבור כל אחד estimator_family. מדוע אתה יוצר שלוש משרות נפרדות של HPO במקום להשיק רק אחת בכל האומדנים? ה HyperparameterTuner המחלקה מוגבלת ל-10 הגדרות מודל המצורפות אליו. לכן, כל HPO אחראי למציאת הפרה-מעבד בעל הביצועים הטובים ביותר עבור משפחת דגמים נתונה וכוונון הפרמטרים ההיפרפרמטרים של משפחת דגמים זו.

להלן מספר נקודות נוספות לגבי ההגדרה:

  • אסטרטגיית האופטימיזציה היא Bayesian, מה שאומר שה-HPO עוקב באופן פעיל אחר הביצועים של כל הניסויים ומנווט את האופטימיזציה לעבר שילובי היפרפרמטרים מבטיחים יותר. יש להגדיר עצירה מוקדמת ל כבוי or אוטומטי כאשר עובדים עם אסטרטגיה בייסיאנית, שמטפלת בהיגיון הזה בעצמה.
  • כל משרת HPO פועלת ל-100 משרות לכל היותר ופועלת 10 משרות במקביל. אם אתה מתמודד עם מערכי נתונים גדולים יותר, ייתכן שתרצה להגדיל את מספר המשרות הכולל.
  • בנוסף, ייתכן שתרצה להשתמש בהגדרות השולטות כמה זמן עבודה פועלת וכמה עבודות ה-HPO שלך מפעיל. אחת הדרכים לעשות זאת היא להגדיר את זמן הריצה המקסימלי בשניות (עבור פוסט זה, הגדרנו אותו לשעה אחת). אחר הוא להשתמש בגרסה ששוחררה לאחרונה TuningJobCompletionCriteriaConfig. הוא מציע סט של הגדרות שמנטרות את התקדמות העבודות שלך ומחליטות אם סביר להניח שעבודות נוספות ישפרו את התוצאה. בפוסט זה, הגדרנו את המספר המרבי של משרות הכשרה שאינן משתפרות ל-20. כך, אם הציון אינו משתפר (לדוגמה, מהניסיון הארבעים), לא תצטרכו לשלם עבור שאר הניסיון עד max_jobs מושג.
STRATEGY = "Bayesian"
OBJECTIVE_TYPE = "Minimize"
MAX_JOBS = 100
MAX_PARALLEL_JOBS = 10
MAX_RUNTIME_IN_SECONDS = 3600
EARLY_STOPPING_TYPE = "Off"
# RANDOM_SEED = 42 # uncomment if you require reproducibility across runs
TUNING_JOB_COMPLETION_CRITERIA_CONFIG = TuningJobCompletionCriteriaConfig( max_number_of_training_jobs_not_improving=20, ) tuners = {}
for estimator_family, hp in hp_args.items(): tuners[estimator_family] = HyperparameterTuner.create( estimator_dict=hp.get_estimator_dict(), objective_metric_name_dict=hp.get_objective_metric_name_dict(), hyperparameter_ranges_dict=hp.get_hyperparameter_ranges_dict(), metric_definitions_dict=hp.get_metric_definition_dict(), strategy=STRATEGY, completion_criteria_config=TUNING_JOB_COMPLETION_CRITERIA_CONFIG, objective_type=OBJECTIVE_TYPE, max_jobs=MAX_JOBS, max_parallel_jobs=MAX_PARALLEL_JOBS, max_runtime_in_seconds=MAX_RUNTIME_IN_SECONDS, base_tuning_job_name=f"custom-automl-{estimator_family}", early_stopping_type=EARLY_STOPPING_TYPE, # early stopping of training jobs is not currently supported when multiple training job definitions are used # random_seed=RANDOM_SEED, )

עכשיו בואו נעבור דרך ה tuners ו hp_args מילונים ומפעילים את כל משרות HPO ב- SageMaker. שימו לב לשימוש בארגומנט המתנה שהוגדר ל False, מה שאומר שהקרנל לא ימתין עד להשלמת התוצאות ותוכל להפעיל את כל המשימות בבת אחת.

סביר להניח שלא כל עבודות ההדרכה יסתיימו וחלקן עשויות להיעצר על ידי עבודת HPO. הסיבה לכך היא ה TuningJobCompletionCriteriaConfig-האופטימיזציה מסתיימת אם מתקיים אחד מהקריטריונים שצוינו. במקרה זה, כאשר קריטריוני האופטימיזציה אינם משתפרים עבור 20 משרות רצופות.

for tuner, hpo in zip(tuners.values(), hp_args.values()): tuner.fit( inputs=hpo.get_inputs_dict(), include_cls_metadata=hpo.get_include_cls_metadata_dict(), wait=False, )

ניתוח תוצאות

תא 15 של המחברת בודק אם כל עבודות HPO הושלמו ומשלב את כל התוצאות בצורה של מסגרת נתונים של פנדה לניתוח נוסף. לפני שננתח את התוצאות בפירוט, בואו נסתכל ברמה גבוהה על קונסולת SageMaker.

בחלק העליון של עבודות כוונון היפרפרמטרים בדף, תוכל לראות את שלוש משרות ה-HPO שהושקו. כולם סיימו מוקדם ולא ביצעו את כל 100 עבודות ההדרכה. בצילום המסך הבא, אתה יכול לראות שמשפחת דגמי Elastic-Net השלימה את המספר הגבוה ביותר של ניסויים, בעוד שאחרים לא היו צריכים כל כך הרבה עבודות אימון כדי למצוא את התוצאה הטובה ביותר.

מסוף משימות כוונון היפרפרמטר של SageMaker מציג את כל שלושת משרות ה-HPO שהופעלו

אתה יכול לפתוח את משימת ה-HPO כדי לגשת לפרטים נוספים, כגון עבודות הכשרה בודדות, תצורת עבודה והמידע והביצועים הטובים ביותר של עבודת ההדרכה.

תצוגה מפורטת של אחת ממשרות HPO שנבחרו

בואו נפיק הדמיה המבוססת על התוצאות כדי לקבל יותר תובנות לגבי ביצועי זרימת העבודה של AutoML בכל משפחות הדגמים.

מהגרף הבא, אתה יכול להסיק כי Elastic-Net הביצועים של המודל נעו בין 70,000 ל-80,000 RMSE ולבסוף נתקעו, מכיוון שהאלגוריתם לא הצליח לשפר את הביצועים שלו למרות שניסיתם טכניקות עיבוד מקדים וערכי היפרפרמטרים שונים. גם כך נראה RandomForest הביצועים השתנו מאוד בהתאם לקבוצת ההיפרפרמטרים שנחקרה על ידי HPO, אך למרות ניסויים רבים הוא לא יכול היה לרדת מתחת לשגיאת 50,000 RMSE. GradientBoosting השיג את הביצועים הטובים ביותר כבר מההתחלה וירד מתחת ל-50,000 RMSE. HPO ניסה לשפר את התוצאה הזו עוד יותר אך לא הצליח להשיג ביצועים טובים יותר בשילובי היפרפרמטרים אחרים. מסקנה כללית לכל משרות ה-HPO היא שלא נדרשו כל כך הרבה עבודות כדי למצוא את קבוצת ההיפרפרמטרים בעלת הביצועים הטובים ביותר עבור כל אלגוריתם. כדי לשפר עוד יותר את התוצאה, תצטרך להתנסות ביצירת תכונות נוספות וביצוע הנדסת תכונות נוספת.

שינויים בערך האובייקטיבי של HPO לאורך זמן על ידי כל משפחת מודלים

אתה יכול גם לבחון תצוגה מפורטת יותר של שילוב הדגם-קדם-מעבד כדי להסיק מסקנות לגבי השילובים המבטיחים ביותר.

שינויים בערך האובייקטיבי של HPO לאורך זמן על ידי כל שילוב דגם-קדם-מעבד

בחר את הדגם הטוב ביותר ופרוס אותו

קטע הקוד הבא בוחר את המודל הטוב ביותר על סמך ערך המטרה הנמוך ביותר שהושג. לאחר מכן תוכל לפרוס את המודל כנקודת קצה של SageMaker.

df_best_job = df_tuner_results.loc[df_tuner_results["FinalObjectiveValue"] == df_tuner_results["FinalObjectiveValue"].min()]
df_best_job
BEST_MODEL_FAMILY = df_best_job["TrainingJobFamily"].values[0] tuners.get(BEST_MODEL_FAMILY).best_training_job() tuners.get(BEST_MODEL_FAMILY).best_estimator() predictor = tuners.get(BEST_MODEL_FAMILY).deploy( initial_instance_count=1, instance_type="ml.c4.large", endpoint_name=f"custom-automl-endpoint-{BEST_MODEL_FAMILY}",
)

לנקות את

כדי למנוע חיובים לא רצויים לחשבון AWS שלך, אנו ממליצים למחוק את משאבי AWS שבהם השתמשת בפוסט זה:

  1. בקונסולת Amazon S3, רוקן את הנתונים מדלי ה-S3 שבו אוחסנו נתוני האימון.

קונסולת Amazon S3 מראה כיצד לרוקן או להסיר דלי לחלוטין

  1. במסוף SageMaker, עצור את מופע המחברת.

מסוף מופעים של SageMaker Notebook המראה כיצד לעצור מופע

  1. מחק את נקודת הקצה של הדגם אם פרסת אותה. יש למחוק נקודות קצה כאשר אינן בשימוש עוד, מכיוון שהן מחויבות לפי זמן הפריסה.
sm_client.delete_endpoint(EndpointName=predictor.endpoint)

סיכום

בפוסט זה, הצגנו כיצד ליצור עבודת HPO מותאמת אישית ב- SageMaker באמצעות מבחר מותאם אישית של אלגוריתמים וטכניקות עיבוד מקדים. בפרט, דוגמה זו מדגימה כיצד להפוך את התהליך של יצירת סקריפטים אימון רבים וכיצד להשתמש במבני תכנות של Python לפריסה יעילה של מספר עבודות אופטימיזציה מקבילות. אנו מקווים שהפתרון הזה יהווה את הפיגום של כל עבודת כוונון מודלים מותאמים אישית שתפרוס באמצעות SageMaker כדי להשיג ביצועים גבוהים יותר ולהאיץ את זרימות העבודה שלך ב-ML.

עיין במשאבים הבאים כדי להעמיק עוד יותר את הידע שלך כיצד להשתמש ב- SageMaker HPO:


על הכותבים

קונרד סמשקונרד סמש הוא ארכיטקט בכיר ML Solutions בצוות מעבדת הנתונים של Amazon Web Services. הוא עוזר ללקוחות להשתמש בלמידת מכונה כדי לפתור את האתגרים העסקיים שלהם עם AWS. הוא נהנה להמציא ולפשט כדי לאפשר ללקוחות פתרונות פשוטים ופרגמטיים לפרויקטים של AI/ML שלהם. הוא נלהב ביותר מ-MlOps וממדעי הנתונים המסורתיים. מחוץ לעבודה, הוא מעריץ גדול של גלישת רוח וגלישת עפיפונים.

טונה ארסויטונה ארסוי הוא אדריכל פתרונות בכיר ב-AWS. המיקוד העיקרי שלה הוא לעזור ללקוחות במגזר הציבורי לאמץ טכנולוגיות ענן לעומסי העבודה שלהם. יש לה רקע בפיתוח אפליקציות, ארכיטקטורה ארגונית וטכנולוגיות מרכז קשר. תחומי העניין שלה כוללים ארכיטקטורות ללא שרת ו-AI/ML.

ספוט_ימג

המודיעין האחרון

ספוט_ימג