מודלים שמורים לשימוש חוזר

מבוא

TensorFlow Hub מארח את SavedModels עבור TensorFlow 2, בין היתר. ניתן לטעון אותם בחזרה לתוכנית Python עם obj = hub.load(url) [ למידע נוסף ]. ה- obj המוחזר הוא תוצאה של tf.saved_model.load() (ראה מדריך SavedModel של TensorFlow). לאובייקט זה יכולות להיות תכונות שרירותיות שהן tf.functions, tf.Variables (אתחול מהערכים המאומנים מראש שלהם), משאבים אחרים ובאופן רקורסיבי, עוד אובייקטים כאלה.

דף זה מתאר ממשק שיש ליישם על ידי obj הנטען על מנת לעשות בו שימוש חוזר בתוכנית TensorFlow Python. SavedModels התואמים ממשק זה נקראים Reusable SavedModels .

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

צוות TensorFlow Hub ממליץ ליישם את ממשק SavedModel הניתן לשימוש חוזר בכל SavedModels שנועדו לשימוש חוזר במובן שלעיל. כלי עזר רבים מספריית tensorflow_hub , בעיקר hub.KerasLayer , דורשים את SavedModels כדי ליישם זאת.

קשר עם SignatureDefs

ממשק זה במונחים של tf.functions ותכונות TF2 אחרות נפרד מהחתימות של SavedModel, שהיו זמינות מאז TF1 וממשיכות לשמש ב-TF2 להסקת מסקנות (כגון פריסת SavedModels ל-TF Serving או TF Lite). חתימות להסקת מסקנות אינן אקספרסיביות מספיק כדי לתמוך בכוונון עדין, ו- tf.function מספקת Python API טבעי ואקספרסיבי יותר עבור המודל בשימוש חוזר.

קשר לספריות בניית מודלים

SavedModel שניתן לשימוש חוזר משתמש רק בפרימיטיבים של TensorFlow 2, ללא תלות בספריית בניית מודלים מסוימת כמו Keras או Sonnet. זה מקל על שימוש חוזר בספריות לבניית מודלים, ללא תלות בקוד בניית המודל המקורי.

תידרש כמות מסוימת של התאמה, טען מודלים שמורים לשימוש חוזר או שמור אותם מכל ספריית בניית דגמים נתונה. עבור Keras, hub.KerasLayer מספקת את הטעינה, והשמירה המובנית של Keras בפורמט SavedModel עוצבה מחדש עבור TF2 במטרה לספק ערכת-על של ממשק זה (ראה RFC ממאי 2019).

קשר ל-"Common SavedModel APIs" ספציפיים למשימה

הגדרת הממשק בעמוד זה מאפשרת כל מספר וסוג של כניסות ויציאות. ממשקי ה-API הנפוצים של SavedModel עבור TF Hub משכללים את הממשק הכללי הזה עם מוסכמות שימוש עבור משימות ספציפיות כדי להפוך מודלים להחלפה בקלות.

הגדרת ממשק

תכונות

SavedModel לשימוש חוזר הוא TensorFlow 2 SavedModel כך ש- obj = tf.saved_model.load(...) מחזיר אובייקט בעל התכונות הבאות

  • __call__ . נדרש. tf.function המיישמת את חישוב המודל ("המעבר קדימה") בכפוף למפרט שלהלן.

  • variables : רשימה של אובייקטי tf.Variable, המפרטת את כל המשתנים המשמשים כל הפעלת __call__ , כולל ניתנים לאימון ולא ניתנים לאימון.

    ניתן להשמיט רשימה זו אם היא ריקה.

  • trainable_variables : רשימה של אובייקטי tf.Variable כך ש- v.trainable נכון עבור כל האלמנטים. משתנים אלה חייבים להיות תת-קבוצה של variables . אלו הם המשתנים שיש לאמן בעת ​​כוונון עדין של האובייקט. היוצר של SavedModel עשוי לבחור להשמיט כאן כמה משתנים שהיו ניתנים לאימון במקור כדי לציין שאין לשנות אותם במהלך כוונון עדין.

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

  • regularization_losses : רשימה של tf.functions, שכל אחת מהן לוקחת אפס קלט ומחזירה טנזור צף סקלרי בודד. לצורך כוונון עדין, מומלץ למשתמש SavedModel לכלול אותם כמונחי רגולציה נוספים בהפסד (במקרה הפשוט ביותר ללא שינוי קנה מידה נוסף). בדרך כלל, אלה משמשים לייצוג מסדרי משקל. (בגלל היעדר תשומות, פונקציות tf. אלה אינן יכולות לבטא מסדירי פעילות.)

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

