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

SavedModels מ- TF Hub ב- TensorFlow 2

הפורמט SavedModel של TensorFlow 2 הוא הדרך המומלצת לשתף מודלים שהוכשרו מראש ויצירות מודל ב- TensorFlow Hub. זה מחליף את הפורמט הישן של TF1 Hub ומגיע עם קבוצה חדשה של ממשקי API.

דף זה מסביר כיצד לעשות שימוש חוזר ב- TF2 SavedModels בתוכנית TensorFlow 2 עם ה- API ברמה נמוכה hub.load() hub.KerasLayer . (בדרך כלל, hub.KerasLayer משולב עם tf.keras.layers אחרות של tf.keras.layers לבניית מודל Keras או את model_fn של TF2 Estimator.) ממשקי API אלה יכולים גם לטעון את הדגמים הישנים בפורמט TF1 Hub, במגבלות, עיין במדריך התאימות .

משתמשים ב- TensorFlow 1 יכולים לעדכן ל- TF 1.15 ואז להשתמש באותם ממשקי API. גרסאות ישנות יותר של TF1 אינן פועלות.

שימוש ב- SavedModels מ- TF Hub

שימוש ב- SavedModel בקרס

Keras הוא ה- API ברמה גבוהה של TensorFlow לבניית מודלים של למידה עמוקה על ידי חיבור אובייקטים של Keras Layer. ספריית tensorflow_hub מספקת את hub.KerasLayer המחלקה. hub.KerasLayer בכתובת ה- URL (או נתיב מערכת הקבצים) של SavedModel ואז מספק את החישוב מה- SavedModel, כולל המשקולות שהוכשרו מראש.

הנה דוגמה לשימוש בהטמעת טקסט שהוכשרה מראש:

import tensorflow as tf
import tensorflow_hub as hub

hub_url = "https://tfhub.dev/google/tf2-preview/nnlm-en-dim128/1"
embed = hub.KerasLayer(hub_url)
embeddings = embed(["A long sentence.", "single-word", "http://example.com"])
print(embeddings.shape, embeddings.dtype)

מכאן, ניתן לבנות מסווג טקסט בדרך Keras הרגילה:

model = tf.keras.Sequential([
    embed,
    tf.keras.layers.Dense(16, activation="relu"),
    tf.keras.layers.Dense(1, activation="sigmoid"),
])

העמודה סיווג הטקסט היא דוגמה מלאה כיצד להכשיר ולהעריך מסווג כזה.

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

שימוש ב- SavedModel ב- Estimator

משתמשים של TensorFlow ההערכה API לאימונים מופצים יכולים להשתמש SavedModels מרכזת TF ידי כתיבה שלהם model_fn מבחינת hub.KerasLayer בקרב אחרים tf.keras.layers .

מאחורי הקלעים: SavedModel הורדה ושמירה במטמון

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

שימוש ב- SavedModel ב- TensorFlow ברמה נמוכה

הפונקציה hub.load(handle) מורידה ומדחיסה של SavedModel (אלא אם כן handle כבר נתיב מערכת קבצים) ואז מחזירה את התוצאה של טעינתו עם הפונקציה המובנית של TensorFlow tf.saved_model.load() . לכן, hub.load() יכול להתמודד עם כל SavedModel חוקי (שלא כמו קודמו hub.Module עבור TF1).

נושא מתקדם: למה לצפות מה- SavedModel לאחר הטעינה

