الگوریتم های سفارشی فدراسیون ، قسمت 1: مقدمه ای بر هسته فدراسیون

مشاهده در TensorFlow.org در Google Colab اجرا کنید مشاهده منبع در GitHub دانلود دفترچه یادداشت

این آموزش قسمت اول از یک سری دو قسمتی که نشان می دهد که چگونه برای اجرای انواع سفارشی از الگوریتم های فدرال در TensorFlow فدرال (TFF) با استفاده از است فدرال هسته (FC) - مجموعه ای از رابط های سطح پایین تر که به عنوان یک پایه و اساس خدمت که بر اساس آن ما را اجرا کرده اند فدرال آموزش (FL) لایه.

این قسمت اول بیشتر مفهومی است. ما برخی از مفاهیم کلیدی و چکیده برنامه نویسی مورد استفاده در TFF را معرفی می کنیم و استفاده از آنها را در یک مثال بسیار ساده با مجموعه ای از حسگرهای دما توزیع شده نشان می دهیم. در بخش دوم از این سری ، ما با استفاده از مکانیزم معرفی می کنیم در اینجا به پیاده سازی یک نسخه ساده از آموزش و ارزیابی الگوریتم های فدرال. به عنوان یک پیگیری، ما شما را تشویق به مطالعه اجرای از میانگین فدرال در tff.learning .

در پایان این سری ، باید بتوانید تشخیص دهید که برنامه های کاربردی Federated Core لزوماً محدود به یادگیری نیست. چکیده برنامه نویسی که ما ارائه می دهیم کاملاً کلی است و می تواند مورد استفاده قرار گیرد ، به عنوان مثال ، برای پیاده سازی تجزیه و تحلیل و سایر انواع محاسبات سفارشی بر روی داده های توزیع شده.

اگر چه این آموزش طراحی شده است که خود شامل، ما شما را تشویق به آموزش خواندن برای اولین بار در طبقه بندی تصویر و متن برای یک سطح بالاتر و معرفی ملایم تر به چارچوب TensorFlow فدرال و فدرال آموزش رابط های برنامه کاربردی ( tff.learning )، به عنوان این به شما کمک می کند مفاهیمی را که در اینجا شرح می دهیم در چهارچوب قرار دهید.

موارد استفاده

به طور خلاصه، فدرال هسته (FC) یک محیط توسعه است که این امکان را به طور فشرده بیان منطق برنامه باعث می شود این است که کد ترکیب TensorFlow با اپراتورهای توزیع ارتباطی مانند کسانی که در استفاده به طور متوسط فدرال - محاسبه مبالغ توزیع شده، به طور متوسط، و انواع دیگر مجموعه های توزیع شده بر روی مجموعه ای از دستگاه های سرویس گیرنده در سیستم ، پخش مدل ها و پارامترها به آن دستگاه ها و غیره.

شما ممکن است از آن آگاه tf.contrib.distribute ، و یک سوال طبیعی به درخواست در این نقطه ممکن است: در چه راه هایی این چارچوب متفاوت است؟ به هر حال ، هر دو چارچوب سعی می کنند محاسبات TensorFlow را توزیع کنند.

یکی از راه های در مورد آن فکر می کنم این است که، در حالی که هدف اعلام شده از tf.contrib.distribute است به کاربران اجازه استفاده از مدل های موجود و کد آموزش با کمترین تغییرات را قادر می سازد آموزش توزیع شده، و تمرکز زیادی است در مورد چگونگی استفاده از زیرساخت های توزیع برای کارآمدتر کردن کد آموزشی موجود ، هدف TFF's Federated Core این است که به محققان و پزشکان کنترلی صریح بر الگوهای خاص ارتباطات توزیعی که در سیستم های خود استفاده خواهند کرد ، بدهد. تمرکز FC بر ارائه یک زبان انعطاف پذیر و قابل توسعه برای بیان الگوریتم های جریان داده توزیع شده است ، نه مجموعه ای مشخص از قابلیت های آموزشی توزیع شده.

یکی از مخاطبین اصلی برای API FC TFF ، محققان و پزشکانی هستند که ممکن است بخواهند با الگوریتم های جدید یادگیری متحد آزمایش کرده و پیامدهای انتخاب های ظریف طراحی را که بر نحوه تنظیم جریان داده ها در سیستم توزیع شده تأثیر می گذارد ، ارزیابی کنند. بدون درگیر شدن با جزئیات پیاده سازی سیستم. سطح انتزاعی که FC API در نظر دارد تقریباً منطبق با شبه کد است که می توان از آن برای توصیف مکانیک الگوریتم یادگیری متحد در یک نشریه تحقیقاتی استفاده کرد - چه داده هایی در سیستم وجود دارد و چگونه تغییر می کند ، اما بدون کاهش به سطح تبادل پیام های شبکه ای نقطه به نقطه

TFF به طور کلی سناریوهایی را که داده ها در آن توزیع می شوند ، هدف قرار می دهد و باید به همین دلیل باقی بماند ، به عنوان مثال ، به دلایل حفظ حریم خصوصی ، و در جایی که جمع آوری تمام داده ها در یک مکان متمرکز ممکن است یک گزینه مناسب نباشد. این امر بر پیاده سازی الگوریتم های یادگیری ماشین که نیاز به درجه کنترل بیشتری دارد ، در مقایسه با سناریوهایی که در آن همه داده ها را می توان در یک مکان متمرکز در مرکز داده جمع آوری کرد ، تأثیر دارد.

قبل از اینکه شروع کنیم

لطفاً قبل از وارد شدن به کد ، سعی کنید مثال "Hello World" زیر را اجرا کنید تا مطمئن شوید محیط شما به درستی تنظیم شده است. اگر آن کار نمی کند، لطفا به مراجعه نصب و راه اندازی راهنمای دستورالعمل.

!pip install --quiet --upgrade tensorflow-federated-nightly
!pip install --quiet --upgrade nest-asyncio

import nest_asyncio
nest_asyncio.apply()
import collections

import numpy as np
import tensorflow as tf
import tensorflow_federated as tff
@tff.federated_computation
def hello_world():
  return 'Hello, World!'

