ג.23 — מעקב והשוואת ניסויים עם W&B

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

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

Weights & Biases — W&B הוא שירות לתיעוד ניסויים בלמידת מכונה, ואחד הכלים הנפוצים למעקב ניסויים. הקוד שולח אליו את הגדרות הניסוי ואת המדדים שבחרנו לתעד. באתר אפשר לעקוב אחרי הגרפים בזמן האימון ולחזור אליהם לאחר שהסתיים. חבילת Python שמחברת את הקוד לשירות נקראת wandb. בפרק זה נפתח חשבון, נחבר אליו את סביבת העבודה, ונוסיף לתוכנית אימון שלוש קריאות בלבד — פתיחת ריצה, דיווח מדדים וסיום — כדי להשוות בין שני קצבי למידה. אותן שלוש קריאות אפשר להוסיף לכל לולאת אימון שכתבנו בספר, וגם לאימון הסוכנים שנבנה בחלק ד, שבו הריצות ארוכות והמדדים תנודתיים במיוחד.

חומרי ליווי: מצגת הקורס (עותק מקומי) · תיעוד W&B · קוד הדוגמה המלא

ג.23.1 — פרויקט וריצות ניסוי

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

סביבת העבודה של W&B: רשימת ריצות משמאל וגרפי loss ודיוק מימין
סביבת עבודה לדוגמה: כל צבע מייצג ריצה. צילום מתוך התיעוד הרשמי, המציג נתוני הדגמה. לחיצה פותחת את התמונה בגודל מלא.

ג.23.2 — פתיחת חשבון וכניסה לאתר

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

  1. פותחים את אתר W&B ובוחרים Sign up. אם כבר יש חשבון, בוחרים Log in.
  2. נרשמים באמצעות אחת מאפשרויות ההזדהות המוצגות, למשל Google או GitHub, או באמצעות דוא״ל וסיסמה. משלימים את אימות החשבון אם מתבקשים.
  3. משלימים את פרטי המשתמש והסביבה שהאתר מבקש. במהלך העבודה נשתמש באותו חשבון גם לצפייה בניסויים וגם לקישור המחשב.
מסך הכניסה של W&B, הכולל לשוניות Log in ו-Sign up ואפשרויות הזדהות
מסך הכניסה והרישום באתר, כפי שנצפה בספטמבר 2026. למשתמש חדש בוחרים בלשונית Sign up.

ג.23.3 — התקנה מקומית ויבוא החבילה

לשירות שני צדדים: האתר מציג את הניסויים בדפדפן, ובמחשב מתקינים את חבילת Python שמדווחת אליו — היא זו שתוכנית האימון שלנו קוראת לה. לשימוש בשירות הענן אין צורך להתקין שרת W&B או תוכנת שולחן עבודה נפרדת.

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

python -m pip install wandb

זו התקנת pip install wandb באמצעות מפרש ה־Python הפעיל. אם עובדים בסביבה וירטואלית, מפעילים אותה לפני ההתקנה. יש לבחור בעורך את אותו מפרש Python; חבילה שהותקנה בסביבה אחרת לא בהכרח תהיה זמינה לתוכנית.

בקובץ ה־Python מייבאים את החבילה:

import wandb

pip install מתקין את החבילה בסביבה; import מאפשר לתוכנית להשתמש בה. אפשר לבדוק את היבוא בטרמינל:

python -c "import wandb; print(wandb.__version__)"

הפקודה אמורה להדפיס את מספר הגרסה שהותקנה. ב־Colab מתקינים בסביבת המחברת באמצעות %pip install wandb, ואז מריצים import wandb בתא Python. התקנה במחשב אינה מתקינה את החבילה ב־Colab.

התקנת החבילה והיבוא מתוארים ב־מדריך ההתחלה הרשמי.

ג.23.4 — קישור המחשב לחשבון: הזדהות מקומית

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

  1. באתר, פותחים את תפריט המשתמש ובוחרים User Settings.
  2. בוחרים Create new API key, נותנים למפתח שם כגון school-laptop, ולוחצים Create.
  3. מעתיקים את המפתח המלא שמוצג. לפי הממשק הנוכחי הוא מוצג במלואו רק בזמן יצירתו.
  4. בטרמינל של סביבת האימון מריצים:
