דף זה תורגם על ידי Cloud Translation API.
Switch to English

גישה לנתונים TensorBoard כמו DataFrames

סקירה כללית

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

TensorBoard 2.3 תומך מקרה השימוש הזה עם tensorboard.data.experimental.ExperimentFromDev() . זה מאפשר גישה תוכניתית של TensorBoard יומני סקלר . דף זה מדגים את השימוש הבסיסי של ה- API החדש הזה.

להכין

כדי להשתמש ב- API התכנותי, הקפד להתקין pandas לצד tensorboard .

נשתמש matplotlib ו seaborn עבור חלקות מנהג במדריך זה, אבל אתה יכול לבחור הכלי המועדף שלך כדי לנתח ולהציג DataFrame ים.

pip install tensorboard pandas
pip install matplotlib seaborn
 from packaging import version

import pandas as pd
from matplotlib import pyplot as plt
import seaborn as sns
from scipy import stats
import tensorboard as tb
 
 major_ver, minor_ver, _ = version.parse(tb.__version__).release
assert major_ver >= 2 and minor_ver >= 3, \
    "This notebook requires TensorBoard 2.3 or later."
print("TensorBoard version: ", tb.__version__)
 
TensorBoard version:  2.3.0a20200626

טוען scalars TensorBoard בתור pandas.DataFrame

פעם logdir TensorBoard הועלתה TensorBoard.dev, הוא הופך להיות מה שאנחנו מכנים כניסוי. לכל ניסוי מזהה ייחודי, אשר ניתן למצוא את כתובת האתר TensorBoard.dev של הניסוי. להדגמה שלנו להלן, נשתמש בניסוי TensorBoard.dev ב: https://tensorboard.dev/experiment/c1KCv3X3QvGwaXfgX1c4tg

 experiment_id = "c1KCv3X3QvGwaXfgX1c4tg"
experiment = tb.data.experimental.ExperimentFromDev(experiment_id)
df = experiment.get_scalars()
df
 

df הוא pandas.DataFrame המכיל את כל יומני סקלר של הניסוי.

עמודי DataFrame הם:

  • run : כל אחד מהם מקביל ריצה בספריית משנה של logdir המקורי. בניסוי זה, כל סיבוב הוא מתוך אימון מלא של רשת עצבית קונבולוציה (CNN) על בסיס הנתונים MNIST עם סוג האופטימיזציה נתון (א hyperparameter אימונים). זה DataFrame מכיל ריצות מרובות כגון, אשר מתאימות ריצות אימונים חוזרים ונשנים תחת סוגים שונים האופטימיזציה.
  • tag : זה מתאר מה value באותו האמצעי בשורה, כי הוא, מה מטר הערך מייצג בשורה. בניסוי זה, יש לנו רק שני תגים ייחודיים: epoch_accuracy ו epoch_loss עבור מדדי הדיוק ואובדן בהתאמה.
  • step : זהו מספר שמשקף את סדר סדרתי של השורה המתאימה הריצה שלה. הנה step בעצם מתייחס למספר עידן. אם ברצונך לקבל את חותמות זמן נוסף על step ערכים, אתה יכול להשתמש בטיעון מילת include_wall_time=True כאשר קוראים get_scalars() .
  • value : זהו הערך המספרי האמיתי של עניין. כפי שתואר לעיל, כל value בפרט זה DataFrame הוא או הפסד או דיוק, תלוי tag של השורה.
 print(df["run"].unique())
print(df["tag"].unique())
 
['adam,run_1/train' 'adam,run_1/validation' 'adam,run_2/train'
 'adam,run_2/validation' 'adam,run_3/train' 'adam,run_3/validation'
 'adam,run_4/train' 'adam,run_4/validation' 'adam,run_5/train'
 'adam,run_5/validation' 'rmsprop,run_1/train' 'rmsprop,run_1/validation'
 'rmsprop,run_2/train' 'rmsprop,run_2/validation' 'rmsprop,run_3/train'
 'rmsprop,run_3/validation' 'rmsprop,run_4/train'
 'rmsprop,run_4/validation' 'rmsprop,run_5/train'
 'rmsprop,run_5/validation' 'sgd,run_1/train' 'sgd,run_1/validation'
 'sgd,run_2/train' 'sgd,run_2/validation' 'sgd,run_3/train'
 'sgd,run_3/validation' 'sgd,run_4/train' 'sgd,run_4/validation'
 'sgd,run_5/train' 'sgd,run_5/validation']
['epoch_accuracy' 'epoch_loss']

קבלה (רחבה-צורה) pivoted DataFrame

בניסוי שלנו, את שני התגים ( epoch_loss ו epoch_accuracy ) נוכחים באותו סט של צעדים בכל ריצה. זה מאפשר לקבל "רחב-טופס" DataFrame ישירות get_scalars() על ידי שימוש pivot=True טיעון מילות מפתח. מנהל-טופס DataFrame יש כל התגים שלה כלול עמודות של DataFrame, וזה יותר נוח לעבוד עם ובמקרים מסוימים כולל זו הנוכחית.

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

 dfw = experiment.get_scalars(pivot=True) 