hello_world()
b'Hello, World!'

داده های فدرال

یکی از ویژگی های متمایز TFF است که اجازه می دهد شما را به طور فشرده بیان محاسبات بر اساس TensorFlow-بر روی داده های فدرال. ما خواهد بود با استفاده از داده های فدرال مدت در این آموزش برای اشاره به یک مجموعه ای از داده در سراسر یک گروه از دستگاه میزبان در یک سیستم توزیع شده است. به عنوان مثال ، برنامه های کاربردی روی دستگاه های تلفن همراه ممکن است داده ها را جمع آوری کرده و به صورت محلی ذخیره کنند ، بدون بارگذاری در یک مکان متمرکز. یا ، مجموعه ای از سنسورهای توزیع شده ممکن است اندازه گیری های دما را در محل خود جمع آوری و ذخیره کند.

اطلاعات فدرال مانند کسانی که در مثال بالا در TFF به عنوان درمان شهروندان درجه اول ، به عنوان مثال، آنها ممکن است به عنوان پارامترها و نتایج حاصل از توابع به نظر می رسد، و آنها را از انواع. برای تقویت این مفهوم، ما به مجموعه داده های فدرال به عنوان ارزش های فدرال، و یا به عنوان ارزش از انواع فدرال مراجعه کنید.

نکته مهمی که باید درک شود این است که ما کل مجموعه موارد داده را در همه دستگاه ها (به عنوان مثال ، کل خواندن دمای مجموعه از همه سنسورها در یک آرایه توزیع شده) را به عنوان یک مقدار واحد مدلسازی می کنیم.

به عنوان مثال، در اینجا نحوه کس در TFF تعریف نوع شناور فدرال که توسط گروهی از دستگاه های مشتری. مجموعه ای از قرائت های دما که در مجموعه ای از سنسورهای توزیع شده به چشم می خورد را می توان به عنوان مقداری از این نوع فدرال مدل کرد.

federated_float_on_clients = tff.type_at_clients(tf.float32)

به طور کلی، یک نوع فدرال در TFF با مشخص نوع تعریف T از ترکیبات عضو آن - مورد از داده ها که اقامت به دستگاه های فردی، و گروه G دستگاههایی که ارزش فدرال از این نوع میزبانی (به علاوه یک سوم، کمی اطلاعات اختیاری که به زودی ذکر می کنیم). ما به گروه مراجعه G از دستگاه های میزبانی یک ارزش فدرال به عنوان قرار دادن ارزش است. بنابراین، tff.CLIENTS یک مثال از یک قرار دادن است.

str(federated_float_on_clients.member)
'float32'
str(federated_float_on_clients.placement)
'CLIENTS'

یک نوع فدرال با حوزه های عضو T و قرار دادن G می تواند نشان فشرده به عنوان {T}@G ، به عنوان زیر نشان داده شده.

str(federated_float_on_clients)
'{float32}@CLIENTS'

آکولاد {} در این مختصر نماد به عنوان یک یادآوری خدمت که اجزای عضو (مورد از داده ها در دستگاه های مختلف) ممکن است متفاوت باشد، به عنوان شما انتظار می رود به عنوان مثال، قرائت سنسور درجه حرارت، تا مشتریان به عنوان یک گروه به طور مشترک میزبانی یک چند تنظیم از T آیتم هایی که با هم ارزش فدرال را تشکیل می دهند -typed.

آن را به توجه داشته باشید مهم است که ترکیبات عضو یک ارزش فدرال به طور کلی به برنامه نویس مات، به عنوان مثال، یک مقدار فدرال باید به عنوان یک ساده تصور نشود dict کوک شده با یک شناسه از یک دستگاه در سیستم - این مقادیر در نظر گرفته شده توان در مجموع تنها توسط اپراتورهای فدرال که انتزاعی نشان دهنده انواع مختلف از پروتکل های ارتباطی توزیع شده (مانند دانه) تبدیل شده است. اگر این امر بیش از حد انتزاعی به نظر می رسد ، نگران نباشید - ما به زودی به این موضوع باز می گردیم و آن را با مثالهای مشخص نشان می دهیم.

انواع فدراسیون شده در TFF دارای دو طعم هستند: انواع که در آن اعضای تشکیل دهنده ارزش فدراسیون ممکن است متفاوت باشند (همانطور که در بالا مشاهده شد) ، و آنهایی که همه آنها برابر شناخته شده اند. این است که با سوم، اختیاری کنترل all_equal پارامتر در tff.FederatedType سازنده (متخلف به False ).

federated_float_on_clients.all_equal
False

یک نوع فدرال با قرار دادن G که در آن همه از T -typed ترکیبات عضو هستند شناخته شده به مساوی را می توان فشرده به عنوان نمایندگی T@G (به عنوان مخالف {T}@G ، این است که، با آکولاد کاهش یافته است تا منعکس کننده این واقعیت که مجموعه های چندگانه اعضای تشکیل دهنده از یک مورد واحد تشکیل شده است).

str(tff.type_at_clients(tf.float32, all_equal=True))
'float32@CLIENTS'

یک مثال از ارزش فدرال شده از این نوع که ممکن است در سناریوهای عملی بوجود بیاید ، یک پارامتر فوق العاده (مانند میزان یادگیری ، یک استاندارد قطع و غیره) است که توسط یک سرور روی گروهی از دستگاه هایی که در آموزش های فدراسیون شرکت می کنند پخش شده است.

مثال دیگر مجموعه ای از پارامترها برای مدل یادگیری ماشین است که از قبل در سرور آموزش دیده است ، و سپس برای گروهی از دستگاه های سرویس گیرنده پخش می شود ، که می تواند برای هر کاربر شخصی سازی شود.

به عنوان مثال، فرض کنید ما یک جفت از float32 پارامترهای و a b برای یک مدل رگرسیون خطی یک بعدی ساده. ما می توانیم نوع (غیر فدراسیون) چنین مدلهایی را برای استفاده در TFF به شرح زیر بسازیم. ابروها زاویه <> در نوع رشته چاپ شده است یک نماد TFF جمع و جور برای تاپل نام و یا نامش ذکر نشده.

