عند إطلاقه في عام 2018، قدم TensorFlow Hub نوعًا واحدًا من الأصول: تنسيق TF1 Hub للاستيراد إلى برامج TensorFlow 1.
تشرح هذه الصفحة كيفية استخدام تنسيق TF1 Hub في TF1 (أو وضع التوافق TF1 الخاص بـ TF2) مع فئة hub.Module
وواجهات برمجة التطبيقات المرتبطة بها. (الاستخدام النموذجي هو إنشاء tf.Graph
، ربما داخل TF1 Estimator
، من خلال دمج نموذج واحد أو أكثر بتنسيق TF1 Hub مع tf.compat.layers
أو tf.layers
).
يجب على مستخدمي TensorFlow 2 (خارج وضع التوافق TF1) استخدام واجهة برمجة التطبيقات الجديدة مع hub.load()
أو hub.KerasLayer
. تقوم واجهة برمجة التطبيقات الجديدة بتحميل نوع الأصل TF2 SavedModel الجديد، ولكنها تتمتع أيضًا بدعم محدود لتحميل تنسيق TF1 Hub إلى TF2 .
استخدام نموذج بتنسيق TF1 Hub
إنشاء نموذج بتنسيق TF1 Hub
يتم استيراد نموذج بتنسيق TF1 Hub إلى برنامج TensorFlow عن طريق إنشاء كائن hub.Module
من سلسلة تحتوي على عنوان URL الخاص بها أو مسار نظام الملفات، مثل:
m = hub.Module("path/to/a/module_dir")
ملاحظة: اطلع على مزيد من المعلومات بخصوص أنواع المقابض الصالحة الأخرى هنا .
يؤدي هذا إلى إضافة متغيرات الوحدة إلى الرسم البياني الحالي لـ TensorFlow. سيؤدي تشغيل أدوات التهيئة الخاصة بهم إلى قراءة قيمهم المدربة مسبقًا من القرص. وبالمثل، تتم إضافة الجداول والحالة الأخرى إلى الرسم البياني.
وحدات التخزين المؤقت
عند إنشاء وحدة نمطية من عنوان URL، يتم تنزيل محتوى الوحدة وتخزينها مؤقتًا في الدليل المؤقت للنظام المحلي. يمكن تجاوز الموقع الذي تم تخزين الوحدات فيه مؤقتًا باستخدام متغير البيئة TFHUB_CACHE_DIR
. لمزيد من التفاصيل، راجع التخزين المؤقت .
تطبيق الوحدة
بمجرد إنشاء مثيل لها، يمكن استدعاء الوحدة m
صفرًا أو أكثر مثل دالة Python من مدخلات الموتر إلى مخرجات الموتر:
y = m(x)
تضيف كل هذه الاستدعاءات عمليات إلى الرسم البياني TensorFlow الحالي لحساب y
من x
. إذا كان ذلك يتضمن متغيرات ذات أوزان مدربة، فسيتم مشاركتها بين جميع التطبيقات.
يمكن للوحدات تعريف عدة توقيعات مسماة للسماح بتطبيقها بأكثر من طريقة (على غرار الطريقة التي تمتلك بها كائنات Python الأساليب ). يجب أن تصف وثائق الوحدة التوقيعات المتاحة. يطبق الاستدعاء أعلاه التوقيع المسمى "default"
. يمكن تحديد أي توقيع عن طريق تمرير اسمه إلى الوسيطة signature=
الاختياري.
إذا كان التوقيع يحتوي على مدخلات متعددة، فيجب تمريرها كإملاء، مع تحديد المفاتيح بواسطة التوقيع. وبالمثل، إذا كان التوقيع يحتوي على مخرجات متعددة، فيمكن استرجاعها كإملاء عن طريق تمرير as_dict=True
، أسفل المفاتيح المحددة بواسطة التوقيع (المفتاح "default"
هو للمخرج الفردي الذي تم إرجاعه إذا كان as_dict=False
). لذا فإن الشكل الأكثر عمومية لتطبيق الوحدة يبدو كما يلي:
outputs = m(dict(apples=x1, oranges=x2), signature="fruit_to_pet", as_dict=True)
y1 = outputs["cats"]
y2 = outputs["dogs"]
يجب على المتصل توفير جميع المدخلات المحددة بواسطة التوقيع، ولكن ليس هناك أي شرط لاستخدام كافة مخرجات الوحدة. لن يقوم TensorFlow بتشغيل سوى تلك الأجزاء من الوحدة التي تنتهي كتبعيات لهدف في tf.Session.run()
. في الواقع، قد يختار ناشرو الوحدات توفير مخرجات مختلفة للاستخدامات المتقدمة (مثل تنشيط الطبقات المتوسطة) إلى جانب المخرجات الرئيسية. يجب على مستهلكي الوحدة التعامل مع المخرجات الإضافية بأمان.
تجربة وحدات بديلة
عندما تكون هناك وحدات متعددة لنفس المهمة، يشجع TensorFlow Hub على تزويدها بتوقيعات (واجهات) متوافقة بحيث تكون تجربة وحدات مختلفة أمرًا سهلاً مثل تغيير مقبض الوحدة كمعلمة تشعبية ذات قيمة سلسلة.
ولتحقيق هذه الغاية، نحتفظ بمجموعة من التوقيعات العامة الموصى بها للمهام الشائعة.
إنشاء وحدة جديدة
ملاحظة التوافق
تم تصميم تنسيق TF1 Hub نحو TensorFlow 1. وهو مدعوم جزئيًا فقط بواسطة TF Hub في TensorFlow 2. يرجى التفكير في النشر بتنسيق TF2 SavedModel الجديد بدلاً من ذلك.
يشبه تنسيق TF1 Hub تنسيق SavedModel الخاص بـ TensorFlow 1 على المستوى النحوي (نفس أسماء الملفات ورسائل البروتوكول) ولكنه يختلف لغويًا للسماح بإعادة استخدام الوحدة النمطية وتكوينها وإعادة التدريب (على سبيل المثال، تخزين مختلف لمهيئات الموارد ووضع علامات مختلفة اتفاقيات الميتاجراف). أسهل طريقة للتمييز بينها على القرص هي وجود أو عدم وجود ملف tfhub_module.pb
.
النهج العام
لتعريف وحدة نمطية جديدة، يقوم الناشر باستدعاء hub.create_module_spec()
مع دالة module_fn
. تقوم هذه الوظيفة بإنشاء رسم بياني يمثل البنية الداخلية للوحدة، باستخدام tf.placeholder()
للمدخلات التي سيتم توفيرها بواسطة المتصل. ثم يقوم بتعريف التوقيعات عن طريق استدعاء hub.add_signature(name, inputs, outputs)
مرة واحدة أو أكثر.
على سبيل المثال:
def module_fn():
inputs = tf.placeholder(dtype=tf.float32, shape=[None, 50])
layer1 = tf.layers.dense(inputs, 200)
layer2 = tf.layers.dense(layer1, 100)
outputs = dict(default=layer2, hidden_activations=layer1)
# Add default signature.
hub.add_signature(inputs=inputs, outputs=outputs)
...
spec = hub.create_module_spec(module_fn)
يمكن استخدام نتيجة hub.create_module_spec()
، بدلاً من المسار، لإنشاء كائن وحدة داخل رسم بياني TensorFlow معين. في مثل هذه الحالة، لا توجد نقطة تفتيش، وسيستخدم مثيل الوحدة مُهيئات المتغير بدلاً من ذلك.
يمكن إجراء تسلسل لأي مثيل وحدة على القرص عبر طريقة export(path, session)
. يؤدي تصدير الوحدة النمطية إلى إجراء تسلسل لتعريفها مع الحالة الحالية لمتغيراتها في session
في المسار الذي تم تمريره. يمكن استخدام هذا عند تصدير وحدة نمطية لأول مرة، وكذلك عند تصدير وحدة مضبوطة بدقة.
للتوافق مع TensorFlow Estimators، يقوم hub.LatestModuleExporter
بتصدير الوحدات من أحدث نقطة تفتيش، تمامًا مثل tf.estimator.LatestExporter
الذي يصدر النموذج بأكمله من أحدث نقطة تفتيش.
يجب على ناشرو الوحدات تنفيذ توقيع مشترك عندما يكون ذلك ممكنًا، بحيث يمكن للمستهلكين تبادل الوحدات النمطية بسهولة والعثور على أفضلها لمشكلتهم.
مثال حقيقي
قم بإلقاء نظرة على مُصدر وحدة تضمين النص الخاص بنا للحصول على مثال واقعي لكيفية إنشاء وحدة من تنسيق تضمين نص شائع.
الكون المثالى
يُطلق على تدريب متغيرات الوحدة المستوردة مع متغيرات النموذج المحيط بها اسم الضبط الدقيق . يمكن أن يؤدي الضبط الدقيق إلى تحسين الجودة، ولكنه يضيف تعقيدات جديدة. ننصح المستهلكين بالنظر في الضبط الدقيق فقط بعد استكشاف تعديلات أبسط للجودة، وفقط إذا أوصى ناشر الوحدة بذلك.
للمستهلكين
لتمكين الضبط الدقيق، قم بإنشاء مثيل للوحدة باستخدام hub.Module(..., trainable=True)
لجعل متغيراتها قابلة للتدريب واستيراد REGULARIZATION_LOSSES
الخاص بـ TensorFlow . إذا كانت الوحدة تحتوي على متغيرات متعددة للرسم البياني، فتأكد من اختيار الخيار المناسب للتدريب. عادة، هذا هو الذي يحتوي على العلامات {"train"}
.
اختر نظامًا تدريبيًا لا يفسد الأوزان المدربة مسبقًا، على سبيل المثال معدل تعلم أقل من التدريب من الصفر.
للناشرين
لتسهيل عملية الضبط على المستهلكين، يرجى مراعاة ما يلي:
الضبط الدقيق يحتاج إلى التنظيم. يتم تصدير الوحدة الخاصة بك مع مجموعة
REGULARIZATION_LOSSES
، وهو ما يضع اختيارك لـtf.layers.dense(..., kernel_regularizer=...)
وما إلى ذلك ضمن ما يحصل عليه المستهلك منtf.losses.get_regularization_losses()
. تفضل هذه الطريقة لتحديد خسائر التنظيم L1/L2.في نموذج الناشر، تجنب تحديد تنظيم L1/L2 عبر معلمات
l1_
وl2_regularization_strength
الخاصة بـtf.train.FtrlOptimizer
وtf.train.ProximalGradientDescentOptimizer
ومحسنات التحسين القريبة الأخرى. ولا يتم تصديرها جنبًا إلى جنب مع الوحدة، وقد لا يكون تحديد نقاط قوة التنظيم عالميًا مناسبًا للمستهلك. باستثناء تنظيم L1 في النماذج الواسعة (أي الخطية المتفرقة) أو الواسعة والعميقة، يجب أن يكون من الممكن استخدام خسائر التنظيم الفردية بدلاً من ذلك.إذا كنت تستخدم التسرب، أو تسوية الدُفعات، أو تقنيات تدريب مشابهة، فقم بتعيين المعلمات الفائقة الخاصة بها على قيم منطقية عبر العديد من الاستخدامات المتوقعة. قد يلزم تعديل معدل التسرب ليتناسب مع ميل المشكلة المستهدفة إلى التجهيز الزائد. في تطبيع الدُفعات، يجب أن يكون الزخم (المعروف أيضًا باسم معامل الانحلال) صغيرًا بما يكفي لتمكين الضبط الدقيق مع مجموعات البيانات الصغيرة و/أو الدُفعات الكبيرة. بالنسبة للمستهلكين المتقدمين، فكر في إضافة توقيع يكشف عن التحكم في المعلمات الفائقة الهامة.