النماذج المحفوظة من TF Hub في TensorFlow 2

تنسيق SavedModel الخاص بـ TensorFlow 2 هو الطريقة الموصى بها لمشاركة النماذج المدربة مسبقًا وقطع النماذج على TensorFlow Hub. يحل محل تنسيق TF1 Hub الأقدم ويأتي مع مجموعة جديدة من واجهات برمجة التطبيقات.

تشرح هذه الصفحة كيفية إعادة استخدام TF2 SavedModels في برنامج TensorFlow 2 مع واجهة برمجة تطبيقات hub.load() منخفضة المستوى ومجمع hub.KerasLayer الخاص به. (عادةً ما يتم دمج hub.KerasLayer مع tf.keras.layers أخرى لبناء نموذج Keras أو model_fn لمقدر TF2.) يمكن لواجهات برمجة التطبيقات هذه أيضًا تحميل النماذج القديمة بتنسيق TF1 Hub ، ضمن الحدود ، راجع دليل التوافق .

يمكن لمستخدمي TensorFlow 1 التحديث إلى TF 1.15 ثم استخدام نفس واجهات برمجة التطبيقات. الإصدارات القديمة من TF1 لا تعمل.

باستخدام SavedModels من TF Hub

استخدام نموذج SavedModel في Keras

Keras هي واجهة برمجة تطبيقات عالية المستوى من TensorFlow لبناء نماذج التعلم العميق عن طريق تكوين كائنات Keras Layer. توفر مكتبة tensorflow_hub محور الفصل hub.KerasLayer الذي يتم تهيئته باستخدام عنوان URL (أو مسار نظام الملفات) لـ SavedModel ثم يوفر الحساب من SavedModel ، بما في ذلك الأوزان المدربة مسبقًا.

فيما يلي مثال على استخدام تضمين نص تم تدريبه مسبقًا:

import tensorflow as tf
import tensorflow_hub as hub

hub_url = "https://tfhub.dev/google/nnlm-en-dim128/2"
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"),
])

يعتبر colab تصنيف النص مثالًا كاملاً على كيفية تدريب وتقييم مثل هذا المصنف.

أوزان النموذج في hub.KerasLayer يتم تعيين KerasLayer افتراضيًا على غير قابل للتدريب. راجع قسم الضبط أدناه للتعرف على كيفية تغيير ذلك. تتم مشاركة الأوزان بين جميع التطبيقات لنفس كائن الطبقة ، كما هو معتاد في Keras.

استخدام SavedModel في مقدر

يمكن لمستخدمي TensorFlow's Estimator API للتدريب الموزع استخدام SavedModels من TF Hub عن طريق كتابة model_fn الخاص بهم من حيث hub.KerasLayer بين tf.keras.layers الآخرين.

خلف الكواليس: SavedModel download and caching

باستخدام SavedModel من TensorFlow Hub (أو خوادم HTTPS الأخرى التي تنفذ بروتوكول الاستضافة الخاص به) يتم تنزيله وفك ضغطه إلى نظام الملفات المحلي إذا لم يكن موجودًا بالفعل. يمكن تعيين متغير البيئة TFHUB_CACHE_DIR لتجاوز الموقع المؤقت الافتراضي للتخزين المؤقت للنماذج SavedModels التي تم تنزيلها وغير المضغوطة. للحصول على التفاصيل ، راجع التخزين المؤقت .

استخدام نموذج SavedModel في TensorFlow منخفض المستوى

مقابض النموذج

يمكن تحميل SavedModels من handle محدد ، حيث يكون handle مسار نظام ملفات ، وعنوان URL صالح لطراز TFhub.dev (على سبيل المثال "https: //tfhub.dev/ ... "). تعكس عناوين URL لـ Kaggle Models TFhub.dev وفقًا لشروطنا والترخيص المرتبط بأصول النموذج ، على سبيل المثال "https: //www.kaggle.com / ...". المقابض من طرازات Kaggle مكافئة لمقبض TFhub.dev المقابل لها.

تقوم الوظيفة 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) ، مع قواميس موترات محددة بواسطة المدخلات والمخرجات المعنية الأسماء وتخضع لشكل التوقيع وقيود النوع.

  • تتم استعادة الطرق @tf.function - المزخرفة للكائن المحفوظ (إن وجدت) ككائنات دالة tf يمكن استدعاؤها من قبل جميع مجموعات وسيطات Tensor وغير Tensor التي تم تتبع دالة tf لها قبل الحفظ. على وجه الخصوص ، إذا كانت هناك طريقة obj.__call__ بتتبعات مناسبة ، فيمكن استدعاء obj نفسه مثل دالة Python. مثال بسيط يمكن أن يبدو مثل output_tensor = obj(input_tensor, training=False) .

هذا يترك حرية هائلة في الواجهات التي يمكن أن تطبقها SavedModels. تُنشئ واجهة SavedModels القابلة لإعادة الاستخدام لـ obj اصطلاحات مثل كود العميل ، بما في ذلك المحولات مثل hub.KerasLayer ، تعرف كيفية استخدام SavedModel.

قد لا تتبع بعض SavedModels هذه الاتفاقية ، خاصةً النماذج الكاملة التي لا يُقصد إعادة استخدامها في الطرز الأكبر ، وتقدم فقط تواقيع الخدمة.