simple_regression_model_type = (
    tff.StructType([('a', tf.float32), ('b', tf.float32)]))

str(simple_regression_model_type)
'<a=float32,b=float32>'

توجه داشته باشید که ما فقط تعیین dtype بازدید کنندگان بالا. انواع غیر اسکالر نیز پشتیبانی می شوند. در کد بالا، tf.float32 است یک نماد میانبر برای کلی تر tff.TensorType(dtype=tf.float32, shape=[]) .

وقتی این مدل برای کلاینت ها پخش می شود ، نوع مقدار فدراسیون حاصل می تواند مطابق شکل زیر نشان داده شود.

str(tff.type_at_clients(
    simple_regression_model_type, all_equal=True))
'<a=float32,b=float32>@CLIENTS'

میانگین پستها در طول تقارن با شناور فدرال فوق، ما به این نوع A به عنوان یک تاپل فدرال مراجعه کنید. به طور کلی، ما اغلب برای اشاره به یک ارزش فدرال که اجزاء عضو XYZ مانند استفاده از XYZ فدرال مدت. بنابراین، ما در مورد چیزهایی مثل تاپل فدرال، توالی فدرال، مدل های فدرال، و غیره صحبت کنید.

در حال حاضر، آینده را به float32@CLIENTS - در حالی که به نظر می رسد تکرار سراسر دستگاه های متعدد، آن است که در واقع یک float32 ، از همه اعضای آن یکسان است. به طور کلی، شما ممکن است از هر نوع فدرال همه برابر یعنی فکر می کنم، یکی از فرم T@G به یک نوع غیر فدرال، به عنوان ریخت T ، چرا که در هر دو مورد، در واقع وجود دارد تنها یک (البته به طور بالقوه تکرار) مورد از نوع T .

با توجه به ریخت بین T و T@G ، شما ممکن است چه هدفی، در صورت وجود، در حالت دوم ممکن است خدمت می کنند. ادامه مطلب را بخوانید.

مکان ها

نمای کلی طراحی

در بخش قبل، ما مفهوم از دادن معرفی کرده ایم - گروه از شرکت کنندگان سیستم که ممکن است به طور مشترک میزبانی ارزش فدرال، و ما استفاده از نشان داده ایم tff.CLIENTS به عنوان مثال مشخصات یک قرار دادن.

برای توضیح دهد که چرا مفهوم قرار دادن چنین بنیادی است که ما نیاز به آن ترکیب را به سیستم نوع TFF است، به یاد آنچه که ما در ابتدای این آموزش در مورد برخی از کاربردهای مورد نظر از TFF ذکر شده است.

اگرچه در این آموزش ، شما فقط مشاهده می کنید که کد TFF به صورت محلی در یک محیط شبیه سازی شده اجرا می شود ، اما هدف ما این است که TFF نوشتن کدی را که می توانید برای اجرا در گروه های دستگاه های فیزیکی در یک سیستم توزیع شده ، به طور بالقوه شامل دستگاه های تلفن همراه یا جاسازی شده ، به کار گیرد ، فعال کند. اجرای اندروید هر یک از این دستگاه ها بسته به نقشی که در سیستم ایفا می کند (برای دستگاه نهایی کاربر ، هماهنگ کننده متمرکز ، لایه میانی در معماری چند لایه و غیره) مجموعه ای از دستورالعمل های جداگانه را برای اجرای محلی دریافت می کند. این مهم است که بتوانیم استدلال کنیم که کدام زیر مجموعه از دستگاه ها چه کدی را اجرا می کنند و قسمتهای مختلف داده از کجا ممکن است به صورت فیزیکی تحقق پیدا کنند.

این امر به ویژه هنگام سروکار داشتن با داده های برنامه در دستگاه های تلفن همراه بسیار مهم است. از آنجایی که داده ها خصوصی هستند و می توانند حساس باشند ، ما نیاز به این توانایی را داریم که به طور ایستا تأیید کنیم که این داده ها هرگز از دستگاه خارج نمی شوند (و حقایقی را در مورد نحوه پردازش داده ها ثابت کنیم). مشخصات مکان یابی یکی از مکانیزم هایی است که برای حمایت از آن طراحی شده است.

TFF به عنوان یک محیط برنامه نویسی داده محور طراحی شده است، و به عنوان مثل، بر خلاف برخی از چارچوب های موجود که تمرکز بر عملیات و که در آن این عملیات ممکن است اجرا، TFF در داده ها، که در آن است که تحقق داده، و چگونه آن را در حال تبدیل متمرکز است. در نتیجه ، مکان یابی به عنوان یک ویژگی داده در TFF مدل می شود ، نه یک ویژگی عملیات روی داده ها. در واقع ، همانطور که در بخش بعدی مشاهده خواهید کرد ، برخی از عملیات TFF در نقاط مختلف گسترده شده و به اصطلاح "در شبکه" اجرا می شوند ، نه اینکه توسط یک دستگاه یا گروهی از ماشین ها اجرا شوند.

به نمایندگی از نوع یک مقدار مشخص به عنوان T@G یا {T}@G (به عنوان تنها مخالف T با تجزیه و تحلیل استاتیک برنامههای نوشته شده در TFF) تصمیم گیری می کند قرار دادن داده صریح و روشن، و با هم، می تواند به عنوان یک پایه برای ارائه خدمت تضمین حریم خصوصی رسمی برای داده های حساس روی دستگاه.

نکته مهم توجه داشته باشید در این نقطه، این است که در حالی که ما کاربران TFF تشویق به صراحت گروه از دستگاه های شرکت که میزبان داده (دادن)، برنامه نویس هرگز با داده های خام یا هویت از شرکت کنندگان فردی برخورد خواهد کرد به