wandb login

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

אפשר לבצע את ההזדהות גם מתוך Python:

import wandb

wandb.login()

אלו שתי דרכים לבצע את אותו שלב: wandb login היא פקודת טרמינל, ו־wandb.login() היא קריאת Python. אין להקליד את קריאת ה־Python ישירות ב־PowerShell. אם פקודת הטרמינל אינה מזוהה, אפשר להשתמש בגרסת ה־Python לאחר שווידאנו שהיבוא מצליח.

ג.23.5 — אתחול הניסוי ושמירת ההגדרות

משהסביבה מחוברת, נעבור לקוד. שילוב W&B בתוכנית אימון מורכב משלושה שלבים: פתיחת ריצה לפני האימון, דיווח מדדים בתוך הלולאה, וסגירת הריצה בסופה. נתחיל בראשון. לפני לולאת האימון פותחים ריצה באמצעות wandb.init. כאן קובעים לאיזה פרויקט הריצה שייכת, נותנים לה שם, ומתעדים את המידע שיאפשר להבין אותה מאוחר יותר: סוג המודל, הנתונים, קצב הלמידה ומספר האפוקים. זהו בדיוק המידע שבפרקים הקודמים היה "מוסתר" בתוך הקוד ונשכח אחרי כל שינוי.

config = {
    "model": "single_weight",
    "learning_rate": 0.05,
    "epochs": 40,
    "initial_weight": 0.0,
    "target_weight": 3.0,
}

run = wandb.init(
    project="learning-rate-comparison",
    name="lr-0.05",
    config=config,
)
פרמטר מה נשמר בו?
project שם הפרויקט המשותף לריצות שנרצה להשוות
name שם קריא לריצה המסוימת
config מילון ההגדרות והמידע על המודל והניסוי

החזרה מ־init היא אובייקט הריצה, run, שבו נשתמש לדיווח. אם צריך לבחור צוות מסוים, מוסיפים entity עם שם המשתמש או הצוות הקיים שבו מורשים לעבוד. פרטי האתחול.

שמירת learning_rate ב־config אינה משנה בעצמה את האופטימייזר. הקוד צריך להשתמש באותו ערך גם באימון. בדוגמה ניגש אל config["learning_rate"] בחישוב העדכון. שמירת תיאור המודל במילון גם אינה שמירה של המשקלים שאומנו; לשמירה וטעינה של המשקלים ראו פרק ג.20. הגדרות ניסוי.

ג.23.6 — דיווח מדדים במהלך האימון

השלב השני הוא לב המעקב. את הגדרות הניסוי שומרים בתחילת הריצה, כי הן קבועות. את הערכים שמשתנים — למשל שגיאה ודיוק — מדווחים במהלך הלולאה, באמצעות run.log. הקריאה מקבלת מילון של שמות מדדים וערכיהם, ושולחת אותו לשירות; כל קריאה כזו מוסיפה נקודה אחת לגרף של כל מדד, במקום שורת ההדפסה שהשתמשנו בה עד כה:

run.log(
    {"train_loss": loss_value, "epoch": epoch},
    step=epoch,
)

זהו קטע לשילוב בלולאה קיימת: loss_value הוא ערך השגיאה שחושב, ו־epoch הוא מספר האפוק. בקריאה אחת אפשר לשלוח כמה מדדים מאותה נקודת זמן. למשל, בסוף אפוק בסיווג תמונות נשלח יחד train_loss, ‏val_loss ו־val_accuracy, לאחר שחושבו.

ב־PyTorch ממירים שגיאה שהיא טנסור סקלרי למספר באמצעות loss.item(). אם רוצים לדווח שגיאה ממוצעת של אפוק, מחשבים תחילה את הממוצע מכל האצוות; שגיאת האצווה האחרונה אינה הממוצע הזה.