يتم إعادة تحميل المتغيرات القابلة للتدريب في SavedModel على أنها قابلة للتدريب ، وسيراقبها tf.GradientTape افتراضيًا. راجع قسم الضبط أدناه للحصول على بعض التحذيرات ، وفكر في تجنب ذلك للمبتدئين. حتى إذا كنت ترغب في إجراء الضبط الدقيق ، فقد ترغب في معرفة ما إذا كان obj.trainable_variables ينصح بإعادة تدريب مجموعة فرعية فقط من المتغيرات التي يمكن تدريبها في الأصل.

إنشاء SavedModels لـ TF Hub

ملخص

SavedModel هو تنسيق تسلسلي قياسي لـ TensorFlow للنماذج المدربة أو القطع النموذجية. يقوم بتخزين أوزان النموذج المدربة جنبًا إلى جنب مع عمليات TensorFlow الدقيقة لأداء حسابه. يمكن استخدامه بشكل مستقل عن الكود الذي أنشأه. على وجه الخصوص ، يمكن إعادة استخدامه عبر واجهات برمجة تطبيقات مختلفة لبناء النماذج عالية المستوى مثل Keras ، لأن عمليات TensorFlow هي لغتهم الأساسية المشتركة.

إنقاذ من كيراس

بدءًا من TensorFlow 2 و tf.keras.Model.save() و tf.keras.models.save_model() افتراضيًا إلى تنسيق SavedModel (وليس HDF5). نماذج SavedModels الناتجة التي يمكن استخدامها مع hub.load() و hub.KerasLayer والمحولات المماثلة لواجهات برمجة التطبيقات عالية المستوى الأخرى عند توفرها.

لمشاركة نموذج Keras الكامل ، ما عليك سوى حفظه باستخدام include_optimizer=False .

لمشاركة قطعة من نموذج Keras ، اجعل القطعة نموذجًا في حد ذاتها ثم احفظها. يمكنك إما وضع الكود مثل هذا من البداية ....

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 تستخدم الأسلوب السابق لـ BERT (انظر nlp / tools / export_tfhub_lib.py ، لاحظ الانقسام بين core_model للتصدير pretrainer لاستعادة نقطة التفتيش) والنهج الأخير لـ ResNet (انظر legacy / image_classification / tfhub_export.py ).

التوفير من TensorFlow منخفض المستوى

يتطلب هذا معرفة جيدة بدليل SavedModel الخاص بـ TensorFlow.

إذا كنت تريد تقديم أكثر من مجرد توقيع للخدمة ، فيجب عليك تنفيذ واجهة SavedModel القابلة لإعادة الاستخدام . من الناحية المفاهيمية ، يبدو هذا

class MyMulModel(tf.train.Checkpoint):
  def __init__(self, v_init):
    super().__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

الكون المثالى

يُطلق على تدريب المتغيرات المدربة بالفعل لنموذج SavedModel المستورد جنبًا إلى جنب مع تلك الموجودة في النموذج المحيط به صقل النموذج SavedModel. يمكن أن يؤدي هذا إلى جودة أفضل ، ولكنه غالبًا ما يجعل التدريب أكثر تطلبًا (قد يستغرق وقتًا أطول ، ويعتمد أكثر على المحسن ومعلماته الفائقة ، ويزيد من خطر التجهيز الزائد ويتطلب زيادة في مجموعة البيانات ، خاصة لشبكات CNN). ننصح مستهلكي SavedModel بالبحث في الضبط الدقيق فقط بعد إنشاء نظام تدريب جيد ، وفقط إذا أوصى به ناشر SavedModel.

يعمل الضبط الدقيق على تغيير معلمات النموذج "المستمر" التي يتم تدريبها. إنه لا يغير التحولات ذات الترميز الثابت ، مثل ترميز إدخال النص وتعيين الرموز المميزة لإدخالاتها المقابلة في مصفوفة التضمين.

للمستهلكين SavedModel

إنشاء hub.KerasLayer مثل KerasLayer

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

يتيح ضبط SavedModel الذي تم تحميله بواسطة الطبقة. إنها تضيف الأوزان القابلة للتدريب ومنظمي الوزن المعلن عنها في SavedModel إلى نموذج Keras ، وتدير حساب SavedModel في وضع التدريب (فكر في التسرب وما إلى ذلك).

يحتوي colab لتصنيف الصور على مثال شامل مع ضبط دقيق اختياري.

إعادة تصدير نتيجة الضبط الدقيق

قد يرغب المستخدمون المتقدمون في حفظ نتائج الضبط الدقيق مرة أخرى في 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__ لكل من training=True training=False ، وما إلى ذلك)

اختر واجهة نموذج تعمل بشكل جيد مع تدفق التدرج ، على سبيل المثال ، سجلات الإخراج بدلاً من احتمالات softmax أو تنبؤات top-k.

إذا كان النموذج يستخدم التسرب أو تسوية الدُفعات أو تقنيات تدريب مشابهة تتضمن معلمات فائقة ، فقم بتعيينها على قيم منطقية عبر العديد من المشكلات المستهدفة المتوقعة وأحجام الدُفعات. (حتى كتابة هذه السطور ، لا يجعل الحفظ من Keras من السهل السماح للمستهلكين بتعديلها.)

يتم حفظ منظمي الوزن على الطبقات الفردية (مع معاملات قوة الانتظام الخاصة بهم) ، ولكن يتم فقدان تنظيم الوزن من داخل المُحسِّن (مثل tf.keras.optimizers.Ftrl.l1_regularization_strength=...) ). قم بإبلاغ المستهلكين بنموذج SavedModel الخاص بك وفقًا لذلك.