(توجه داشته باشید: در حالی که از آن می رود دور در خارج از محدوده ی این آموزش، ما باید به ذکر است که یک استثناء قابل توجه به بالا، وجود دارد tff.federated_collect اپراتور است که به عنوان یک سطح پایین اولیه در نظر گرفته شده، تنها برای شرایط تخصصی استفاده صریح آن. در مواردی که می توان از آن اجتناب کرد ، توصیه نمی شود ، زیرا ممکن است برنامه های کاربردی آینده را محدود کند. به عنوان مثال ، اگر در طول تجزیه و تحلیل استاتیک ، تشخیص دهیم که در محاسباتی از چنین مکانیسم های سطح پایین استفاده می شود ، ممکن است دسترسی آن به برخی انواع داده ها.)

در داخل بدن از کد TFF، طراحی، هیچ راهی برای شمردن دستگاه هایی که این گروه به نمایندگی را تشکیل می دهند وجود دارد tff.CLIENTS ، و یا به پروب برای وجود یک دستگاه خاص در این گروه است. هیچ مفهومی از دستگاه یا هویت مشتری در هیچ کجا در API هسته ای فدرال ، مجموعه ای از انتزاعات معماری یا زیرساخت اصلی زمان اجرا که ما برای پشتیبانی از شبیه سازی ارائه می دهیم ، وجود ندارد. تمام منطق محاسباتی که می نویسید به عنوان عملیات روی کل گروه مشتری بیان می شود.

به یاد بیاورید در اینجا چیزی است که ما قبلا در مورد ارزش های انواع فدرال بودن برعکس پایتون ذکر dict ، که در یکی به سادگی نمی تواند شمردن ترکیبات عضو خود. ارزشهایی را که منطق برنامه TFF شما دستکاری می کند ، به عنوان ارتباط با مکان ها (گروه ها) در نظر بگیرید ، نه با افراد شرکت کننده.

کارگماری طراحی شده اند به یک شهروند درجه اول در TFF و همچنین، و می تواند به عنوان پارامترها و نتایج حاصل از یک نظر می رسد placement نوع (به این صورت بیان می شود tff.PlacementType در API). در آینده ، ما قصد داریم انواع اپراتورها را برای تغییر یا ترکیب مکان ها ارائه دهیم ، اما این خارج از محدوده این آموزش است. در حال حاضر، آن کافی است به فکر می کنم از placement به عنوان یک مات بدوی ساخته شده در نوع در TFF، شبیه به int و bool می مات، ساخته شده در انواع در پایتون با tff.CLIENTS بودن یک لفظ ثابت از این نوع، بر خلاف 1 بودن یک لفظ ثابت از نوع int .

تعیین مکان ها

TFF فراهم می کند دو لیترال قرار دادن پایه، tff.CLIENTS و tff.SERVER ، آن را آسان برای بیان انواع غنی از سناریوهای عملی که به طور طبیعی به عنوان معماری کلاینت سرور مدل، با دستگاه های چند مشتری (تلفن همراه، دستگاه تعبیه شده، پایگاه داده توزیع شده ، سنسور، و غیره) هماهنگ شده با یک هماهنگ کننده سرور متمرکز است. TFF همچنین برای پشتیبانی از مکان های سفارشی ، چندین گروه مشتری ، چند طبقه و معماری های توزیع شده عمومی تر طراحی شده است ، اما بحث در مورد آنها خارج از محدوده این آموزش است.

TFF می کند تجویز که چه یا tff.CLIENTS یا tff.SERVER در واقع نشان دهنده.

به طور خاص، tff.SERVER ممکن است یک دستگاه فیزیکی منفرد (یک عضو از یک گروه تک قلو)، اما آن را فقط به عنوان به خوبی ممکن است یک گروه از کپی در یک دستگاه تکثیر دولت خوشه مقاوم در برابر خطا در حال اجرا باشد - ما هیچ معماری خاص را ندارد مفروضات در عوض، ما با استفاده از all_equal کمی ذکر شده در بخش قبل برای بیان این واقعیت است که ما در حال به طور کلی خرید و فروش با تنها یک آیتم از داده ها در سرور.

به همین ترتیب، tff.CLIENTS در برخی از برنامه های کاربردی ممکن است همه مشتریان نشان دهنده در سیستم - در زمینه یادگیری فدرال ما گاهی اوقات به عنوان جمعیت مراجعه کنید، اما به عنوان مثال، در چه پیاده سازی تولید به طور متوسط فدرال ، ممکن است نشان دهنده یک گروه - یک زیر مجموعه از مشتریانی که برای شرکت در دور خاصی از آموزش انتخاب شده اند. هنگامی که محاسباتی که در آن ظاهر می شوند برای اجرا به کار گرفته می شوند (یا به سادگی مانند یک تابع پایتون در یک محیط شبیه سازی شده ، همانطور که در این آموزش نشان داده شده است) ، به مکانهایی که به طور انتزاعی تعریف شده اند معنای مشخصی داده می شود. در شبیه سازی های محلی ما ، گروه کلاینت ها توسط داده های فدراسیون ارائه شده به عنوان ورودی تعیین می شود.

محاسبات فدرال

اعلام محاسبات فدرال

TFF به عنوان یک محیط برنامه نویسی کاربردی قوی طراحی شده است که از توسعه مدولار پشتیبانی می کند.

یک بخش از منطق است که ممکن است مقادیر فدرال به عنوان ورودی قبول و بازگشت به ارزش های فدرال به عنوان خروجی - واحد پایه ترکیب در TFF محاسبات فدرال است. در اینجا چگونه می توانید محاسبه ای را تعریف کنید که میانگین دمای گزارش شده توسط آرایه سنسور را از مثال قبلی ما محاسبه کند.

@tff.federated_computation(tff.type_at_clients(tf.float32))
def get_average_temperature(sensor_readings):
  return tff.federated_mean(sensor_readings)

نگاهی به کد بالا، در این نقطه شاید بپرسید - نه در حال حاضر وجود دکوراتور سازه به تعریف واحد ساخت مجموع مانند tf.function در TensorFlow، و اگر چنین است، چرا معرفی یکی دیگر، و چگونه آن را متفاوت است؟