בהתאם לתוכן ה- SavedModel, ניתן להפעיל את התוצאה של obj = hub.load(...) בדרכים שונות (כפי שמוסבר בפירוט רב בהרבה במדריך SavedModel של TensorFlow :

  • חתימות ההגשה של ה- SavedModel (אם קיימות) מיוצגות כמילון של פונקציות קונקרטיות וניתן לקרוא tensors_out = obj.signatures["serving_default"](**tensors_in) כמו tensors_out = obj.signatures["serving_default"](**tensors_in) , עם מילוני טנסורים tensors_out = obj.signatures["serving_default"](**tensors_in) ידי קלט ופלט בהתאמה. שמות ובכפוף לצורת החתימה ולאילוצי ה- dtype.

  • @tf.function שיטות -decorated של האובייקט נשמר (אם בכלל) משוחזרים כאובייקטים tf.function שיכולים להיקרא על ידי כל הצירופים של טיעונים מותח הלא מותח שעבורם tf.function היה לייחס לפני חיסכון. בפרט, אם יש שיטת obj.__call__ עם עקבות מתאימים, ניתן לכנות את obj עצמו כמו פונקציית Python. דוגמה פשוטה יכולה להיראות כמו output_tensor = obj(input_tensor, training=False) .

זה משאיר חירות עצומה בממשקים ש- SavedModels יכולים ליישם. הממשק הרב הפעמים SavedModels עבור obj קובע מוסכם כזה קוד הלקוח, כוללים מתאמים כמו hub.KerasLayer , יודע כיצד להשתמש SavedModel.

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

המשתנים הניתנים לאימון ב- SavedModel נטענים מחדש ככאלה שניתן tf.GradientTape אותם, ו- tf.GradientTape יצפה בהם כברירת מחדל. עיין בסעיף של כוונון עדין למטה בכמה אזהרות, ושקול להימנע מכך בתור התחלה. גם אם ברצונך לכוונן עדין, ייתכן שתרצה לראות אם obj.trainable_variables ממליץ לאמן מחדש רק תת-קבוצה של המשתנים שניתן לאמן במקור.

יצירת SavedModels עבור TF Hub

סקירה כללית

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

חוסך מקרס

החל מ- TensorFlow 2, tf.keras.Model.save() ו- tf.keras.models.save_model() כברירת מחדל לפורמט SavedModel (לא HDF5). SavedModels שהתקבלו וניתן להשתמש בהם עם hub.load() , hub.KerasLayer ומתאמים דומים עבור ממשקי API אחרים ברמה גבוהה ככל שהם זמינים.

כדי לשתף מודל שלם של Keras, פשוט שמור אותו עם include_optimizer=False .

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

piece_to_share = tf.keras.Model(...)
full_model = tf.keras.Sequential([piece_to_share, ...])
full_model.fit(...)
piece_to_share.save(...)

... או גזור את היצירה לשיתוף לאחר מעשה (אם זה מתיישב עם שכבת הדגם המלא שלך):

full_model = tf.keras.Model(...)
sharing_input = full_model.get_layer(...).get_output_at(0)
sharing_output = full_model.get_layer(...).get_output_at(0)
piece_to_share = tf.keras.Model(sharing_input, sharing_output)
piece_to_share.save(..., include_optimizer=False)

מודלים TensorFlow על GitHub משתמשת בגישה לשעבר ברט (ראה NLP / ברט / bert_models.py ו NLP / ברט / export_tfhub.py , לציין את הפיצול בין core_model ו pretrain_model ) ואת הגישה השנייה עבור ResNet (ראה חזון / image_classification / tfhub_export .py ).

חיסכון מ- TensorFlow ברמה נמוכה

זה דורש היכרות טובה עם מדריך SavedModel של TensorFlow .

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

class MyMulModel(tf.train.Checkpoint):
  def __init__(self, v_init):
    super(MyMulModel, self).__init__()
    self.v = tf.Variable(v_init)
    self.variables = [self.v]
    self.trainable_variables = [self.v]
    self.regularization_losses = [
        tf.function(input_signature=[])(lambda: 0.001 * self.v**2),
    ]

  @tf.function(input_signature=[tf.TensorSpec(shape=None, dtype=tf.float32)])
  def __call__(self, inputs):
    return tf.multiply(inputs, self.v)

tf.saved_model.save(MyMulModel(2.0), "/tmp/my_mul")

layer = hub.KerasLayer("/tmp/my_mul")
print(layer([10., 20.]))  # [20., 40.]
layer.trainable = True
print(layer.trainable_weights)  # [2.]
print(layer.losses)  # 0.004

הקוד ב- tensorflow / דוגמאות / שמור_מודל / שילוב_בדיקות / מכיל דוגמאות גדולות יותר, במיוחד. export_mnist.py ו use_mnist.py זוג.

כוונון עדין

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

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

עבור צרכני SavedModel

יצירת hub.KerasLayer כמו hub.KerasLayer

layer = hub.KerasLayer(..., trainable=True)

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

המכלאה לסיווג תמונות מכילה דוגמה מקצה לקצה עם כוונון עדין אופציונלי.

ייצוא מחדש של תוצאת הכוונון

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

loaded_obj = hub.load("https://tfhub.dev/...")
hub_layer = hub.KerasLayer(loaded_obj, trainable=True, ...)

model = keras.Sequential([..., hub_layer, ...])
model.compile(...)
model.fit(...)

export_module_dir = os.path.join(os.getcwd(), "finetuned_model_export")
tf.saved_model.save(loaded_obj, export_module_dir)

ליוצרים של SavedModel

כשאתה יוצר SavedModel לשיתוף ב- TensorFlow Hub, חשוב מראש אם וכיצד על צרכניו לכוונן אותו ולספק הנחיות בתיעוד.

חיסכון ממודל של Keras אמור לגרום לכל המכניקות של כוונון עדין לעבוד (חיסכון בהפסדי __call__ משקל, הכרזה על משתנים __call__ לאימון, מעקב אחר __call__ לשני training=True training=False וכו ').

בחר ממשק מודל שמשחק היטב עם זרימת שיפוע, למשל כניסות פלט במקום הסתברויות softmax או תחזיות top-k.

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

רגליזציה של משקל בשכבות בודדות נשמרת (עם מקדמי חוזק tf.keras.optimizers.Ftrl.l1_regularization_strength=...) שלהם), אך tf.keras.optimizers.Ftrl.l1_regularization_strength=...) משקל מתוך האופטימיזציה (כמו tf.keras.optimizers.Ftrl.l1_regularization_strength=...) ) הולכת לאיבוד. יעץ לצרכני ה- SavedModel שלך בהתאם.