הפרמטר step קובע את מיקום הנקודה על ציר X של הגרף. ללא step מפורש, מספר צעד הדיווח מתקדם אוטומטית עם הקריאות. הוא אינו בהכרח מספר האפוק: אם מדווחים בכל אצווה, הצעד יספור אצוות. בדוגמה שלנו נשלח פעם אחת בסוף כל אפוק עם step=epoch, בסדר עולה. השלב השלישי והאחרון: בסיום קוראים run.finish() כדי לסיים את הריצה ולהשלים את הדיווח — הנתונים נשלחים ברקע, והקריאה מוודאת שכולם הגיעו ליעדם לפני שהתוכנית מסתיימת. דיווח מדדים וציר הצעדים · סיום ריצה.

ג.23.7 — דוגמה מלאה: השוואת שני קצבי למידה

נשתמש במשימה הקטנה של Gradient Descent במשתנה אחד: מזעור השגיאה L(w) = (w − 3)². כאן נתמקד בתיעוד. שתי הריצות מתחילות מאותו משקל, ומשנות רק את קצב הלמידה. אין צורך בנתונים חיצוניים או ב־PyTorch כדי להריץ את הדוגמה.

import wandb


def train(learning_rate):
    config = {
        "model": "single_weight",
        "learning_rate": learning_rate,
        "epochs": 40,
        "initial_weight": 0.0,
        "target_weight": 3.0,
    }
    run = wandb.init(
        project="learning-rate-comparison",
        name=f"lr-{learning_rate}",
        config=config,
    )

    weight = config["initial_weight"]
    target = config["target_weight"]
    for epoch in range(1, config["epochs"] + 1):
        gradient = 2 * (weight - target)
        weight -= config["learning_rate"] * gradient
        loss_value = (weight - target) ** 2
        run.log(
            {
                "epoch": epoch,
                "train_loss": loss_value,
                "weight": weight,
            },
            step=epoch,
        )

    run.finish()


if __name__ == "__main__":
    wandb.login()
    for learning_rate in (0.05, 0.2):
        train(learning_rate)

שומרים את קובץ הדוגמה ומריצים אותו בסביבה שהותקנה וקושרה לחשבון:

python wandb_example.py

נוצרות שתי ריצות באותו פרויקט. בכל אפוק מדווחים את המשקל ואת השגיאה אחרי העדכון. השמות train_loss ו־weight יופיעו באתר כשמות מדדים. הנתונים כאן מחושבים באימון הפשוט שבקוד; צילומי האתר בפרק הם דוגמאות ממשק ואינם תוצאות של ריצה זו.

ג.23.8 — צפייה בתוצאות והשוואת ריצות

נשווה את הגרפים של שתי הריצות כדי לראות כיצד קצב הלמידה השפיע על ההתקדמות. פותחים את הקישור לפרויקט שמופיע במסוף, או נכנסים לאתר ובוחרים את הפרויקט learning-rate-comparison. בסביבת העבודה Workspace מאתרים את שתי הריצות ברשימת Runs ומפעילים את הצגת שתיהן. לכל ריצה צבע משלה.

פותחים גרף של train_loss. אם הוא אינו מוצג, בוחרים Add panel, אחר כך Line plot, ומגדירים בציר Y את train_loss. בציר X בוחרים Step או epoch; בדוגמה הם מייצגים אותם אפוקים, משום שדיווחנו כך במפורש. פותחים גם גרף של weight ורואים כיצד הוא מתקרב ל־3. אפשרויות הגרף.

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

ג.23.9 — החלקת הגרף: Smoothing

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

  1. פותחים את הגדרות הגרף באמצעות סמל גלגל השיניים.
  2. בלשונית Data מאתרים את Smoothing.
  3. בוחרים, למשל, Time-weighted EMA, ומעלים בהדרגה את עוצמת ההחלקה. בשיטה זו 0 פירושו ללא החלקה; ככל שהערך קרוב יותר ל־1 ההחלקה חזקה יותר.
  4. משאירים את Show Original פעיל כדי לראות גם את הנתונים הגולמיים בקו בהיר. שמות הכפתורים ומיקומם עשויים להשתנות עם עדכון האתר. הגדרות ההחלקה.
גרף W&B עם נתונים גולמיים בקו בהיר ומגמה מוחלקת בקו כחול כהה
צילום מתוך תיעוד W&B: הקו הבהיר מציג את התנודות המקוריות, והקו הכהה את ההחלקה.

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