پاسخ کوتاه این است که کد تولید شده توسط tff.federated_computation است لفاف بسته بندی نه TensorFlow، و نه آن پایتون - این یک مشخصات یک سیستم توزیع شده در یک مستقل از پلتفرم زبان چسب داخلی است. در این مرحله ، این بدون شک رمزآلود به نظر می رسد ، اما لطفاً این تفسیر شهودی از یک محاسبه متحد را به عنوان یک مشخصات انتزاعی از یک سیستم توزیع شده در نظر داشته باشید. ما آن را در یک دقیقه توضیح خواهیم داد.

ابتدا بیایید کمی با تعریف بازی کنیم. محاسبات TFF به طور کلی به عنوان توابع مدل سازی می شوند - با یا بدون پارامترها ، اما با امضاهای نوع مشخص. شما می توانید امضا نوع محاسبات توسط پرس و جو خود را چاپ type_signature اموال، به عنوان زیر نشان داده شده.

str(get_average_temperature.type_signature)
'({float32}@CLIENTS -> float32@SERVER)'

امضای نوع به ما می گوید که محاسبه مجموعه ای از خوانش های مختلف سنسور را در دستگاه های سرویس گیرنده می پذیرد و یک میانگین واحد را بر روی سرور باز می گرداند.

قبل از اینکه ما به هر بیشتر، اجازه دهید در این منعکس برای یک دقیقه - ورودی و خروجی از این محاسبات در مکان های مختلف (در می CLIENTS در مقابل در SERVER ). به یاد بیاورید که ما در بخش قبل در مورد چگونگی دادن عملیات TFF ممکن است در سراسر نقاط دهانه و در شبکه اجرا شود، و آنچه که ما فقط در مورد محاسبات فدرال به عنوان نمایندگی مشخصات انتزاعی از سیستم های توزیع شده گفت گفت. ما فقط یک محاسبه تعریف شده داریم - یک سیستم توزیع شده ساده که در آن داده ها در دستگاه های سرویس گیرنده مصرف می شوند و نتایج کلی در سرور ظاهر می شود.

در بسیاری از حالات عملی، محاسبات است که نشان دهنده وظایف سطح بالا تمایل به قبول ورودی خود و گزارش خروجی خود را در سرور - این نشان دهنده این ایده که محاسبات ممکن است توسط نمایش داده شد که سرچشمه و خاتمه بر روی سرور باعث شده است.

با این حال، FC API کند این فرض تحمیل نیست، و بسیاری از بلوک های ساختمان ما با استفاده از داخلی (از جمله تعداد زیادی tff.federated_... اپراتورهای شما ممکن است در API را پیدا کنید) دارند ورودی و خروجی با دادن متمایز، بنابراین به طور کلی، شما باید در مورد محاسبات فدرال به عنوان چیزی که بر روی سرور اجرا می شود و یا توسط یک سرور اجرا فکر نمی کنم. سرور تنها یک نوع شرکت کننده در محاسبات فدراسیون است. در تفکر درباره مکانیک چنین محاسباتی ، بهتر است همیشه به جای دیدگاه یک هماهنگ کننده متمرکز واحد ، از دیدگاه شبکه جهانی پیش فرض استفاده کنید.

به طور کلی، امضا نوع کاربردی فشرده به عنوان نمایندگی (T -> U) برای انواع T و U ورودی و خروجی، به ترتیب. نوع پارامتر رسمی (مانند sensor_readings در این مورد) به عنوان آرگومان به دکوراتور مشخص شده است. نیازی نیست نوع نتیجه را مشخص کنید - به طور خودکار تعیین می شود.

اگرچه TFF اشکال محدودی از چند شکلی را ارائه می دهد ، اما برنامه نویسان به شدت تشویق می شوند که در مورد انواع داده هایی که با آنها کار می کنند صریح باشند ، زیرا این امر درک ، اشکال زدایی و تأیید رسمی خواص کد شما را آسان تر می کند. در برخی موارد ، تعیین صریح انواع مورد نیاز است (به عنوان مثال ، محاسبات چند شکلی در حال حاضر به طور مستقیم قابل اجرا نیستند).

اجرای محاسبات فدرال

به منظور پشتیبانی از توسعه و اشکال زدایی ، TFF به شما این امکان را می دهد که محاسباتی را که به این صورت به عنوان توابع پایتون تعریف شده اند ، به طور مستقیم فراخوانی کنید ، همانطور که در زیر نشان داده شده است. که در آن محاسبات انتظار مقدار از نوع فدرال با all_equal بیت به False ، شما می توانید آن را به عنوان یک دشت تغذیه list در پایتون، و برای انواع فدرال با all_equal بیت به True ، شما فقط می توانید به طور مستقیم تغذیه (تک) جزء تشکیل دهنده اعضا همچنین به این ترتیب نتایج به شما گزارش می شود.

get_average_temperature([68.5, 70.3, 69.8])
69.53334

هنگامی که محاسباتی مانند این را در حالت شبیه سازی اجرا می کنید ، شما به عنوان یک ناظر خارجی با نمای کلی سیستم عمل می کنید ، که می تواند ورودی ها و خروجی ها را در هر مکان از شبکه تأمین کند ، همانطور که در اینجا چنین است - شما ارزش های مشتری را ارائه کرده اید در ورودی ، و نتیجه سرور را مصرف می کند.

در حال حاضر، بازگشت اجازه دهید به توجه داشته باشید که ما قبلا در مورد ساخته شده tff.federated_computation دکوراتور رهبری کد در یک زبان چسب. اگر چه منطق محاسبات TFF می تواند به عنوان توابع معمولی در پایتون بیان (شما فقط نیاز به آنها را تزئین با tff.federated_computation همانطور که در بالا انجام داده ام)، و شما به طور مستقیم می توانید فراخوان آنها را با استدلال پایتون مانند هر توابع پایتون دیگر در این نوت بوک، پشت صحنه، همانطور که ما قبلا اشاره شد، محاسبات TFF در واقع پایتون است.

چه این منظور ما این است که وقتی مفسر پایتون یک تابع تزئین شده با برخورد tff.federated_computation ، آن آثار اظهارات در بدن این تابع را یک بار (در زمان تعریف)، و سپس به ساختن یک نمایندگی سریال منطق محاسبات را برای استفاده در آینده - چه برای اجرا ، یا به عنوان یک جزء فرعی در محاسبات دیگر گنجانده شود.