dfw
 

שים לב כי במקום טור "ערך" יחיד, DataFrame הרחב-הטופס כולל שני תגים (מדדים) כעמודים שלה במפורש: epoch_accuracy ו epoch_loss .

שמירת DataFrame כמו CSV

pandas.DataFrame יש יכולת פעולה הדדית טובה עם CSV . אתה יכול לאחסן אותו כקובץ CSV מקומי לטעון אותו שוב מאוחרת יותר. לדוגמה:

 csv_path = '/tmp/tb_experiment_1.csv'
dfw.to_csv(csv_path, index=False)
dfw_roundtrip = pd.read_csv(csv_path)
pd.testing.assert_frame_equal(dfw_roundtrip, dfw)
 

ויזואליזציה מנהג Performing וניתוח סטטיסטי

 # Filter the DataFrame to only validation data, which is what the subsequent
# analyses and visualization will be focused on.
dfw_validation = dfw[dfw.run.str.endswith("/validation")]
# Get the optimizer value for each row of the validation DataFrame.
optimizer_validation = dfw_validation.run.apply(lambda run: run.split(",")[0])

plt.figure(figsize=(16, 6))
plt.subplot(1, 2, 1)
sns.lineplot(data=dfw_validation, x="step", y="epoch_accuracy",
             hue=optimizer_validation).set_title("accuracy")
plt.subplot(1, 2, 2)
sns.lineplot(data=dfw_validation, x="step", y="epoch_loss",
             hue=optimizer_validation).set_title("loss")
 
Text(0.5, 1.0, 'loss')

png

המגרשים הנ"ל מראים את timecourses דיוק אימות ואובדן אימות. עקום כול מראה את הממוצע על פני 5 ריצות תחת סוג האופטימיזציה. הודות תכונה מובנית של seaborn.lineplot() , כל עקומה גם מציג ± 1 סטיית תקן סביב הממוצע, אשר נותנת לנו תחושה ברורה של ההשתנות עקומות אלה ואת המשמעות של הבדלים בין סוגי האופטימיזציה השלושה. ויזואליזציה של השתנות זו עדיין אינה נתמכת ב GUI של TensorBoard.

אנחנו רוצים ללמוד את ההשערה כי שונה אובדן אימות מינימום משמעותי beteen את "האדם", "rmsprop" ו אופטימיזציה "SGD". אז אנחנו לחלץ DataFrame על אובדן אימות מינימום תחת כל אחת אופטימיזציה.

אחר כך נעשינו boxplot לדמיין את הבדל הפסדי אימות מינימום.

 adam_min_val_loss = dfw_validation.loc[optimizer_validation=="adam", :].groupby(
    "run", as_index=False).agg({"epoch_loss": "min"})
rmsprop_min_val_loss = dfw_validation.loc[optimizer_validation=="rmsprop", :].groupby(
    "run", as_index=False).agg({"epoch_loss": "min"})
sgd_min_val_loss = dfw_validation.loc[optimizer_validation=="sgd", :].groupby(
    "run", as_index=False).agg({"epoch_loss": "min"})
min_val_loss = pd.concat([adam_min_val_loss, rmsprop_min_val_loss, sgd_min_val_loss])

sns.boxplot(data=min_val_loss, y="epoch_loss",
            x=min_val_loss.run.apply(lambda run: run.split(",")[0]))
 
<matplotlib.axes._subplots.AxesSubplot at 0x7f5e017c8150>

png

 # Perform pairwise comparisons between the minimum validation losses
# from the three optimizers.
_, p_adam_vs_rmsprop = stats.ttest_ind(
    adam_min_val_loss["epoch_loss"],
    rmsprop_min_val_loss["epoch_loss"]) 
_, p_adam_vs_sgd = stats.ttest_ind(
    adam_min_val_loss["epoch_loss"],
    sgd_min_val_loss["epoch_loss"]) 
_, p_rmsprop_vs_sgd = stats.ttest_ind(
    rmsprop_min_val_loss["epoch_loss"],
    sgd_min_val_loss["epoch_loss"]) 
print("adam vs. rmsprop: p = %.4f" % p_adam_vs_rmsprop)
print("adam vs. sgd: p = %.4f" % p_adam_vs_sgd)
print("rmsprop vs. sgd: p = %.4f" % p_rmsprop_vs_sgd)
 
adam vs. rmsprop: p = 0.0244
adam vs. sgd: p = 0.9749
rmsprop vs. sgd: p = 0.0135

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

לסיכום, הדרכה זו מדגימה כיצד לגשת לנתונים סקלר כמו panda.DataFrame ים מ TensorBoard.dev. זה מדגים את הסוג של ניתוחים גמישים ורב עוצמה להדמיה אתה יכול לעשות עם DataFrame הים.