ملخص
يقدم هذا المستند واجهات تسهل مهام التعلم الموحد ، مثل التدريب الموحد أو التقييم باستخدام نماذج التعلم الآلي الحالية المطبقة في TensorFlow. في تصميم هذه الواجهات ، كان هدفنا الأساسي هو إتاحة تجربة التعلم الموحد دون الحاجة إلى معرفة كيفية عمله تحت الغطاء ، وتقييم خوارزميات التعلم الموحد المنفذة على مجموعة متنوعة من النماذج والبيانات الحالية. نحن نشجعك على المساهمة مرة أخرى في المنصة. تم تصميم TFF مع مراعاة القابلية للتوسعة والتركيب ، ونحن نرحب بالمساهمات ؛ نحن متحمسون لرؤية ما توصلت إليه!
تتكون الواجهات التي توفرها هذه الطبقة من الأجزاء الثلاثة التالية:
النماذج . الفئات والوظائف المساعدة التي تسمح لك بتغليف النماذج الموجودة لديك لاستخدامها مع TFF. يمكن أن يكون التفاف النموذج بسيطًا مثل استدعاء وظيفة التفاف واحدة (على سبيل المثال ،
tff.learning.models.from_keras_model
) ، أو تحديد فئة فرعية من واجهةtff.learning.models.VariableModel
للتخصيص الكامل.بناة الحساب الموحد . الدالات المساعدة التي تنشئ حسابات موحدة للتدريب أو التقييم ، باستخدام النماذج الموجودة لديك.
مجموعات البيانات . مجموعات البيانات المعلبة التي يمكنك تنزيلها والوصول إليها في Python لاستخدامها في محاكاة سيناريوهات التعلم الموحد. على الرغم من أن التعلم الموحد مصمم للاستخدام مع البيانات اللامركزية التي لا يمكن تنزيلها ببساطة في موقع مركزي ، إلا أنه في مراحل البحث والتطوير يكون من الملائم في كثير من الأحيان إجراء تجارب أولية باستخدام البيانات التي يمكن تنزيلها ومعالجتها محليًا ، خاصة للمطورين الذين قد يكونون كذلك. جديد في هذا النهج.
يتم تعريف هذه الواجهات في المقام الأول في مساحة الاسم tff.learning
، باستثناء مجموعات بيانات البحث والقدرات الأخرى المتعلقة بالمحاكاة التي تم تجميعها في tff.simulation
. يتم تنفيذ هذه الطبقة باستخدام واجهات ذات مستوى منخفض توفرها Federated Core (FC) ، والتي توفر أيضًا بيئة تشغيل.
قبل المتابعة ، نوصي بأن تقوم أولاً بمراجعة البرامج التعليمية حول تصنيف الصور وإنشاء النص ، لأنها تقدم معظم المفاهيم الموضحة هنا باستخدام أمثلة ملموسة. إذا كنت مهتمًا بمعرفة المزيد حول كيفية عمل TFF ، فقد ترغب في الاطلاع على البرنامج التعليمي للخوارزميات المخصصة كمقدمة للواجهات ذات المستوى الأدنى التي نستخدمها للتعبير عن منطق الحسابات الموحدة ، ودراسة التنفيذ الحالي لـ واجهات tff.learning
.
عارضات ازياء
الافتراضات المعمارية
التسلسل
يهدف TFF إلى دعم مجموعة متنوعة من سيناريوهات التعلم الموزعة التي قد يتم فيها تنفيذ كود نموذج التعلم الآلي الذي تكتبه على عدد كبير من العملاء غير المتجانسين ذوي القدرات المتنوعة. بينما في أحد طرفي الطيف ، قد يكون هؤلاء العملاء في بعض التطبيقات خوادم قاعدة بيانات قوية ، فإن العديد من الاستخدامات المهمة التي تعتزم منصتنا دعمها تتضمن الأجهزة المحمولة والمدمجة ذات الموارد المحدودة. لا يمكننا افتراض أن هذه الأجهزة قادرة على استضافة أوقات تشغيل Python ؛ الشيء الوحيد الذي يمكننا أن نفترضه في هذه المرحلة هو أنهم قادرون على استضافة وقت تشغيل TensorFlow محلي. وبالتالي ، فإن الافتراض المعماري الأساسي الذي نتخذه في TFF هو أن كود النموذج الخاص بك يجب أن يكون قابلاً للتسلسل كرسم بياني TensorFlow.
لا يزال بإمكانك (ويجب عليك) تطوير كود TF الخاص بك باتباع أحدث الممارسات مثل استخدام الوضع المتهور. ومع ذلك ، يجب أن يكون الكود النهائي قابلاً للتسلسل (على سبيل المثال ، يمكن لفه كدالة tf.function
لكود الوضع المتلهف). يضمن ذلك إمكانية إجراء تسلسل لأي حالة أو تدفق تحكم في Python ضروري في وقت التنفيذ (ربما بمساعدة Autograph ).
حاليًا ، لا يدعم TensorFlow بشكل كامل التسلسل وإلغاء التسلسل في الوضع النشط TensorFlow. وبالتالي ، فإن التسلسل في TFF يتبع حاليًا نمط TF 1.0 ، حيث يجب إنشاء كل الكود داخل tf.Graph
يتحكم فيه TFF. هذا يعني أن TFF حاليًا لا يمكنه استهلاك نموذج تم إنشاؤه بالفعل ؛ بدلاً من ذلك ، يتم تجميع منطق تعريف النموذج في دالة no-arg التي تقوم بإرجاع tff.learning.models.VariableModel
. ثم يتم استدعاء هذه الوظيفة بواسطة TFF لضمان إجراء تسلسل لجميع مكونات النموذج. بالإضافة إلى ذلك ، نظرًا لكونها بيئة مكتوبة بشدة ، سيتطلب TFF القليل من البيانات الوصفية الإضافية ، مثل مواصفات نوع إدخال النموذج الخاص بك.
تجميع
نوصي بشدة معظم المستخدمين بإنشاء نماذج باستخدام Keras ، راجع قسم محولات Keras أدناه. تتعامل هذه الأغلفة مع تجميع تحديثات النموذج بالإضافة إلى أي مقاييس محددة للنموذج تلقائيًا. ومع ذلك ، قد يكون من المفيد فهم كيفية معالجة التجميع لـ tff.learning.models.VariableModel
العام.
هناك دائمًا طبقتان على الأقل من التجميع في التعلم الموحد: التجميع المحلي على الجهاز والتجميع عبر الأجهزة (أو الموحد):
التجميع المحلي . يشير مستوى التجميع هذا إلى التجميع عبر مجموعات متعددة من الأمثلة التي يمتلكها عميل فردي. ينطبق على كل من معلمات النموذج (المتغيرات) ، والتي تستمر في التطور بالتسلسل حيث يتم تدريب النموذج محليًا ، بالإضافة إلى الإحصائيات التي تحسبها (مثل متوسط الخسارة والدقة والمقاييس الأخرى) ، والتي سيقوم نموذجك بتحديثها محليًا مرة أخرى لأنه يتكرر عبر تدفق البيانات المحلية لكل عميل على حدة.
يعد إجراء التجميع على هذا المستوى مسؤولية كود النموذج الخاص بك ، ويتم إنجازه باستخدام تركيبات TensorFlow القياسية.
الهيكل العام للمعالجة كما يلي:
يبني النموذج أولاً
tf.Variable
للاحتفاظ بالمجموعات ، مثل عدد الدُفعات أو عدد الأمثلة التي تمت معالجتها ، ومجموع الخسائر لكل دفعة أو لكل مثال ، إلخ.تستدعي TFF طريقة
forward_pass
فيModel
الخاص بك عدة مرات ، بالتتابع على دفعات لاحقة من بيانات العميل ، مما يسمح لك بتحديث المتغيرات التي تحتوي على مجاميع مختلفة كأثر جانبي.أخيرًا ، تستدعي TFF طريقة
report_local_unfinalized_metrics
على نموذجك للسماح لنموذجك بتجميع جميع الإحصائيات الموجزة التي تم جمعها في مجموعة مضغوطة من المقاييس ليتم تصديرها بواسطة العميل. هذا هو المكان الذي قد تقوم فيه شفرة النموذج ، على سبيل المثال ، بتقسيم مجموع الخسائر على عدد الأمثلة التي تمت معالجتها لتصدير متوسط الخسارة ، إلخ.
تجميع متحد . يشير مستوى التجميع هذا إلى التجميع عبر عدة عملاء (أجهزة) في النظام. مرة أخرى ، ينطبق على كل من معلمات النموذج (المتغيرات) ، التي يتم حساب متوسطها عبر العملاء ، بالإضافة إلى المقاييس التي تم تصديرها بواسطة نموذجك كنتيجة للتجميع المحلي.
أداء التجميع على هذا المستوى هو مسؤولية TFF. بصفتك منشئ نموذج ، يمكنك التحكم في هذه العملية (المزيد حول هذا أدناه).
الهيكل العام للمعالجة كما يلي:
يتم توزيع النموذج الأولي ، وأي معلمات مطلوبة للتدريب ، بواسطة الخادم على مجموعة فرعية من العملاء الذين سيشاركون في جولة من التدريب أو التقييم.
على كل عميل ، بشكل مستقل وبالتوازي ، يتم استدعاء رمز النموذج الخاص بك بشكل متكرر على دفق من مجموعات البيانات المحلية لإنتاج مجموعة جديدة من معلمات النموذج (عند التدريب) ، ومجموعة جديدة من المقاييس المحلية ، كما هو موضح أعلاه (هذا محلي تجميع).
يدير TFF بروتوكول تجميع موزع لتجميع وتجميع معلمات النموذج والمقاييس المصدرة محليًا عبر النظام. يتم التعبير عن هذا المنطق بطريقة توضيحية باستخدام لغة الحساب الموحدة الخاصة بـ TFF (ليس في TensorFlow). راجع البرنامج التعليمي للخوارزميات المخصصة لمزيد من المعلومات حول واجهة برمجة تطبيقات التجميع.
واجهات مجردة
يتم تمثيل المُنشئ الأساسي + واجهة البيانات الوصفية بالواجهة tff.learning.models.VariableModel
، على النحو التالي:
يجب أن تنشئ طرق المُنشئ ، و
forward_pass
، وreport_local_unfinalized_metrics
متغيرات النموذج ، وتمرير التوجيه ، والإحصاءات التي ترغب في الإبلاغ عنها ، في المقابل. يجب أن يكون TensorFlow الذي تم إنشاؤه بواسطة هذه الطرق قابلاً للتسلسل ، كما تمت مناقشته أعلاه.تمثل خاصية
input_spec
، بالإضافة إلى الخصائص الثلاث التي تعرض مجموعات فرعية من المتغيرات المحلية القابلة للتدريب وغير القابلة للتدريب والمحلية ، البيانات الوصفية. يستخدم TFF هذه المعلومات لتحديد كيفية توصيل أجزاء من النموذج الخاص بك بخوارزميات التحسين الموحدة ، ولتحديد تواقيع النوع الداخلي للمساعدة في التحقق من صحة النظام المُنشأ (بحيث لا يمكن إنشاء مثيل للنموذج الخاص بك على البيانات التي لا تتطابق مع ما النموذج مصمم للاستهلاك).
بالإضافة إلى ذلك ، تعرض الواجهة المجردة tff.learning.models.VariableModel
خاصية metric_finalizers
التي تأخذ القيم غير النهائية للمقياس (يتم إرجاعها بواسطة report_local_unfinalized_metrics()
) وإرجاع القيم المترية النهائية. سيتم استخدام طريقة metric_finalizers
و report_local_unfinalized_metrics()
معًا لبناء مجمّع مقاييس عبر العملاء عند تحديد عمليات التدريب الموحدة أو حسابات التقييم. على سبيل المثال ، سوف يقوم المجمّع tff.learning.metrics.sum_then_finalize
البسيط بجمع القيم المترية غير النهائية من العملاء أولاً ، ثم استدعاء وظائف finalizer على الخادم.
يمكنك العثور على أمثلة حول كيفية تحديد tff.learning.models.VariableModel
المخصص الخاص بك في الجزء الثاني من البرنامج التعليمي الخاص بتصنيف الصور ، وكذلك في نماذج النماذج التي نستخدمها للاختبار في model_examples.py
.
محولات Keras
يمكن اشتقاق جميع المعلومات المطلوبة تقريبًا بواسطة TFF عن طريق استدعاء واجهات tf.keras
، لذلك إذا كان لديك نموذج Keras ، فيمكنك الاعتماد على tff.learning.models.from_keras_model
لإنشاء نموذج tff.learning.models.VariableModel
.
لاحظ أن TFF لا تزال تريد منك توفير مُنشئ - دالة نموذج بدون وسيطة مثل ما يلي:
def model_fn():
keras_model = ...
return tff.learning.models.from_keras_model(keras_model, sample_batch, loss=...)
بالإضافة إلى النموذج نفسه ، يمكنك توفير دفعة عينة من البيانات التي يستخدمها TFF لتحديد نوع وشكل إدخال النموذج الخاص بك. هذا يضمن أن TFF يمكنه إنشاء مثيل صحيح لنموذج البيانات التي ستكون موجودة بالفعل على أجهزة العميل (نظرًا لأننا نفترض أن هذه البيانات غير متاحة بشكل عام في الوقت الذي تقوم فيه بإنشاء TensorFlow ليتم تحويلها إلى تسلسل).
تم توضيح استخدام أغلفة Keras في برامجنا التعليمية لتصنيف الصور وإنشاء النصوص .
بناة الحساب الموحد
توفر حزمة tff.learning
العديد من البناة لـ tff.Computation
s التي تؤدي مهام متعلقة بالتعلم ؛ نتوقع أن تتوسع مجموعة هذه الحسابات في المستقبل.
الافتراضات المعمارية
تنفيذ
هناك مرحلتان متميزتان في تشغيل حساب موحد.
التحويل البرمجي : يقوم TFF أولاً بتجميع خوارزميات التعلم الموحدة في تمثيل تسلسلي مجردة للحساب الموزع بأكمله. يحدث هذا عند حدوث تسلسل TensorFlow ، ولكن يمكن أن تحدث تحويلات أخرى لدعم التنفيذ الأكثر كفاءة. نشير إلى التمثيل المتسلسل المنبعث من المترجم كحساب موحد .
يوفر تنفيذ TFF طرقًا لتنفيذ هذه الحسابات. في الوقت الحالي ، يتم دعم التنفيذ فقط من خلال محاكاة محلية (على سبيل المثال ، في جهاز كمبيوتر محمول باستخدام محاكاة بيانات لامركزية).
يتضمن الحساب الموحد الذي تم إنشاؤه بواسطة واجهة برمجة تطبيقات التعلم الموحدة الخاصة بـ TFF ، مثل خوارزمية التدريب التي تستخدم متوسط نموذج موحد ، أو تقييم موحد ، عددًا من العناصر ، أبرزها:
نموذج متسلسل من كود النموذج الخاص بك بالإضافة إلى كود TensorFlow الإضافي الذي تم إنشاؤه بواسطة إطار عمل Federated Learning لدفع حلقة التدريب / التقييم الخاصة بنموذجك (مثل إنشاء أدوات تحسين ، وتطبيق تحديثات النموذج ، والتكرار عبر
tf.data.Dataset
s ، ومقاييس الحوسبة ، وتطبيق التحديث المجمع على الخادم ، على سبيل المثال لا الحصر).مواصفات تعريفية للاتصال بين العملاء والخادم (عادةً أشكال مختلفة من التجميع عبر أجهزة العميل ، والبث من الخادم إلى جميع العملاء) ، وكيف يتم تشذير هذا الاتصال الموزع مع تنفيذ العميل المحلي أو الخادم المحلي من كود TensorFlow.
يتم التعبير عن الحسابات الموحدة الممثلة في هذا النموذج المتسلسل بلغة داخلية مستقلة عن النظام الأساسي تختلف عن لغة Python ، ولكن لاستخدام Federated Learning API ، لن تحتاج إلى القلق بشأن تفاصيل هذا التمثيل. يتم تمثيل العمليات الحسابية في كود Python الخاص بك ككائنات من النوع tff.Computation
، والتي في معظمها يمكنك التعامل معها على أنها مبهمة للغة Python callable
.
في البرامج التعليمية ، ستستدعي تلك الحسابات الموحدة كما لو كانت وظائف Python عادية ، ليتم تنفيذها محليًا. ومع ذلك ، تم تصميم TFF للتعبير عن الحسابات الموحدة بطريقة لا تراعي معظم جوانب بيئة التنفيذ ، بحيث يمكن نشرها على سبيل المثال ، على مجموعات من الأجهزة التي تعمل Android
، أو إلى مجموعات في مركز بيانات. مرة أخرى ، النتيجة الرئيسية لهذا هي افتراضات قوية حول التسلسل . على وجه الخصوص ، عند استدعاء إحدى طرق build_...
الموضحة أدناه ، يتم إجراء تسلسل كامل للحساب.
حالة النمذجة
TFF هي بيئة برمجة وظيفية ، ومع ذلك فإن العديد من العمليات ذات الأهمية في التعلم الفيدرالي تتسم بالحالة. على سبيل المثال ، حلقة التدريب التي تتضمن جولات متعددة من نموذج الاتحاد المتوسط هي مثال على ما يمكن أن نصنفه على أنه عملية ذات حالة . في هذه العملية ، تتضمن الحالة التي تتطور من جولة إلى أخرى مجموعة معلمات النموذج التي يتم تدريبها ، وربما الحالة الإضافية المرتبطة بالمحسِّن (على سبيل المثال ، ناقل الزخم).
نظرًا لأن TFF وظيفية ، يتم نمذجة العمليات ذات الحالة في TFF كعمليات حسابية تقبل الحالة الحالية كمدخلات ثم توفر الحالة المحدثة كمخرج. من أجل تحديد عملية ذات حالة كاملة ، يحتاج المرء أيضًا إلى تحديد مصدر الحالة الأولية (وإلا لا يمكننا تمهيد العملية). يتم التقاط هذا في تعريف الفئة المساعدة tff.templates.IterativeProcess
، مع initialize
الخاصيتين ثم next
للتهيئة والتكرار ، على التوالي.
البناة المتاحون
في الوقت الحالي ، يوفر TFF العديد من وظائف البناء التي تنشئ حسابات موحدة للتدريب والتقييم الفيدرالي. من الأمثلة البارزة ما يلي:
tff.learning.algorithms.build_weighted_fed_avg
، والتي تأخذ كمدخل دالة نموذج ومحسن عميل ، وتعيدtff.learning.templates.LearningProcess
(أي الفئات الفرعيةtff.templates.IterativeProcess
).يأخذ
tff.learning.build_federated_evaluation
دالة نموذجية ويعيد حسابًا موحدًا واحدًا للتقييم الموحد للنماذج ، نظرًا لأن التقييم ليس ذو حالة.
مجموعات البيانات
الافتراضات المعمارية
اختيار العميل
في سيناريو التعلم الموحد النموذجي ، لدينا عدد كبير من السكان يحتمل أن يصل إلى مئات الملايين من أجهزة العملاء ، والتي قد يكون جزء صغير منها نشطًا ومتاحًا للتدريب في أي لحظة (على سبيل المثال ، قد يقتصر هذا على العملاء الذين هم متصل بمصدر طاقة ، وليس على شبكة مقننة ، وبخلاف ذلك خاملاً). بشكل عام ، تكون مجموعة العملاء المتاحة للمشاركة في التدريب أو التقييم خارج سيطرة المطور. علاوة على ذلك ، نظرًا لأنه من غير العملي التنسيق بين ملايين العملاء ، فإن الجولة النموذجية من التدريب أو التقييم ستشمل جزءًا صغيرًا فقط من العملاء المتاحين ، والتي قد يتم أخذ عينات منها بشكل عشوائي .
والنتيجة الرئيسية لذلك هي أن الحسابات الموحدة ، حسب التصميم ، يتم التعبير عنها بطريقة غير مدركة للمجموعة الدقيقة من المشاركين ؛ يتم التعبير عن جميع عمليات المعالجة على أنها عمليات مجمعة على مجموعة مجردة من العملاء المجهولين ، وقد تختلف هذه المجموعة من جولة تدريب إلى أخرى. وبالتالي ، فإن الارتباط الفعلي للحساب بالمشاركين الملموسين ، وبالتالي بالبيانات الملموسة التي يغذونها في الحساب ، يتم نمذجته خارج الحساب نفسه.
من أجل محاكاة نشر واقعي لرمز التعلم الموحد الخاص بك ، سوف تكتب بشكل عام حلقة تدريب تبدو كالتالي:
trainer = tff.learning.algorithms.build_weighted_fed_avg(...)
state = trainer.initialize()
federated_training_data = ...
def sample(federate_data):
return ...
while True:
data_for_this_round = sample(federated_training_data)
result = trainer.next(state, data_for_this_round)
state = result.state
من أجل تسهيل ذلك ، عند استخدام TFF في عمليات المحاكاة ، يتم قبول البيانات الموحدة على أنها list
Python ، مع عنصر واحد لكل جهاز عميل مشارك لتمثيل tf.data.Dataset
المحلي للجهاز.
واجهات مجردة
من أجل توحيد التعامل مع مجموعات البيانات الموحدة المحاكية ، يوفر TFF واجهة مجردة tff.simulation.datasets.ClientData
، والتي تتيح للفرد تعداد مجموعة العملاء ، وإنشاء tf.data.Dataset
التي تحتوي على بيانات معينة عميل. يمكن تغذية مجموعات البيانات هذه tf.data.Dataset
مباشرة كمدخلات للحسابات الموحدة التي تم إنشاؤها في الوضع الحثيث.
تجدر الإشارة إلى أن القدرة على الوصول إلى هويات العميل هي ميزة لا يتم توفيرها إلا من خلال مجموعات البيانات لاستخدامها في عمليات المحاكاة ، حيث قد تكون هناك حاجة إلى القدرة على التدريب على البيانات من مجموعات فرعية محددة من العملاء (على سبيل المثال ، لمحاكاة التوافر اليومي لمختلف أنواع العملاء). لا تتضمن الحسابات المترجمة ووقت التشغيل الأساسي أي فكرة عن هوية العميل. بمجرد اختيار البيانات من مجموعة فرعية معينة من العملاء كمدخلات ، على سبيل المثال ، في استدعاء tff.templates.IterativeProcess.next
، لن تظهر هويات العميل فيها.
مجموعات البيانات المتاحة
لقد خصصنا مساحة الاسم tff.simulation.datasets
لمجموعات البيانات التي تنفذ واجهة tff.simulation.datasets.ClientData
لاستخدامها في عمليات المحاكاة ، وزرناها بمجموعات بيانات لدعم تصنيف الصور والبرامج التعليمية لإنشاء النص . نود أن نشجعك على المساهمة بمجموعات البيانات الخاصة بك في النظام الأساسي.
ملخص
يقدم هذا المستند واجهات تسهل مهام التعلم الموحد ، مثل التدريب الموحد أو التقييم باستخدام نماذج التعلم الآلي الحالية المطبقة في TensorFlow. في تصميم هذه الواجهات ، كان هدفنا الأساسي هو إتاحة تجربة التعلم الموحد دون الحاجة إلى معرفة كيفية عمله تحت الغطاء ، وتقييم خوارزميات التعلم الموحد المنفذة على مجموعة متنوعة من النماذج والبيانات الحالية. نحن نشجعك على المساهمة مرة أخرى في المنصة. تم تصميم TFF مع مراعاة القابلية للتوسعة والتركيب ، ونحن نرحب بالمساهمات ؛ نحن متحمسون لرؤية ما توصلت إليه!
تتكون الواجهات التي توفرها هذه الطبقة من الأجزاء الثلاثة التالية:
النماذج . الفئات والوظائف المساعدة التي تسمح لك بتغليف النماذج الموجودة لديك لاستخدامها مع TFF. يمكن أن يكون التفاف النموذج بسيطًا مثل استدعاء وظيفة التفاف واحدة (على سبيل المثال ،
tff.learning.models.from_keras_model
) ، أو تحديد فئة فرعية من واجهةtff.learning.models.VariableModel
للتخصيص الكامل.بناة الحساب الموحد . الدالات المساعدة التي تنشئ حسابات موحدة للتدريب أو التقييم ، باستخدام النماذج الموجودة لديك.
مجموعات البيانات . مجموعات البيانات المعلبة التي يمكنك تنزيلها والوصول إليها في Python لاستخدامها في محاكاة سيناريوهات التعلم الموحد. على الرغم من أن التعلم الموحد مصمم للاستخدام مع البيانات اللامركزية التي لا يمكن تنزيلها ببساطة في موقع مركزي ، إلا أنه في مراحل البحث والتطوير يكون من الملائم في كثير من الأحيان إجراء تجارب أولية باستخدام البيانات التي يمكن تنزيلها ومعالجتها محليًا ، خاصة للمطورين الذين قد يكونون كذلك. جديد في هذا النهج.
يتم تعريف هذه الواجهات في المقام الأول في مساحة الاسم tff.learning
، باستثناء مجموعات بيانات البحث والقدرات الأخرى المتعلقة بالمحاكاة التي تم تجميعها في tff.simulation
. يتم تنفيذ هذه الطبقة باستخدام واجهات ذات مستوى منخفض توفرها Federated Core (FC) ، والتي توفر أيضًا بيئة تشغيل.
قبل المتابعة ، نوصي بأن تقوم أولاً بمراجعة البرامج التعليمية حول تصنيف الصور وإنشاء النص ، لأنها تقدم معظم المفاهيم الموضحة هنا باستخدام أمثلة ملموسة. إذا كنت مهتمًا بمعرفة المزيد حول كيفية عمل TFF ، فقد ترغب في الاطلاع على البرنامج التعليمي للخوارزميات المخصصة كمقدمة للواجهات ذات المستوى الأدنى التي نستخدمها للتعبير عن منطق الحسابات الموحدة ، ودراسة التنفيذ الحالي لـ واجهات tff.learning
.
عارضات ازياء
الافتراضات المعمارية
التسلسل
يهدف TFF إلى دعم مجموعة متنوعة من سيناريوهات التعلم الموزعة التي قد يتم فيها تنفيذ كود نموذج التعلم الآلي الذي تكتبه على عدد كبير من العملاء غير المتجانسين ذوي القدرات المتنوعة. بينما في أحد طرفي الطيف ، قد يكون هؤلاء العملاء في بعض التطبيقات خوادم قاعدة بيانات قوية ، فإن العديد من الاستخدامات المهمة التي تعتزم منصتنا دعمها تتضمن الأجهزة المحمولة والمدمجة ذات الموارد المحدودة. لا يمكننا افتراض أن هذه الأجهزة قادرة على استضافة أوقات تشغيل Python ؛ الشيء الوحيد الذي يمكننا أن نفترضه في هذه المرحلة هو أنهم قادرون على استضافة وقت تشغيل TensorFlow محلي. وبالتالي ، فإن الافتراض المعماري الأساسي الذي نتخذه في TFF هو أن كود النموذج الخاص بك يجب أن يكون قابلاً للتسلسل كرسم بياني TensorFlow.
لا يزال بإمكانك (ويجب عليك) تطوير كود TF الخاص بك باتباع أحدث الممارسات مثل استخدام الوضع المتهور. ومع ذلك ، يجب أن يكون الكود النهائي قابلاً للتسلسل (على سبيل المثال ، يمكن لفه كدالة tf.function
لكود الوضع المتلهف). يضمن ذلك إمكانية إجراء تسلسل لأي حالة أو تدفق تحكم في Python ضروري في وقت التنفيذ (ربما بمساعدة Autograph ).
حاليًا ، لا يدعم TensorFlow بشكل كامل التسلسل وإلغاء التسلسل في الوضع النشط TensorFlow. وبالتالي ، فإن التسلسل في TFF يتبع حاليًا نمط TF 1.0 ، حيث يجب إنشاء كل الكود داخل tf.Graph
يتحكم فيه TFF. هذا يعني أن TFF حاليًا لا يمكنه استهلاك نموذج تم إنشاؤه بالفعل ؛ بدلاً من ذلك ، يتم تجميع منطق تعريف النموذج في دالة no-arg التي تقوم بإرجاع tff.learning.models.VariableModel
. ثم يتم استدعاء هذه الوظيفة بواسطة TFF لضمان إجراء تسلسل لجميع مكونات النموذج. بالإضافة إلى ذلك ، نظرًا لكونها بيئة مكتوبة بشدة ، سيتطلب TFF القليل من البيانات الوصفية الإضافية ، مثل مواصفات نوع إدخال النموذج الخاص بك.
تجميع
نوصي بشدة معظم المستخدمين بإنشاء نماذج باستخدام Keras ، راجع قسم محولات Keras أدناه. تتعامل هذه الأغلفة مع تجميع تحديثات النموذج بالإضافة إلى أي مقاييس محددة للنموذج تلقائيًا. ومع ذلك ، قد يكون من المفيد فهم كيفية معالجة التجميع لـ tff.learning.models.VariableModel
العام.
هناك دائمًا طبقتان على الأقل من التجميع في التعلم الموحد: التجميع المحلي على الجهاز والتجميع عبر الأجهزة (أو الموحد):
التجميع المحلي . يشير مستوى التجميع هذا إلى التجميع عبر مجموعات متعددة من الأمثلة التي يمتلكها عميل فردي. ينطبق على كل من معلمات النموذج (المتغيرات) ، والتي تستمر في التطور بالتسلسل حيث يتم تدريب النموذج محليًا ، بالإضافة إلى الإحصائيات التي تحسبها (مثل متوسط الخسارة والدقة والمقاييس الأخرى) ، والتي سيقوم نموذجك بتحديثها محليًا مرة أخرى لأنه يتكرر عبر تدفق البيانات المحلية لكل عميل على حدة.
يعد إجراء التجميع على هذا المستوى مسؤولية كود النموذج الخاص بك ، ويتم إنجازه باستخدام تركيبات TensorFlow القياسية.
الهيكل العام للمعالجة كما يلي:
يبني النموذج أولاً
tf.Variable
للاحتفاظ بالمجموعات ، مثل عدد الدُفعات أو عدد الأمثلة التي تمت معالجتها ، ومجموع الخسائر لكل دفعة أو لكل مثال ، إلخ.تستدعي TFF طريقة
forward_pass
فيModel
الخاص بك عدة مرات ، بالتتابع على دفعات لاحقة من بيانات العميل ، مما يسمح لك بتحديث المتغيرات التي تحتوي على مجاميع مختلفة كأثر جانبي.أخيرًا ، تستدعي TFF طريقة
report_local_unfinalized_metrics
على نموذجك للسماح لنموذجك بتجميع جميع الإحصائيات الموجزة التي تم جمعها في مجموعة مضغوطة من المقاييس ليتم تصديرها بواسطة العميل. هذا هو المكان الذي قد تقوم فيه شفرة النموذج ، على سبيل المثال ، بتقسيم مجموع الخسائر على عدد الأمثلة التي تمت معالجتها لتصدير متوسط الخسارة ، إلخ.
تجميع متحد . يشير مستوى التجميع هذا إلى التجميع عبر عدة عملاء (أجهزة) في النظام. مرة أخرى ، ينطبق على كل من معلمات النموذج (المتغيرات) ، التي يتم حساب متوسطها عبر العملاء ، بالإضافة إلى المقاييس التي تم تصديرها بواسطة نموذجك كنتيجة للتجميع المحلي.
أداء التجميع على هذا المستوى هو مسؤولية TFF. بصفتك منشئ نموذج ، يمكنك التحكم في هذه العملية (المزيد حول هذا أدناه).
الهيكل العام للمعالجة كما يلي:
يتم توزيع النموذج الأولي ، وأي معلمات مطلوبة للتدريب ، بواسطة الخادم على مجموعة فرعية من العملاء الذين سيشاركون في جولة من التدريب أو التقييم.
على كل عميل ، بشكل مستقل وبالتوازي ، يتم استدعاء رمز النموذج الخاص بك بشكل متكرر على دفق من مجموعات البيانات المحلية لإنتاج مجموعة جديدة من معلمات النموذج (عند التدريب) ، ومجموعة جديدة من المقاييس المحلية ، كما هو موضح أعلاه (هذا محلي تجميع).
يدير TFF بروتوكول تجميع موزع لتجميع وتجميع معلمات النموذج والمقاييس المصدرة محليًا عبر النظام. يتم التعبير عن هذا المنطق بطريقة توضيحية باستخدام لغة الحساب الموحدة الخاصة بـ TFF (ليس في TensorFlow). راجع البرنامج التعليمي للخوارزميات المخصصة لمزيد من المعلومات حول واجهة برمجة تطبيقات التجميع.
واجهات مجردة
يتم تمثيل المُنشئ الأساسي + واجهة البيانات الوصفية بالواجهة tff.learning.models.VariableModel
، على النحو التالي:
يجب أن تنشئ طرق المُنشئ ، و
forward_pass
، وreport_local_unfinalized_metrics
متغيرات النموذج ، وتمرير التوجيه ، والإحصاءات التي ترغب في الإبلاغ عنها ، في المقابل. يجب أن يكون TensorFlow الذي تم إنشاؤه بواسطة هذه الطرق قابلاً للتسلسل ، كما تمت مناقشته أعلاه.تمثل خاصية
input_spec
، بالإضافة إلى الخصائص الثلاث التي تعرض مجموعات فرعية من المتغيرات المحلية القابلة للتدريب وغير القابلة للتدريب والمحلية ، البيانات الوصفية. يستخدم TFF هذه المعلومات لتحديد كيفية توصيل أجزاء من النموذج الخاص بك بخوارزميات التحسين الموحدة ، ولتحديد تواقيع النوع الداخلي للمساعدة في التحقق من صحة النظام المُنشأ (بحيث لا يمكن إنشاء مثيل للنموذج الخاص بك على البيانات التي لا تتطابق مع ما النموذج مصمم للاستهلاك).
بالإضافة إلى ذلك ، تعرض الواجهة المجردة tff.learning.models.VariableModel
خاصية metric_finalizers
التي تأخذ القيم غير النهائية للمقياس (يتم إرجاعها بواسطة report_local_unfinalized_metrics()
) وإرجاع القيم المترية النهائية. سيتم استخدام طريقة metric_finalizers
و report_local_unfinalized_metrics()
معًا لبناء مجمّع مقاييس عبر العملاء عند تحديد عمليات التدريب الموحدة أو حسابات التقييم. على سبيل المثال ، سوف يقوم المجمّع tff.learning.metrics.sum_then_finalize
البسيط بجمع القيم المترية غير النهائية من العملاء أولاً ، ثم استدعاء وظائف finalizer على الخادم.
يمكنك العثور على أمثلة حول كيفية تحديد tff.learning.models.VariableModel
المخصص الخاص بك في الجزء الثاني من البرنامج التعليمي الخاص بتصنيف الصور ، وكذلك في نماذج النماذج التي نستخدمها للاختبار في model_examples.py
.
محولات Keras
يمكن اشتقاق جميع المعلومات المطلوبة تقريبًا بواسطة TFF عن طريق استدعاء واجهات tf.keras
، لذلك إذا كان لديك نموذج Keras ، فيمكنك الاعتماد على tff.learning.models.from_keras_model
لإنشاء نموذج tff.learning.models.VariableModel
.
لاحظ أن TFF لا تزال تريد منك توفير مُنشئ - دالة نموذج بدون وسيطة مثل ما يلي:
def model_fn():
keras_model = ...
return tff.learning.models.from_keras_model(keras_model, sample_batch, loss=...)
بالإضافة إلى النموذج نفسه ، يمكنك توفير دفعة عينة من البيانات التي يستخدمها TFF لتحديد نوع وشكل إدخال النموذج الخاص بك. هذا يضمن أن TFF يمكنه إنشاء مثيل صحيح لنموذج البيانات التي ستكون موجودة بالفعل على أجهزة العميل (نظرًا لأننا نفترض أن هذه البيانات غير متاحة بشكل عام في الوقت الذي تقوم فيه بإنشاء TensorFlow ليتم تحويلها إلى تسلسل).
تم توضيح استخدام أغلفة Keras في برامجنا التعليمية لتصنيف الصور وإنشاء النصوص .
بناة الحساب الموحد
توفر حزمة tff.learning
العديد من البناة لـ tff.Computation
s التي تؤدي مهام متعلقة بالتعلم ؛ نتوقع أن تتوسع مجموعة هذه الحسابات في المستقبل.
الافتراضات المعمارية
تنفيذ
هناك مرحلتان متميزتان في تشغيل حساب موحد.
التحويل البرمجي : يقوم TFF أولاً بتجميع خوارزميات التعلم الموحدة في تمثيل تسلسلي مجردة للحساب الموزع بأكمله. يحدث هذا عند حدوث تسلسل TensorFlow ، ولكن يمكن أن تحدث تحويلات أخرى لدعم التنفيذ الأكثر كفاءة. نشير إلى التمثيل المتسلسل المنبعث من المترجم كحساب موحد .
يوفر تنفيذ TFF طرقًا لتنفيذ هذه الحسابات. في الوقت الحالي ، يتم دعم التنفيذ فقط من خلال محاكاة محلية (على سبيل المثال ، في جهاز كمبيوتر محمول باستخدام محاكاة بيانات لامركزية).
يتضمن الحساب الموحد الذي تم إنشاؤه بواسطة واجهة برمجة تطبيقات التعلم الموحدة الخاصة بـ TFF ، مثل خوارزمية التدريب التي تستخدم متوسط نموذج موحد ، أو تقييم موحد ، عددًا من العناصر ، أبرزها:
نموذج متسلسل من كود النموذج الخاص بك بالإضافة إلى كود TensorFlow الإضافي الذي تم إنشاؤه بواسطة إطار عمل Federated Learning لدفع حلقة التدريب / التقييم الخاصة بنموذجك (مثل إنشاء أدوات تحسين ، وتطبيق تحديثات النموذج ، والتكرار عبر
tf.data.Dataset
s ، ومقاييس الحوسبة ، وتطبيق التحديث المجمع على الخادم ، على سبيل المثال لا الحصر).مواصفات تعريفية للاتصال بين العملاء والخادم (عادةً أشكال مختلفة من التجميع عبر أجهزة العميل ، والبث من الخادم إلى جميع العملاء) ، وكيف يتم تشذير هذا الاتصال الموزع مع تنفيذ العميل المحلي أو الخادم المحلي من كود TensorFlow.
يتم التعبير عن الحسابات الموحدة الممثلة في هذا النموذج المتسلسل بلغة داخلية مستقلة عن النظام الأساسي تختلف عن لغة Python ، ولكن لاستخدام Federated Learning API ، لن تحتاج إلى القلق بشأن تفاصيل هذا التمثيل. يتم تمثيل العمليات الحسابية في كود Python الخاص بك ككائنات من النوع tff.Computation
، والتي في معظمها يمكنك التعامل معها على أنها مبهمة للغة Python callable
.
في البرامج التعليمية ، ستستدعي تلك الحسابات الموحدة كما لو كانت وظائف Python عادية ، ليتم تنفيذها محليًا. ومع ذلك ، تم تصميم TFF للتعبير عن الحسابات الموحدة بطريقة لا تراعي معظم جوانب بيئة التنفيذ ، بحيث يمكن نشرها ، على سبيل المثال ، في مجموعات من الأجهزة التي تعمل Android
، أو إلى مجموعات في مركز بيانات. مرة أخرى ، النتيجة الرئيسية لهذا هي افتراضات قوية حول التسلسل . على وجه الخصوص ، عند استدعاء إحدى طرق build_...
الموضحة أدناه ، يتم إجراء تسلسل كامل للحساب.
حالة النمذجة
TFF هي بيئة برمجة وظيفية ، ومع ذلك فإن العديد من العمليات ذات الأهمية في التعلم الفيدرالي تتسم بالحالة. على سبيل المثال ، حلقة التدريب التي تتضمن جولات متعددة من نموذج الاتحاد المتوسط هي مثال على ما يمكن أن نصنفه على أنه عملية ذات حالة . في هذه العملية ، تتضمن الحالة التي تتطور من جولة إلى أخرى مجموعة معلمات النموذج التي يتم تدريبها ، وربما الحالة الإضافية المرتبطة بالمحسِّن (على سبيل المثال ، ناقل الزخم).
نظرًا لأن TFF وظيفية ، يتم نمذجة العمليات ذات الحالة في TFF كعمليات حسابية تقبل الحالة الحالية كمدخلات ثم توفر الحالة المحدثة كمخرج. من أجل تحديد عملية ذات حالة كاملة ، يحتاج المرء أيضًا إلى تحديد مصدر الحالة الأولية (وإلا لا يمكننا تمهيد العملية). يتم التقاط هذا في تعريف الفئة المساعدة tff.templates.IterativeProcess
، مع initialize
الخاصيتين ثم next
للتهيئة والتكرار ، على التوالي.
البناة المتاحون
At the moment, TFF provides various builder functions that generate federated computations for federated training and evaluation. Two notable examples include:
tff.learning.algorithms.build_weighted_fed_avg
, which takes as input a model function and a client optimizer , and returns a statefultff.learning.templates.LearningProcess
(which subclassestff.templates.IterativeProcess
).tff.learning.build_federated_evaluation
takes a model function and returns a single federated computation for federated evaluation of models, since evaluation is not stateful.
Datasets
Architectural assumptions
Client selection
In the typical federated learning scenario, we have a large population of potentially hundreds of millions of client devices, of which only a small portion may be active and available for training at any given moment (for example, this may be limited to clients that are plugged in to a power source, not on a metered network, and otherwise idle). Generally, the set of clients available to participate in training or evaluation is outside of the developer's control. Furthermore, as it's impractical to coordinate millions of clients, a typical round of training or evaluation will include only a fraction of the available clients, which may be sampled at random .
The key consequence of this is that federated computations, by design, are expressed in a manner that is oblivious to the exact set of participants; all processing is expressed as aggregate operations on an abstract group of anonymous clients , and that group might vary from one round of training to another. The actual binding of the computation to the concrete participants, and thus to the concrete data they feed into the computation, is thus modeled outside of the computation itself.
In order to simulate a realistic deployment of your federated learning code, you will generally write a training loop that looks like this:
trainer = tff.learning.algorithms.build_weighted_fed_avg(...)
state = trainer.initialize()
federated_training_data = ...
def sample(federate_data):
return ...
while True:
data_for_this_round = sample(federated_training_data)
result = trainer.next(state, data_for_this_round)
state = result.state
In order to facilitate this, when using TFF in simulations, federated data is accepted as Python list
s, with one element per participating client device to represent that device's local tf.data.Dataset
.
Abstract interfaces
In order to standardize dealing with simulated federated data sets, TFF provides an abstract interface tff.simulation.datasets.ClientData
, which allows one to enumerate the set of clients, and to construct a tf.data.Dataset
that contains the data of a particular client. Those tf.data.Dataset
s can be fed directly as input to the generated federated computations in eager mode.
It should be noted that the ability to access client identities is a feature that's only provided by the datasets for use in simulations, where the ability to train on data from specific subsets of clients may be needed (eg, to simulate the diurnal availability of different types of clients). The compiled computations and the underlying runtime do not involve any notion of client identity. Once data from a specific subset of clients has been selected as an input, eg, in a call to tff.templates.IterativeProcess.next
, client identities no longer appear in it.
Available data sets
We have dedicated the namespace tff.simulation.datasets
for datasets that implement the tff.simulation.datasets.ClientData
interface for use in simulations, and seeded it with datasets to support the image classification and text generation tutorials. We'd like to encourage you to contribute your own datasets to the platform.
Overview
This document introduces interfaces that facilitate federated learning tasks, such as federated training or evaluation with existing machine learning models implemented in TensorFlow. In designing these interfaces, our primary goal was to make it possible to experiment with federated learning without requiring the knowledge of how it works under the hood, and to evaluate the implemented federated learning algorithms on a variety of existing models and data. We encourage you to contribute back to the platform. TFF has been designed with extensibility and composability in mind, and we welcome contributions; we are excited to see what you come up with!
The interfaces offered by this layer consist of the following three key parts:
Models . Classes and helper functions that allow you to wrap your existing models for use with TFF. Wrapping a model can be as simple as calling a single wrapping function (eg,
tff.learning.models.from_keras_model
), or defining a subclass of thetff.learning.models.VariableModel
interface for full customizability.Federated Computation Builders . Helper functions that construct federated computations for training or evaluation, using your existing models.
Datasets . Canned collections of data that you can download and access in Python for use in simulating federated learning scenarios. Although federated learning is designed for use with decentralized data that cannot be simply downloaded at a centralized location, at the research and development stages it is often convenient to conduct initial experiments using data that can be downloaded and manipulated locally, especially for developers who might be new to the approach.
These interfaces are defined primarily in the tff.learning
namespace, except for research data sets and other simulation-related capabilities that have been grouped in tff.simulation
. This layer is implemented using lower-level interfaces offered by the Federated Core (FC) , which also provides a runtime environment.
Before proceeding, we recommend that you first review the tutorials on image classification and text generation , as they introduce most of the concepts described here using concrete examples. If you're interested in learning more about how TFF works, you may want to skim over the custom algorithms tutorial as an introduction to the lower-level interfaces we use to express the logic of federated computations, and to study the existing implementation of the tff.learning
interfaces.
Models
Architectural assumptions
Serialization
TFF aims at supporting a variety of distributed learning scenarios in which the machine learning model code you write might be executing on a large number of heterogeneous clients with diverse capabilities. While at one end of the spectrum, in some applications those clients might be powerful database servers, many important uses our platform intends to support involve mobile and embedded devices with limited resources. We cannot assume that these devices are capable of hosting Python runtimes; the only thing we can assume at this point is that they are capable of hosting a local TensorFlow runtime. Thus, a fundamental architectural assumption we make in TFF is that your model code must be serializable as a TensorFlow graph.
You can (and should) still develop your TF code following the latest best practices like using eager mode. However, the final code must be serializable (eg, can be wrapped as a tf.function
for eager-mode code). This ensures that any Python state or control flow necessary at execution time can be serialized (possibly with the help of Autograph ).
Currently, TensorFlow does not fully support serializing and deserializing eager-mode TensorFlow. Thus, serialization in TFF currently follows the TF 1.0 pattern, where all code must be constructed inside a tf.Graph
that TFF controls. This means currently TFF cannot consume an already-constructed model; instead, the model definition logic is packaged in a no-arg function that returns a tff.learning.models.VariableModel
. This function is then called by TFF to ensure all components of the model are serialized. In addition, being a strongly-typed environment, TFF will require a little bit of additional metadata , such as a specification of your model's input type.
Aggregation
We strongly recommend most users construct models using Keras, see the Converters for Keras section below. These wrappers handle the aggregation of model updates as well as any metrics defined for the model automatically. However, it may still be useful to understand how aggregation is handled for a general tff.learning.models.VariableModel
.
There are always at least two layers of aggregation in federated learning: local on-device aggregation, and cross-device (or federated) aggregation:
Local aggregation . This level of aggregation refers to aggregation across multiple batches of examples owned by an individual client. It applies to both the model parameters (variables), which continue to sequentially evolve as the model is locally trained, as well as the statistics you compute (such as average loss, accuracy, and other metrics), which your model will again update locally as it iterates over each individual client's local data stream.
Performing aggregation at this level is the responsibility of your model code, and is accomplished using standard TensorFlow constructs.
The general structure of processing is as follows:
The model first constructs
tf.Variable
s to hold aggregates, such as the number of batches or the number of examples processed, the sum of per-batch or per-example losses, etc.TFF invokes the
forward_pass
method on yourModel
multiple times, sequentially over subsequent batches of client data, which allows you to update the variables holding various aggregates as a side effect.Finally, TFF invokes the
report_local_unfinalized_metrics
method on your Model to allow your model to compile all the summary statistics it collected into a compact set of metrics to be exported by the client. This is where your model code may, for example, divide the sum of losses by the number of examples processed to export the average loss, etc.
Federated aggregation . This level of aggregation refers to aggregation across multiple clients (devices) in the system. Again, it applies to both the model parameters (variables), which are being averaged across clients, as well as the metrics your model exported as a result of local aggregation.
Performing aggregation at this level is the responsibility of TFF. As a model creator, however, you can control this process (more on this below).
The general structure of processing is as follows:
The initial model, and any parameters required for training, are distributed by a server to a subset of clients that will participate in a round of training or evaluation.
On each client, independently and in parallel, your model code is invoked repeatedly on a stream of local data batches to produce a new set of model parameters (when training), and a new set of local metrics, as described above (this is local aggregation).
TFF runs a distributed aggregation protocol to accumulate and aggregate the model parameters and locally exported metrics across the system. This logic is expressed in a declarative manner using TFF's own federated computation language (not in TensorFlow). See the custom algorithms tutorial for more on the aggregation API.
Abstract interfaces
This basic constructor + metadata interface is represented by the interface tff.learning.models.VariableModel
, as follows:
The constructor,
forward_pass
, andreport_local_unfinalized_metrics
methods should construct model variables, forward pass, and statistics you wish to report, correspondingly. The TensorFlow constructed by those methods must be serializable, as discussed above.The
input_spec
property, as well as the 3 properties that return subsets of your trainable, non-trainable, and local variables represent the metadata. TFF uses this information to determine how to connect parts of your model to the federated optimization algorithms, and to define internal type signatures to assist in verifying the correctness of the constructed system (so that your model cannot be instantiated over data that does not match what the model is designed to consume).
In addition, the abstract interface tff.learning.models.VariableModel
exposes a property metric_finalizers
that takes in a metric's unfinalized values (returned by report_local_unfinalized_metrics()
) and returns the finalized metric values. The metric_finalizers
and report_local_unfinalized_metrics()
method will be used together to build a cross-client metrics aggregator when defining the federated training processes or evaluation computations. For example, a simple tff.learning.metrics.sum_then_finalize
aggregator will first sum the unfinalized metric values from clients, and then call the finalizer functions at the server.
You can find examples of how to define your own custom tff.learning.models.VariableModel
in the second part of our image classification tutorial, as well as in the example models we use for testing in model_examples.py
.
Converters for Keras
Nearly all the information that's required by TFF can be derived by calling tf.keras
interfaces, so if you have a Keras model, you can rely on tff.learning.models.from_keras_model
to construct a tff.learning.models.VariableModel
.
Note that TFF still wants you to provide a constructor - a no-argument model function such as the following:
def model_fn():
keras_model = ...
return tff.learning.models.from_keras_model(keras_model, sample_batch, loss=...)
In addition to the model itself, you supply a sample batch of data which TFF uses to determine the type and shape of your model's input. This ensures that TFF can properly instantiate the model for the data that will actually be present on client devices (since we assume this data is not generally available at the time you are constructing the TensorFlow to be serialized).
The use of Keras wrappers is illustrated in our image classification and text generation tutorials.
Federated Computation Builders
The tff.learning
package provides several builders for tff.Computation
s that perform learning-related tasks; we expect the set of such computations to expand in the future.
Architectural assumptions
Execution
There are two distinct phases in running a federated computation.
Compile : TFF first compiles federated learning algorithms into an abstract serialized representation of the entire distributed computation. This is when TensorFlow serialization happens, but other transformations can occur to support more efficient execution. We refer to the serialized representation emitted by the compiler as a federated computation .
Execute TFF provides ways to execute these computations. For now, execution is only supported via a local simulation (eg, in a notebook using simulated decentralized data).
A federated computation generated by TFF's Federated Learning API, such as a training algorithm that uses federated model averaging , or a federated evaluation, includes a number of elements, most notably:
A serialized form of your model code as well as additional TensorFlow code constructed by the Federated Learning framework to drive your model's training/evaluation loop (such as constructing optimizers, applying model updates, iterating over
tf.data.Dataset
s, and computing metrics, and applying the aggregated update on the server, to name a few).A declarative specification of the communication between the clients and a server (typically various forms of aggregation across the client devices, and broadcasting from the server to all clients), and how this distributed communication is interleaved with the client-local or server-local execution of TensorFlow code.
The federated computations represented in this serialized form are expressed in a platform-independent internal language distinct from Python, but to use the Federated Learning API, you won't need to concern yourself with the details of this representation. The computations are represented in your Python code as objects of type tff.Computation
, which for the most part you can treat as opaque Python callable
s.
In the tutorials, you will invoke those federated computations as if they were regular Python functions, to be executed locally. However, TFF is designed to express federated computations in a manner agnostic to most aspects of the execution environment, so that they can potentially be deployable to, eg, groups of devices running Android
, or to clusters in a datacenter. Again, the main consequence of this are strong assumptions about serialization . In particular, when you invoke one of the build_...
methods described below the computation is fully serialized.
Modeling state
TFF is a functional programming environment, yet many processes of interest in federated learning are stateful. For example, a training loop that involves multiple rounds of federated model averaging is an example of what we could classify as a stateful process . In this process, the state that evolves from round to round includes the set of model parameters that are being trained, and possibly additional state associated with the optimizer (eg, a momentum vector).
Since TFF is functional, stateful processes are modeled in TFF as computations that accept the current state as an input and then provide the updated state as an output. In order to fully define a stateful process, one also needs to specify where the initial state comes from (otherwise we cannot bootstrap the process). This is captured in the definition of the helper class tff.templates.IterativeProcess
, with the 2 properties initialize
and next
corresponding to the initialization and iteration, respectively.
Available builders
At the moment, TFF provides various builder functions that generate federated computations for federated training and evaluation. Two notable examples include:
tff.learning.algorithms.build_weighted_fed_avg
, which takes as input a model function and a client optimizer , and returns a statefultff.learning.templates.LearningProcess
(which subclassestff.templates.IterativeProcess
).tff.learning.build_federated_evaluation
takes a model function and returns a single federated computation for federated evaluation of models, since evaluation is not stateful.
Datasets
Architectural assumptions
Client selection
In the typical federated learning scenario, we have a large population of potentially hundreds of millions of client devices, of which only a small portion may be active and available for training at any given moment (for example, this may be limited to clients that are plugged in to a power source, not on a metered network, and otherwise idle). Generally, the set of clients available to participate in training or evaluation is outside of the developer's control. Furthermore, as it's impractical to coordinate millions of clients, a typical round of training or evaluation will include only a fraction of the available clients, which may be sampled at random .
The key consequence of this is that federated computations, by design, are expressed in a manner that is oblivious to the exact set of participants; all processing is expressed as aggregate operations on an abstract group of anonymous clients , and that group might vary from one round of training to another. The actual binding of the computation to the concrete participants, and thus to the concrete data they feed into the computation, is thus modeled outside of the computation itself.
In order to simulate a realistic deployment of your federated learning code, you will generally write a training loop that looks like this:
trainer = tff.learning.algorithms.build_weighted_fed_avg(...)
state = trainer.initialize()
federated_training_data = ...
def sample(federate_data):
return ...
while True:
data_for_this_round = sample(federated_training_data)
result = trainer.next(state, data_for_this_round)
state = result.state
In order to facilitate this, when using TFF in simulations, federated data is accepted as Python list
s, with one element per participating client device to represent that device's local tf.data.Dataset
.
Abstract interfaces
In order to standardize dealing with simulated federated data sets, TFF provides an abstract interface tff.simulation.datasets.ClientData
, which allows one to enumerate the set of clients, and to construct a tf.data.Dataset
that contains the data of a particular client. Those tf.data.Dataset
s can be fed directly as input to the generated federated computations in eager mode.
It should be noted that the ability to access client identities is a feature that's only provided by the datasets for use in simulations, where the ability to train on data from specific subsets of clients may be needed (eg, to simulate the diurnal availability of different types of clients). The compiled computations and the underlying runtime do not involve any notion of client identity. Once data from a specific subset of clients has been selected as an input, eg, in a call to tff.templates.IterativeProcess.next
, client identities no longer appear in it.
Available data sets
We have dedicated the namespace tff.simulation.datasets
for datasets that implement the tff.simulation.datasets.ClientData
interface for use in simulations, and seeded it with datasets to support the image classification and text generation tutorials. We'd like to encourage you to contribute your own datasets to the platform.
Overview
This document introduces interfaces that facilitate federated learning tasks, such as federated training or evaluation with existing machine learning models implemented in TensorFlow. In designing these interfaces, our primary goal was to make it possible to experiment with federated learning without requiring the knowledge of how it works under the hood, and to evaluate the implemented federated learning algorithms on a variety of existing models and data. We encourage you to contribute back to the platform. TFF has been designed with extensibility and composability in mind, and we welcome contributions; we are excited to see what you come up with!
The interfaces offered by this layer consist of the following three key parts:
Models . Classes and helper functions that allow you to wrap your existing models for use with TFF. Wrapping a model can be as simple as calling a single wrapping function (eg,
tff.learning.models.from_keras_model
), or defining a subclass of thetff.learning.models.VariableModel
interface for full customizability.Federated Computation Builders . Helper functions that construct federated computations for training or evaluation, using your existing models.
Datasets . Canned collections of data that you can download and access in Python for use in simulating federated learning scenarios. Although federated learning is designed for use with decentralized data that cannot be simply downloaded at a centralized location, at the research and development stages it is often convenient to conduct initial experiments using data that can be downloaded and manipulated locally, especially for developers who might be new to the approach.
These interfaces are defined primarily in the tff.learning
namespace, except for research data sets and other simulation-related capabilities that have been grouped in tff.simulation
. This layer is implemented using lower-level interfaces offered by the Federated Core (FC) , which also provides a runtime environment.
Before proceeding, we recommend that you first review the tutorials on image classification and text generation , as they introduce most of the concepts described here using concrete examples. If you're interested in learning more about how TFF works, you may want to skim over the custom algorithms tutorial as an introduction to the lower-level interfaces we use to express the logic of federated computations, and to study the existing implementation of the tff.learning
interfaces.
Models
Architectural assumptions
Serialization
TFF aims at supporting a variety of distributed learning scenarios in which the machine learning model code you write might be executing on a large number of heterogeneous clients with diverse capabilities. While at one end of the spectrum, in some applications those clients might be powerful database servers, many important uses our platform intends to support involve mobile and embedded devices with limited resources. We cannot assume that these devices are capable of hosting Python runtimes; the only thing we can assume at this point is that they are capable of hosting a local TensorFlow runtime. Thus, a fundamental architectural assumption we make in TFF is that your model code must be serializable as a TensorFlow graph.
You can (and should) still develop your TF code following the latest best practices like using eager mode. However, the final code must be serializable (eg, can be wrapped as a tf.function
for eager-mode code). This ensures that any Python state or control flow necessary at execution time can be serialized (possibly with the help of Autograph ).
Currently, TensorFlow does not fully support serializing and deserializing eager-mode TensorFlow. Thus, serialization in TFF currently follows the TF 1.0 pattern, where all code must be constructed inside a tf.Graph
that TFF controls. This means currently TFF cannot consume an already-constructed model; instead, the model definition logic is packaged in a no-arg function that returns a tff.learning.models.VariableModel
. This function is then called by TFF to ensure all components of the model are serialized. In addition, being a strongly-typed environment, TFF will require a little bit of additional metadata , such as a specification of your model's input type.
Aggregation
We strongly recommend most users construct models using Keras, see the Converters for Keras section below. These wrappers handle the aggregation of model updates as well as any metrics defined for the model automatically. However, it may still be useful to understand how aggregation is handled for a general tff.learning.models.VariableModel
.
There are always at least two layers of aggregation in federated learning: local on-device aggregation, and cross-device (or federated) aggregation:
Local aggregation . This level of aggregation refers to aggregation across multiple batches of examples owned by an individual client. It applies to both the model parameters (variables), which continue to sequentially evolve as the model is locally trained, as well as the statistics you compute (such as average loss, accuracy, and other metrics), which your model will again update locally as it iterates over each individual client's local data stream.
Performing aggregation at this level is the responsibility of your model code, and is accomplished using standard TensorFlow constructs.
The general structure of processing is as follows:
The model first constructs
tf.Variable
s to hold aggregates, such as the number of batches or the number of examples processed, the sum of per-batch or per-example losses, etc.TFF invokes the
forward_pass
method on yourModel
multiple times, sequentially over subsequent batches of client data, which allows you to update the variables holding various aggregates as a side effect.Finally, TFF invokes the
report_local_unfinalized_metrics
method on your Model to allow your model to compile all the summary statistics it collected into a compact set of metrics to be exported by the client. This is where your model code may, for example, divide the sum of losses by the number of examples processed to export the average loss, etc.
Federated aggregation . This level of aggregation refers to aggregation across multiple clients (devices) in the system. Again, it applies to both the model parameters (variables), which are being averaged across clients, as well as the metrics your model exported as a result of local aggregation.
Performing aggregation at this level is the responsibility of TFF. As a model creator, however, you can control this process (more on this below).
The general structure of processing is as follows:
The initial model, and any parameters required for training, are distributed by a server to a subset of clients that will participate in a round of training or evaluation.
On each client, independently and in parallel, your model code is invoked repeatedly on a stream of local data batches to produce a new set of model parameters (when training), and a new set of local metrics, as described above (this is local aggregation).
TFF runs a distributed aggregation protocol to accumulate and aggregate the model parameters and locally exported metrics across the system. This logic is expressed in a declarative manner using TFF's own federated computation language (not in TensorFlow). See the custom algorithms tutorial for more on the aggregation API.
Abstract interfaces
This basic constructor + metadata interface is represented by the interface tff.learning.models.VariableModel
, as follows:
The constructor,
forward_pass
, andreport_local_unfinalized_metrics
methods should construct model variables, forward pass, and statistics you wish to report, correspondingly. The TensorFlow constructed by those methods must be serializable, as discussed above.The
input_spec
property, as well as the 3 properties that return subsets of your trainable, non-trainable, and local variables represent the metadata. TFF uses this information to determine how to connect parts of your model to the federated optimization algorithms, and to define internal type signatures to assist in verifying the correctness of the constructed system (so that your model cannot be instantiated over data that does not match what the model is designed to consume).
In addition, the abstract interface tff.learning.models.VariableModel
exposes a property metric_finalizers
that takes in a metric's unfinalized values (returned by report_local_unfinalized_metrics()
) and returns the finalized metric values. The metric_finalizers
and report_local_unfinalized_metrics()
method will be used together to build a cross-client metrics aggregator when defining the federated training processes or evaluation computations. For example, a simple tff.learning.metrics.sum_then_finalize
aggregator will first sum the unfinalized metric values from clients, and then call the finalizer functions at the server.
You can find examples of how to define your own custom tff.learning.models.VariableModel
in the second part of our image classification tutorial, as well as in the example models we use for testing in model_examples.py
.
Converters for Keras
Nearly all the information that's required by TFF can be derived by calling tf.keras
interfaces, so if you have a Keras model, you can rely on tff.learning.models.from_keras_model
to construct a tff.learning.models.VariableModel
.
Note that TFF still wants you to provide a constructor - a no-argument model function such as the following:
def model_fn():
keras_model = ...
return tff.learning.models.from_keras_model(keras_model, sample_batch, loss=...)
In addition to the model itself, you supply a sample batch of data which TFF uses to determine the type and shape of your model's input. This ensures that TFF can properly instantiate the model for the data that will actually be present on client devices (since we assume this data is not generally available at the time you are constructing the TensorFlow to be serialized).
The use of Keras wrappers is illustrated in our image classification and text generation tutorials.
Federated Computation Builders
The tff.learning
package provides several builders for tff.Computation
s that perform learning-related tasks; we expect the set of such computations to expand in the future.
Architectural assumptions
Execution
There are two distinct phases in running a federated computation.
Compile : TFF first compiles federated learning algorithms into an abstract serialized representation of the entire distributed computation. This is when TensorFlow serialization happens, but other transformations can occur to support more efficient execution. We refer to the serialized representation emitted by the compiler as a federated computation .
Execute TFF provides ways to execute these computations. For now, execution is only supported via a local simulation (eg, in a notebook using simulated decentralized data).
A federated computation generated by TFF's Federated Learning API, such as a training algorithm that uses federated model averaging , or a federated evaluation, includes a number of elements, most notably:
A serialized form of your model code as well as additional TensorFlow code constructed by the Federated Learning framework to drive your model's training/evaluation loop (such as constructing optimizers, applying model updates, iterating over
tf.data.Dataset
s, and computing metrics, and applying the aggregated update on the server, to name a few).A declarative specification of the communication between the clients and a server (typically various forms of aggregation across the client devices, and broadcasting from the server to all clients), and how this distributed communication is interleaved with the client-local or server-local execution of TensorFlow code.
The federated computations represented in this serialized form are expressed in a platform-independent internal language distinct from Python, but to use the Federated Learning API, you won't need to concern yourself with the details of this representation. The computations are represented in your Python code as objects of type tff.Computation
, which for the most part you can treat as opaque Python callable
s.
In the tutorials, you will invoke those federated computations as if they were regular Python functions, to be executed locally. However, TFF is designed to express federated computations in a manner agnostic to most aspects of the execution environment, so that they can potentially be deployable to, eg, groups of devices running Android
, or to clusters in a datacenter. Again, the main consequence of this are strong assumptions about serialization . In particular, when you invoke one of the build_...
methods described below the computation is fully serialized.
Modeling state
TFF is a functional programming environment, yet many processes of interest in federated learning are stateful. For example, a training loop that involves multiple rounds of federated model averaging is an example of what we could classify as a stateful process . In this process, the state that evolves from round to round includes the set of model parameters that are being trained, and possibly additional state associated with the optimizer (eg, a momentum vector).
Since TFF is functional, stateful processes are modeled in TFF as computations that accept the current state as an input and then provide the updated state as an output. In order to fully define a stateful process, one also needs to specify where the initial state comes from (otherwise we cannot bootstrap the process). This is captured in the definition of the helper class tff.templates.IterativeProcess
, with the 2 properties initialize
and next
corresponding to the initialization and iteration, respectively.
Available builders
At the moment, TFF provides various builder functions that generate federated computations for federated training and evaluation. Two notable examples include:
tff.learning.algorithms.build_weighted_fed_avg
, which takes as input a model function and a client optimizer , and returns a statefultff.learning.templates.LearningProcess
(which subclassestff.templates.IterativeProcess
).tff.learning.build_federated_evaluation
takes a model function and returns a single federated computation for federated evaluation of models, since evaluation is not stateful.
Datasets
Architectural assumptions
Client selection
In the typical federated learning scenario, we have a large population of potentially hundreds of millions of client devices, of which only a small portion may be active and available for training at any given moment (for example, this may be limited to clients that are plugged in to a power source, not on a metered network, and otherwise idle). Generally, the set of clients available to participate in training or evaluation is outside of the developer's control. Furthermore, as it's impractical to coordinate millions of clients, a typical round of training or evaluation will include only a fraction of the available clients, which may be sampled at random .
The key consequence of this is that federated computations, by design, are expressed in a manner that is oblivious to the exact set of participants; all processing is expressed as aggregate operations on an abstract group of anonymous clients , and that group might vary from one round of training to another. The actual binding of the computation to the concrete participants, and thus to the concrete data they feed into the computation, is thus modeled outside of the computation itself.
In order to simulate a realistic deployment of your federated learning code, you will generally write a training loop that looks like this:
trainer = tff.learning.algorithms.build_weighted_fed_avg(...)
state = trainer.initialize()
federated_training_data = ...
def sample(federate_data):
return ...
while True:
data_for_this_round = sample(federated_training_data)
result = trainer.next(state, data_for_this_round)
state = result.state
In order to facilitate this, when using TFF in simulations, federated data is accepted as Python list
s, with one element per participating client device to represent that device's local tf.data.Dataset
.
Abstract interfaces
In order to standardize dealing with simulated federated data sets, TFF provides an abstract interface tff.simulation.datasets.ClientData
, which allows one to enumerate the set of clients, and to construct a tf.data.Dataset
that contains the data of a particular client. Those tf.data.Dataset
s can be fed directly as input to the generated federated computations in eager mode.
It should be noted that the ability to access client identities is a feature that's only provided by the datasets for use in simulations, where the ability to train on data from specific subsets of clients may be needed (eg, to simulate the diurnal availability of different types of clients). The compiled computations and the underlying runtime do not involve any notion of client identity. Once data from a specific subset of clients has been selected as an input, eg, in a call to tff.templates.IterativeProcess.next
, client identities no longer appear in it.
Available data sets
We have dedicated the namespace tff.simulation.datasets
for datasets that implement the tff.simulation.datasets.ClientData
interface for use in simulations, and seeded it with datasets to support the image classification and text generation tutorials. We'd like to encourage you to contribute your own datasets to the platform.