הצג באתר TensorFlow.org | הפעל בגוגל קולאב | צפה במקור ב-GitHub | הורד מחברת |
import tensorflow as tf
TensorFlow 2.x כוללת שינויים משמעותיים tf.summary
API המשמש נתוני סיכום כתיבה עבור להדמיה ב TensorBoard.
מה השתנה
זה שימושי לחשוב על tf.summary
API כשתי-APIs משנה:
- קבוצה של חיילים מיחידות לסיכומים הפרט הקלטה -
summary.scalar()
,summary.histogram()
,summary.image()
,summary.audio()
, ולאחרsummary.text()
- אשר נקראים מוטבעות מקוד המודל שלך. - היגיון כתיבה שאוסף את הסיכומים האישיים הללו וכותב אותם לקובץ יומן בפורמט מיוחד (שאותו TensorBoard קורא לאחר מכן כדי ליצור הדמיות).
ב-TF 1.x
שני החצאים היו צריכים להיות חוטית באופן ידני יחד - על ידי שליפת פלטי אופ סיכום באמצעות Session.run()
וקראו FileWriter.add_summary(output, step)
. v1.summary.merge_all()
op הקל זאת באמצעות אוסף גרף כדי לצבור את כול תפוקות אופ הסיכום, אך גישה זו עדיין עבדה היטב לביצוע להוט ובקרת זרימה, מה שהופך אותו במיוחד חולה מתאים עבור 2.X. TF
ב-TF 2.X
שני החצאים משולבים באופן הדוק, ועכשיו הפרט tf.summary
ops לכתוב את הנתונים שלהם באופן מיידי כאשר להורג. השימוש ב-API מקוד הדגם שלך עדיין אמור להיראות מוכר, אך כעת הוא ידידותי לביצוע נלהב בעודו תואם למצב גרף. שילוב שני החצאים של אמצעי API את summary.FileWriter
הוא עכשיו חלק מהקשר ביצוע TensorFlow ומקבל לגשת ישירות tf.summary
ops, כך תצורת סופרים הוא החלק העיקרי שנראה שונה.
שימוש לדוגמה עם ביצוע להוט, ברירת המחדל ב-TF 2.x:
writer = tf.summary.create_file_writer("/tmp/mylogs/eager")
with writer.as_default():
for step in range(100):
# other model code would go here
tf.summary.scalar("my_metric", 0.5, step=step)
writer.flush()
ls /tmp/mylogs/eager
events.out.tfevents.1633086727.kokoro-gcp-ubuntu-prod-1386032077.31590.0.v2
דוגמה לשימוש עם ביצוע גרף tf.function:
writer = tf.summary.create_file_writer("/tmp/mylogs/tf_function")
@tf.function
def my_func(step):
with writer.as_default():
# other model code would go here
tf.summary.scalar("my_metric", 0.5, step=step)
for step in tf.range(100, dtype=tf.int64):
my_func(step)
writer.flush()
ls /tmp/mylogs/tf_function
events.out.tfevents.1633086728.kokoro-gcp-ubuntu-prod-1386032077.31590.1.v2
דוגמה לשימוש עם ביצוע גרף TF 1.x מדור קודם:
g = tf.compat.v1.Graph()
with g.as_default():
step = tf.Variable(0, dtype=tf.int64)
step_update = step.assign_add(1)
writer = tf.summary.create_file_writer("/tmp/mylogs/session")
with writer.as_default():
tf.summary.scalar("my_metric", 0.5, step=step)
all_summary_ops = tf.compat.v1.summary.all_v2_summary_ops()
writer_flush = writer.flush()
with tf.compat.v1.Session(graph=g) as sess:
sess.run([writer.init(), step.initializer])
for i in range(100):
sess.run(all_summary_ops)
sess.run(step_update)
sess.run(writer_flush)
ls /tmp/mylogs/session
events.out.tfevents.1633086728.kokoro-gcp-ubuntu-prod-1386032077.31590.2.v2
המרת הקוד שלך
המרת הקיים tf.summary
השימוש ל- API 2.x TF לא יכול להיות אוטומטי באופן מהימן, ולכן tf_upgrade_v2
סקריפט פשוט משכתב את הכל כדי tf.compat.v1.summary
. כדי לעבור ל-TF 2.x, תצטרך להתאים את הקוד שלך באופן הבא:
סט סופר ברירת המחדל באמצעות
.as_default()
חייב להיות נוכח כדי ops סיכום השימוש- משמעות הדבר היא ביצוע פעולות בשקיקה או שימוש באופציות בבניית גרפים
- ללא כותב ברירת מחדל, פעולות סיכום הופכות ל-Silent No-Ops
- סופרי ברירה לא (עדיין) הפיצו ברחבי
@tf.function
גבול ביצוע - הם מזוהים רק כאשר הפונקציה לייחס - כך התרגול הטוב ביותר הוא לקרואwriter.as_default()
בגוף הפונקציה, ועל מנת להבטיח כי האובייקט סופר ממשיכה להתקיים כל עוד@tf.function
נמצא בשימוש
הערך "צעד" יש להעביר אל כל op באמצעות
step
טיעון- TensorBoard דורש ערך צעד כדי להציג את הנתונים כסדרת זמן
- יש צורך במעבר מפורש מכיוון שהצעד הגלובלי מ-TF 1.x הוסר, כך שכל פעולה חייבת לדעת את משתנה הצעד הרצוי לקריאה
- כדי להפחית מוכן מראש, תמיכה ניסיונית רישום ערך צעד ברירת מחדל היא זמינה
tf.summary.experimental.set_step()
, אבל זה פונקציונאלי זמני שעשוי להשתנות ללא הודעה
חתימות הפונקציות של פעולות סיכום בודדות השתנו
- ערך ההחזרה הוא כעת בוליאני (מציין אם סיכום נכתב בפועל)
- שם הפרמטר השני (אם משתמשים בו) השתנה מן
tensor
עדdata
-
collections
הפרמטר הוסר; האוספים הם TF 1.x בלבד -
family
פרמטר הוסר; השימוש פשוטtf.name_scope()
[רק עבור משתמשי מצב גרף / ביצוע הפעלה מדור קודם]
ראשית לאתחל את הסופר עם
v1.Session.run(writer.init())
השתמש
v1.summary.all_v2_summary_ops()
כדי לקבל את כל ops סיכום 2.x TF עבור הגרף הנוכחי, למשל לבצע אותם באמצעותSession.run()
שטוף את הסופר עם
v1.Session.run(writer.flush())
וכך גם לגביclose()
אם הקוד 1.x TF שלך היה במקום באמצעות tf.contrib.summary
API, זה הרבה יותר דומה ל- API 2.x TF, כך tf_upgrade_v2
התסריט יהיה להפוך את רוב השלבים הגירה (ואזהרות לפלוט או שגיאות עבור כל שימוש שלא יכול להיות מועבר במלואו). על פי רוב זה רק משכתב את שיחות ה- API כדי tf.compat.v2.summary
; אם אתה רק צריך תאימות עם 2.x TF תוכל לשחרר את compat.v2
ופשוט להתייחס אליה כמו tf.summary
.
טיפים נוספים
בנוסף לאזורים הקריטיים לעיל, השתנו גם כמה היבטי עזר:
להקלטה מותנית (כמו "תיעוד כל 100 צעדים") יש מראה חדש
- כדי ops המלאה קודים נלווים, לעטוף אותם בהצהרה אם קבוע (אשר עובדת במצב להוט וב
@tf.function
באמצעות חתימה ) אוtf.cond
- כדי לשלוט סיכומים רק, במבנה החדש של
tf.summary.record_if()
מנהל בהקשר, ולהעביר לו את מצבו בוליאני על פי בחירתך אלה מחליפים את תבנית TF 1.x:
if condition: writer.add_summary()
- כדי ops המלאה קודים נלווים, לעטוף אותם בהצהרה אם קבוע (אשר עובדת במצב להוט וב
אין כתיבה ישירה של
tf.compat.v1.Graph
- במקום פונקציות עקבות השימוש- ביצוע גרף בשימושי 2.x TF
@tf.function
במקום הגרף המפורש - בשנת 2.x TF, להשתמש בממשקי API העקיבה חדש בסגנון
tf.summary.trace_on()
וtf.summary.trace_export()
כדי להקליט גרפים פונקציה להורג
- ביצוע גרף בשימושי 2.x TF
אין במטמון סופר הגלובלי יותר לכול logdir עם
tf.summary.FileWriterCache
- משתמשים צריכים גם ליישם במטמון משלהם / שיתוף חפצים סופר, או פשוט להשתמש סופרים נפרדים (תמיכת TensorBoard עבור שהאחרון הוא בהתקדמות )
הייצוג הבינארי של קובץ האירוע השתנה
- TensorBoard 1.x כבר תומך בפורמט החדש; הבדל זה משפיע רק על משתמשים שמנתחים באופן ידני נתוני סיכום מקובצי אירועים
- נתוני סיכום מאוחסנים כעת כבייטים טנסוריים; אתה יכול להשתמש
tf.make_ndarray(event.summary.value[0].tensor)
כדי להמיר אותו numpy