הפונקציה __call__

ל-Restored SavedModel obj יש תכונה obj.__call__ שהיא tf.function משוחזרת ומאפשרת לקרוא ל- obj באופן הבא.

תקציר (פסאודו-קוד):

outputs = obj(inputs, trainable=..., **kwargs)

טיעונים

הטיעונים הם כדלקמן.

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

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

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

  • ייתכן שיש training אופציונלי של ארגומנט מילות מפתח שמקבל ערך בוליאני של Python, True או False . ברירת המחדל היא False . אם המודל תומך בכוונון עדין, ואם החישוב שלו שונה בין השניים (למשל, כמו נשירה ונורמליזציה של אצווה), ההבחנה הזו מיושמת עם הטיעון הזה. אחרת, טיעון זה עשוי להיעדר.

    אין צורך ש__ __call__ יקבל טיעון training בעל ערך טנסור. זה נופל על המתקשר להשתמש tf.cond() במידת הצורך כדי לשלוח ביניהם.

  • היוצר של SavedModel עשוי לבחור לקבל יותר kwargs אופציונליים של שמות מסוימים.

    • עבור ארגומנטים בעלי ערך Tensor, יוצר SavedModel מגדיר את ה-dtypes והצורות המותרים שלהם. tf.function מקבל ערך ברירת מחדל של Python על ארגומנט שמתחקה באמצעות קלט tf.TensorSpec. ניתן להשתמש בארגומנטים כאלה כדי לאפשר התאמה אישית של היפרפרמטרים מספריים המעורבים ב __call__ (למשל, שיעור נשירה).

    • עבור ארגומנטים בעלי ערך Python, יוצר SavedModel מגדיר את הערכים המותרים שלהם. ארגומנטים כאלה יכולים לשמש כדגלים כדי לבצע בחירות בדידות בפונקציית המעקב (אבל שימו לב לפיצוץ העקבות הקומבינטורי).

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

תוֹצָאָה

outputs מקריאת obj יכולים להיות

  • טנסור בודד עבור פלט בודד,
  • רשימה של Tensors עבור רצף מסודר של פלטים ללא שם,
  • הכתבה של Tensors הממוקמת על ידי קבוצה מסוימת של שמות פלט.

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

בעלי שם

מודל שמור לשימוש חוזר יכול לספק חלקי דגמים מרובים בדרך שתוארה לעיל על ידי הכנסתם לתתי-אובייקטים בעלי שם, למשל, obj.foo , obj.bar וכן הלאה. כל אובייקט משנה מספק שיטת __call__ ותכונות תומכות לגבי המשתנים וכו' הספציפיים לאותו דגם. עבור הדוגמה שלמעלה, יהיו obj.foo.__call__ , obj.foo.variables וכן הלאה.

שימו לב שממשק זה אינו מכסה את הגישה של הוספת פונקציית tf. חשופה ישירות כ- tf.foo .

משתמשים של SavedModels הניתנים לשימוש חוזר צפויים להתמודד רק עם רמה אחת של קינון ( obj.bar אך לא obj.bar.baz ). (תיקונים עתידיים של ממשק זה עשויים לאפשר קינון עמוק יותר, ועשויים לוותר על הדרישה שהאובייקט ברמה העליונה יהיה ניתן להתקשרות בעצמו.)

הערות סיכום

קשר לממשקי API בתהליך

מסמך זה מתאר ממשק של מחלקת Python המורכבת מפרימיטיבים כמו tf.function ו-tf.Variable ששורדים סיבוב הלוך ושוב באמצעות סדרה באמצעות tf.saved_model.save() ו- tf.saved_model.load() . עם זאת, הממשק כבר היה קיים באובייקט המקורי שהועבר ל- tf.saved_model.save() . התאמה לממשק זה מאפשרת החלפה של חלקי מודל על פני ממשקי API לבניית מודלים בתוך תוכנית TensorFlow אחת.