می توانید با افزودن یک دستور چاپ ، موارد زیر را تأیید کنید:

@tff.federated_computation(tff.type_at_clients(tf.float32))
def get_average_temperature(sensor_readings):

  print ('Getting traced, the argument is "{}".'.format(
      type(sensor_readings).__name__))

  return tff.federated_mean(sensor_readings)
Getting traced, the argument is "ValueImpl".

می توانید به کد پایتون فکر کنید که یک محاسبه فدرال را تعریف می کند ، مانند تصور شما از کد پایتون که نمودار TensorFlow را در زمینه ای مشتاق ایجاد می کند (اگر با کاربردهای غیر مشتاقانه TensorFlow آشنا نیستید ، به فکر خود باشید. کد پایتون گراف عملیات را تعریف می کند که بعداً اجرا می شود ، اما در واقع آنها را در حال اجرا نیست). کد ایجاد گراف بدون اشتیاق در TensorFlow پایتون است ، اما نمودار TensorFlow ساخته شده توسط این کد مستقل از پلتفرم و قابل سریال سازی است.

به همین ترتیب، محاسبات TFF در پایتون تعریف شده است، اما اظهارات پایتون در بدن آنها، مانند tff.federated_mean در مثال نشان داده شده است فقط ایم، به نمایندگی serializable قابل حمل و مستقل از پلتفرم در زیر کاپوت وارد شده است.

به عنوان یک توسعه دهنده ، نیازی به توجه به جزئیات این نمایندگی ندارید ، زیرا هرگز نیازی به کار مستقیم با آن نخواهید داشت ، اما باید از وجود آن آگاه باشید ، این واقعیت که محاسبات TFF اساساً مشتاق نیستند ، و نمی تواند حالت خودسرانه پایتون را ضبط کند. کد پایتون موجود در بدن یک محاسبه TFF است در زمان تعریف اعدام، زمانی که بدن از تابع پایتون تزئین شده با tff.federated_computation است قبل از گرفتن مرتب پیش بینی کرد. در زمان فراخوانی مجدداً بازگردانده نمی شود (مگر در مواردی که عملکرد چند شکل باشد ؛ لطفاً برای جزئیات به صفحات اسناد مراجعه کنید).

شاید تعجب کنید که چرا ما معرفی یک نمای داخلی اختصاصی غیر پایتون را انتخاب کرده ایم. یکی از دلایل این است که در نهایت ، محاسبات TFF قابل استفاده در محیط های فیزیکی واقعی هستند و بر روی دستگاه های تلفن همراه یا جاسازی شده ، جایی که پایتون در دسترس نیست ، میزبانی می شود.

دلیل دیگر این است که محاسبات TFF رفتار جهانی سیستم های توزیع شده را نشان می دهد ، در مقابل برنامه های پایتون که رفتار محلی تک تک شرکت کنندگان را بیان می کنند. شما می توانید در مثال ساده بالا می بینیم که، با اپراتور خاص tff.federated_mean که داده ها در دستگاه های مشتری، اما سپرده نتایج بر روی سرور می پذیرد.

اپراتور tff.federated_mean نمی توان به راحتی به عنوان یک اپراتور معمولی در پایتون مدل، از آن به طور محلی اجرا نیست - همانطور که قبلا اشاره شد، آن را نشان دهنده یک سیستم توزیع شده که مختصات رفتار شرکت کنندگان سیستم های مختلف. ما به چنین اپراتورهای عنوان اپراتور فدرال مراجعه کنید، آنها را متمایز از عادی اپراتورهای (محلی) در پایتون.

سیستم نوع TFF ، و مجموعه اصلی عملیات پشتیبانی شده در زبان TFF ، بنابراین به طور قابل توجهی از سیستم های پایتون منحرف می شود و استفاده از نمای اختصاصی را ضروری می سازد.

ایجاد محاسبات فدراسیون

همانطور که در بالا اشاره شد ، محاسبات فدراسیون شده و اجزای سازنده آنها به عنوان مدلهای سیستمهای توزیع شده بهتر درک می شوند و شما می توانید ترکیب محاسبات فدرال را به عنوان ترکیب سیستمهای توزیع شده پیچیده تر از سیستمهای ساده تر در نظر بگیرید. شما می توانید از فکر می کنم tff.federated_mean اپراتور عنوان یک نوع از ساخته شده است در قالب محاسبات فدرال با امضای نوع ({T}@CLIENTS -> T@SERVER) (در واقع، درست مثل محاسبات شما ارسال، این اپراتور همچنین دارای یک مجموعه ساختار - در زیر کاپوت ما آن را به اپراتورهای ساده تر تقسیم می کنیم).

همین امر در مورد ساخت محاسبات فدراسیون صادق است. محاسبه get_average_temperature ممکن است در یک بدن دیگر تابع پایتون تزئین شده با استناد tff.federated_computation - انجام این کار باعث می شود آن را به در بدن از پدر و مادر جاسازی شده باشد، بسیار در همان راه tff.federated_mean در بدن خود زودتر جاسازی شده بود.

محدودیت مهم است که از این است که بدن از توابع پایتون تزئین شده با آگاه tff.federated_computation باید تنها از اپراتورهای فدرال، یعنی تشکیل شده است، آنها نمی توانند مستقیما شامل عملیات TensorFlow. به عنوان مثال، شما می توانید به طور مستقیم استفاده tf.nest رابط برای اضافه کردن یک جفت از ارزش فدرال. کد TensorFlow باید به بلوک از کد تزئین شده با محدود tff.tf_computation بحث شده در بخش های زیر است. تنها زمانی که در این روش پیچیده می توانید کد TensorFlow پیچیده می شود در بدن یک استناد tff.federated_computation .

دلایل این جدایی فنی است (آن را سخت برای فریب اپراتورهای مانند tf.add به کار با غیر تانسورها) و همچنین معماری. زبان محاسبات فدرال (یعنی منطق ساخته شده از بدن مرتب از توابع پایتون تزئین شده با tff.federated_computation ) طراحی شده است که به عنوان یک زبان مستقل از پلتفرم چسب خدمت می کنند. این زبان چسب در حال حاضر به سیستم ساخت توزیع از بخش های جاسازی شده از کد TensorFlow (محدود به استفاده tff.tf_computation بلوک). در پری از زمان، ما پیش بینی نیاز به بخش های جاسازی دیگر، منطق غیر TensorFlow، مانند نمایش داده شد پایگاه داده رابطه ای که ممکن است خط لوله ورودی نشان، همه با هم متصل با استفاده از زبان چسب همان (به tff.federated_computation بلوک).

منطق TensorFlow

اعلام محاسبات TensorFlow

TFF برای استفاده با TensorFlow طراحی شده است. به این ترتیب ، عمده کدی که در TFF می نویسید احتمالاً کد TensorFlow معمولی (یعنی محلی) است. به منظور استفاده از این کد با TFF، همانطور که در بالا اشاره شد، آن را فقط باید با تزئین می شود tff.tf_computation .

به عنوان مثال، در اینجا چگونه ما می تواند یک تابع است که طول می کشد یک تعداد و می افزاید: اجرای 0.5 به آن است.

@tff.tf_computation(tf.float32)
def add_half(x):
  return tf.add(x, 0.5)

یک بار دیگر، به دنبال در این، شما ممکن است تعجب کنید که چرا ما باید یکی دیگر از دکوراتور تعریف tff.tf_computation به جای به سادگی با استفاده از یک مکانیزم موجود مانند tf.function . برخلاف بخش قبل ، در اینجا ما با یک بلوک معمولی از کد TensorFlow سروکار داریم.

دلایل متعددی برای این امر وجود دارد ، که درمان کامل آنها از حوصله این آموزش فراتر می رود ، اما ارزش ذکر دلیل اصلی را دارد:

  • به منظور جاسازی بلوک های ساختمانی قابل استفاده مجدد که با استفاده از کد TensorFlow در بدنه محاسبات فدراسیون اجرا می شوند ، باید ویژگی های خاصی را داشته باشند - مانند ردیابی و سریال سازی در زمان تعریف ، داشتن امضای نوع و غیره. این به طور کلی به نوعی از تزئین کننده نیاز دارد.

به طور کلی، توصیه می کنیم با استفاده از مکانیسم های بومی TensorFlow برای ترکیب، مانند tf.function ، هر کجا که ممکن است، به عنوان شیوه ای دقیق که در آن تعامل دکوراتور TFF با توابع مشتاق می توان انتظار داشت به تکامل است.

در حال حاضر، آینده را به عنوان مثال کد قطعه بالا، محاسبات add_half ما فقط تعریف را می توان با TFF درست مثل هر محاسبه TFF دیگر درمان می شود. به طور خاص ، دارای امضای نوع TFF است.

str(add_half.type_signature)
'(float32 -> float32)'

توجه داشته باشید این نوع امضا محل قرارگیری ندارد. محاسبات TensorFlow نمی توانند انواع متصل شده را مصرف کرده یا بازگردانند.

شما هم اکنون می توانید با استفاده از add_half عنوان یک بلوک ساختمان در محاسبات. به عنوان مثال، در اینجا شما می توانید استفاده از tff.federated_map اپراتور به درخواست add_half نقطه به نقطه به تمام اجزاء عضو یک شناور فدرال به دستگاه های مشتری.

@tff.federated_computation(tff.type_at_clients(tf.float32))
def add_half_on_clients(x):
  return tff.federated_map(add_half, x)
str(add_half_on_clients.type_signature)
'({float32}@CLIENTS -> {float32}@CLIENTS)'

اجرای محاسبات TensorFlow

اجرای محاسبات تعریف شده با tff.tf_computation به پیروی از قوانین همان کسانی که ما برای توصیف tff.federated_computation . آنها را می توان به عنوان فراخوانی های معمولی در پایتون به شرح زیر فراخوانی کرد.

add_half_on_clients([1.0, 3.0, 2.0])
[<tf.Tensor: shape=(), dtype=float32, numpy=1.5>,
 <tf.Tensor: shape=(), dtype=float32, numpy=3.5>,
 <tf.Tensor: shape=(), dtype=float32, numpy=2.5>]

یک بار دیگر، شایان ذکر است که با استناد به محاسبات است add_half_on_clients در این روش شبیه سازی یک فرآیند توزیع شده است. داده ها در مورد مشتریان مصرف می شود و در اختیار مشتریان قرار می گیرد. در واقع ، با این محاسبه هر مشتری یک عمل محلی انجام می دهد. وجود ندارد tff.SERVER به صراحت در این سیستم ذکر شده (حتی اگر در عمل، سازماندهی پردازش چنین ممکن است شامل یک و). فکر می کنم از یک محاسبه این راه به عنوان مفهومی شبیه به تعریف Map مرحله در MapReduce .

همچنین، به خاطر داشته باشید که آنچه که ما در بخش قبل در مورد محاسبات TFF گرفتن در زمان تعریف مرتب گفت درست است برای باقی می ماند tff.tf_computation کد و همچنین - بدن پایتون از add_half_on_clients می شود یک بار در زمان تعریف پیش بینی کرد. در فراخوانی های بعدی ، TFF از نمایش سریال شده خود استفاده می کند.

تنها تفاوت بین روش پایتون تزئین شده با tff.federated_computation و کسانی که تزئین شده با tff.tf_computation این است که دومی به عنوان نمودار TensorFlow مرتب (در حالی که سابق امکان پذیر نیست به شامل کد TensorFlow طور مستقیم در آنها تعبیه شده است).

در زیر هود، هر روش تزئین شده با tff.tf_computation به طور موقت اجرای مشتاق به منظور اجازه ساختار محاسبات را به اسیر غیر فعال. در حالی که اجرای مشتاق به صورت محلی غیرفعال است ، می توانید از سازه های مشتاق TensorFlow ، AutoGraph ، TensorFlow 2.0 و غیره استفاده کنید ، تا زمانی که منطق محاسبه خود را به گونه ای بنویسید که بتواند به درستی سریال سازی شود.

به عنوان مثال ، کد زیر خراب می شود:

try:

  # Eager mode
  constant_10 = tf.constant(10.)

  @tff.tf_computation(tf.float32)
  def add_ten(x):
    return x + constant_10

except Exception as err:
  print (err)
Attempting to capture an EagerTensor without building a function.

فوق نتواند به دلیل constant_10 در حال حاضر در خارج از نمودار که ساخته شده tff.tf_computation سازه داخلی در بدن از add_ten در طول فرایند ترتیب است.

از سوی دیگر، با استناد به توابع پایتون است که تغییر نمودار فعلی زمانی که در داخل یک نام tff.tf_computation خوب است:

def get_constant_10():
  return tf.constant(10.)

@tff.tf_computation(tf.float32)
def add_ten(x):
  return x + get_constant_10()

add_ten(5.0)
15.0

توجه داشته باشید که مکانیزم های سریال سازی در TensorFlow در حال تکامل است و ما انتظار داریم جزئیات نحوه سریال سازی محاسبات TFF نیز تکامل یابد.

کار با tf.data.Dataset بازدید کنندگان

As noted earlier, a unique feature of tff.tf_computation s is that they allows you to work with tf.data.Dataset s defined abstractly as formal parameters by your code. Parameters to be represented in TensorFlow as data sets need to be declared using the tff.SequenceType constructor.

For example, the type specification tff.SequenceType(tf.float32) defines an abstract sequence of float elements in TFF. Sequences can contain either tensors, or complex nested structures (we'll see examples of those later). The concise representation of a sequence of T -typed items is T* .

float32_sequence = tff.SequenceType(tf.float32)

str(float32_sequence)
'float32*'

Suppose that in our temperature sensor example, each sensor holds not just one temperature reading, but multiple. Here's how you can define a TFF computation in TensorFlow that calculates the average of temperatures in a single local data set using the tf.data.Dataset.reduce operator.

@tff.tf_computation(tff.SequenceType(tf.float32))
def get_local_temperature_average(local_temperatures):
  sum_and_count = (
      local_temperatures.reduce((0.0, 0), lambda x, y: (x[0] + y, x[1] + 1)))
  return sum_and_count[0] / tf.cast(sum_and_count[1], tf.float32)
str(get_local_temperature_average.type_signature)
'(float32* -> float32)'

In the body of a method decorated with tff.tf_computation , formal parameters of a TFF sequence type are represented simply as objects that behave like tf.data.Dataset , ie, support the same properties and methods (they are currently not implemented as subclasses of that type - this may change as the support for data sets in TensorFlow evolves).

You can easily verify this as follows.

@tff.tf_computation(tff.SequenceType(tf.int32))
def foo(x):
  return x.reduce(np.int32(0), lambda x, y: x + y)

foo([1, 2, 3])
6

Keep in mind that unlike ordinary tf.data.Dataset s, these dataset-like objects are placeholders. They don't contain any elements, since they represent abstract sequence-typed parameters, to be bound to concrete data when used in a concrete context. Support for abstractly-defined placeholder data sets is still somewhat limited at this point, and in the early days of TFF, you may encounter certain restrictions, but we won't need to worry about them in this tutorial (please refer to the documentation pages for details).

When locally executing a computation that accepts a sequence in a simulation mode, such as in this tutorial, you can feed the sequence as Python list, as below (as well as in other ways, eg, as a tf.data.Dataset in eager mode, but for now, we'll keep it simple).

get_local_temperature_average([68.5, 70.3, 69.8])
69.53333

Like all other TFF types, sequences like those defined above can use the tff.StructType constructor to define nested structures. For example, here's how one could declare a computation that accepts a sequence of pairs A , B , and returns the sum of their products. We include the tracing statements in the body of the computation so that you can see how the TFF type signature translates into the dataset's output_types and output_shapes .

@tff.tf_computation(tff.SequenceType(collections.OrderedDict([('A', tf.int32), ('B', tf.int32)])))
def foo(ds):
  print('element_structure = {}'.format(ds.element_spec))
  return ds.reduce(np.int32(0), lambda total, x: total + x['A'] * x['B'])
element_structure = OrderedDict([('A', TensorSpec(shape=(), dtype=tf.int32, name=None)), ('B', TensorSpec(shape=(), dtype=tf.int32, name=None))])
str(foo.type_signature)
'(<A=int32,B=int32>* -> int32)'
foo([{'A': 2, 'B': 3}, {'A': 4, 'B': 5}])
26

The support for using tf.data.Datasets as formal parameters is still somewhat limited and evolving, although functional in simple scenarios such as those used in this tutorial.

Putting it all together

Now, let's try again to use our TensorFlow computation in a federated setting. Suppose we have a group of sensors that each have a local sequence of temperature readings. We can compute the global temperature average by averaging the sensors' local averages as follows.

@tff.federated_computation(
    tff.type_at_clients(tff.SequenceType(tf.float32)))
def get_global_temperature_average(sensor_readings):
  return tff.federated_mean(
      tff.federated_map(get_local_temperature_average, sensor_readings))

Note that this isn't a simple average across all local temperature readings from all clients, as that would require weighing contributions from different clients by the number of readings they locally maintain. We leave it as an exercise for the reader to update the above code; the tff.federated_mean operator accepts the weight as an optional second argument (expected to be a federated float).

Also note that the input to get_global_temperature_average now becomes a federated float sequence . Federated sequences is how we will typically represent on-device data in federated learning, with sequence elements typically representing data batches (you will see examples of this shortly).

str(get_global_temperature_average.type_signature)
'({float32*}@CLIENTS -> float32@SERVER)'

Here's how we can locally execute the computation on a sample of data in Python. Notice that the way we supply the input is now as a list of list s. The outer list iterates over the devices in the group represented by tff.CLIENTS , and the inner ones iterate over elements in each device's local sequence.

get_global_temperature_average([[68.0, 70.0], [71.0], [68.0, 72.0, 70.0]])
70.0

This concludes the first part of the tutorial... we encourage you to continue on to the second part .