Przegląd
W tym dokumencie przedstawiono interfejsy, które ułatwiają zadania związane z uczeniem federacyjnym, takie jak szkolenie federacyjne lub ocena z istniejącymi modelami uczenia maszynowego zaimplementowanymi w TensorFlow. Podczas projektowania tych interfejsów naszym głównym celem było umożliwienie eksperymentowania z uczeniem federacyjnym bez konieczności posiadania wiedzy o tym, jak to działa od podstaw, oraz ocena zaimplementowanych algorytmów uczenia federacyjnego na różnych istniejących modelach i danych. Zachęcamy do współtworzenia platformy. TFF został zaprojektowany z myślą o możliwości rozbudowy i komponowania, a my czekamy na wkład; jesteśmy podekscytowani, aby zobaczyć, co wymyślisz!
Interfejsy oferowane przez tę warstwę składają się z trzech kluczowych części:
modele . Klasy i funkcje pomocnicze, które umożliwiają zawijanie istniejących modeli do użytku z TFF. Zawijanie modelu może być tak proste, jak wywołanie pojedynczej funkcji zawijającej (np.
tff.learning.models.from_keras_model
) lub zdefiniowanie podklasy interfejsutff.learning.models.VariableModel
w celu uzyskania pełnej personalizacji.Konstruktorzy obliczeń stowarzyszonych . Funkcje pomocnicze, które konstruują obliczenia stowarzyszone na potrzeby szkolenia lub oceny przy użyciu istniejących modeli.
zestawy danych . Zbiory danych w puszkach, które można pobierać i uzyskiwać do nich dostęp w języku Python, do użytku w symulowaniu scenariuszy nauczania federacyjnego. Chociaż federacyjne uczenie się jest przeznaczone do użytku ze zdecentralizowanymi danymi, których nie można po prostu pobrać w scentralizowanej lokalizacji, na etapie badań i rozwoju często wygodnie jest przeprowadzić wstępne eksperymenty z wykorzystaniem danych, które można pobrać i manipulować lokalnie, zwłaszcza dla programistów, którzy mogą być nowe podejście.
Te interfejsy są zdefiniowane głównie w przestrzeni nazw tff.learning
, z wyjątkiem zestawów danych badawczych i innych możliwości związanych z symulacją, które zostały zgrupowane w tff.simulation
. Warstwa ta jest implementowana przy użyciu interfejsów niższego poziomu oferowanych przez Federated Core (FC) , który udostępnia również środowisko uruchomieniowe.
Przed kontynuowaniem zalecamy zapoznanie się z samouczkami dotyczącymi klasyfikacji obrazów i generowania tekstu , ponieważ wprowadzają one większość opisanych tutaj pojęć na konkretnych przykładach. Jeśli chcesz dowiedzieć się więcej o tym, jak działa TFF, możesz przejrzeć samouczek dotyczący algorytmów niestandardowych jako wprowadzenie do interfejsów niższego poziomu, których używamy do wyrażania logiki obliczeń stowarzyszonych, oraz do przestudiowania istniejącej implementacji interfejsy tff.learning
.
modele
Założenia architektoniczne
Serializacja
TFF ma na celu obsługę różnych scenariuszy uczenia rozproszonego, w których napisany kod modelu uczenia maszynowego może być wykonywany na dużej liczbie heterogenicznych klientów o różnych możliwościach. Chociaż na jednym krańcu spektrum, w niektórych aplikacjach klienci ci mogą być potężnymi serwerami baz danych, wiele ważnych zastosowań, które nasza platforma zamierza obsługiwać, dotyczy urządzeń mobilnych i wbudowanych o ograniczonych zasobach. Nie możemy zakładać, że te urządzenia są w stanie obsługiwać środowiska wykonawcze Pythona; jedyne, co możemy założyć w tym momencie, to to, że są w stanie obsługiwać lokalne środowisko uruchomieniowe TensorFlow. W związku z tym fundamentalnym założeniem architektonicznym, które przyjmujemy w TFF, jest to, że kod modelu musi nadawać się do serializacji jako wykres TensorFlow.
Możesz (i powinieneś) nadal rozwijać swój kod TF zgodnie z najnowszymi najlepszymi praktykami, takimi jak korzystanie z trybu gotowości. Jednak końcowy kod musi być możliwy do serializacji (np. może być opakowany jako tf.function
dla kodu w trybie chętnym). Gwarantuje to, że każdy stan Pythona lub przepływ sterowania wymagany w czasie wykonywania może zostać zserializowany (prawdopodobnie za pomocą Autograph ).
Obecnie TensorFlow nie obsługuje w pełni serializacji i deserializacji TensorFlow w trybie gotowości. W związku z tym serializacja w TFF jest obecnie zgodna ze wzorcem TF 1.0, w którym cały kod musi być skonstruowany wewnątrz tf.Graph
, który kontroluje TFF. Oznacza to, że obecnie TFF nie może korzystać z już skonstruowanego modelu; zamiast tego logika definicji modelu jest spakowana w funkcji bez argumentów, która zwraca tff.learning.models.VariableModel
. Ta funkcja jest następnie wywoływana przez TFF, aby upewnić się, że wszystkie komponenty modelu są serializowane. Ponadto, będąc środowiskiem silnie typowanym, TFF będzie wymagać trochę dodatkowych metadanych , takich jak specyfikacja typu danych wejściowych twojego modelu.
Zbiór
Zdecydowanie zalecamy większości użytkowników tworzenie modeli przy użyciu Keras, zobacz sekcję Konwertery dla Keras poniżej. Te opakowania obsługują agregację aktualizacji modelu, a także wszelkie metryki zdefiniowane dla modelu automatycznie. Jednak nadal przydatne może być zrozumienie sposobu obsługi agregacji dla ogólnego tff.learning.models.VariableModel
.
W federacyjnym uczeniu się zawsze istnieją co najmniej dwie warstwy agregacji: agregacja lokalna na urządzeniu i agregacja między urządzeniami (lub federacyjna):
Agregacja lokalna . Ten poziom agregacji odnosi się do agregacji wielu partii przykładów należących do pojedynczego klienta. Dotyczy to zarówno parametrów modelu (zmiennych), które nadal sekwencyjnie ewoluują, gdy model jest trenowany lokalnie, jak i statystyk, które obliczasz (takich jak średnia strata, dokładność i inne metryki), które twój model będzie ponownie aktualizował lokalnie podczas iteracji lokalnego strumienia danych każdego klienta.
Wykonywanie agregacji na tym poziomie jest obowiązkiem kodu modelu i jest realizowane przy użyciu standardowych konstrukcji TensorFlow.
Ogólna struktura przetwarzania jest następująca:
Model najpierw konstruuje
tf.Variable
s do przechowywania agregatów, takich jak liczba partii lub liczba przetworzonych przykładów, suma strat na partię lub na przykład itp.TFF wielokrotnie wywołuje metodę
forward_pass
na twoimModel
, sekwencyjnie na kolejnych partiach danych klienta, co pozwala aktualizować zmienne przechowujące różne agregaty jako efekt uboczny.Na koniec TFF wywołuje metodę
report_local_unfinalized_metrics
w twoim Modelu, aby umożliwić modelowi skompilowanie wszystkich zebranych statystyk podsumowujących w zwarty zestaw metryk do wyeksportowania przez klienta. W tym miejscu kod modelu może na przykład podzielić sumę strat przez liczbę przetworzonych przykładów w celu wyeksportowania średniej straty itp.
Agregacja federacyjna . Ten poziom agregacji odnosi się do agregacji na wielu klientach (urządzeniach) w systemie. Ponownie dotyczy to zarówno parametrów modelu (zmiennych), które są uśredniane przez klientów, jak i metryk wyeksportowanych przez Twój model w wyniku lokalnej agregacji.
Za przeprowadzenie agregacji na tym poziomie odpowiada TFF. Jako twórca modelu możesz jednak kontrolować ten proces (więcej na ten temat poniżej).
Ogólna struktura przetwarzania jest następująca:
Początkowy model i wszelkie parametry wymagane do szkolenia są dystrybuowane przez serwer do podzbioru klientów, którzy wezmą udział w rundzie szkolenia lub oceny.
Na każdym kliencie, niezależnie i równolegle, kod modelu jest wielokrotnie wywoływany w strumieniu lokalnych partii danych w celu utworzenia nowego zestawu parametrów modelu (podczas uczenia) oraz nowego zestawu lokalnych metryk, jak opisano powyżej (jest to zbiór).
TFF obsługuje rozproszony protokół agregacji w celu gromadzenia i agregowania parametrów modelu oraz lokalnie eksportowanych metryk w całym systemie. Ta logika jest wyrażona w sposób deklaratywny przy użyciu własnego federacyjnego języka obliczeniowego TFF (nie w TensorFlow). Zobacz samouczek algorytmów niestandardowych, aby uzyskać więcej informacji na temat interfejsu API agregacji.
Interfejsy abstrakcyjne
Ten podstawowy interfejs konstruktora i metadanych jest reprezentowany przez interfejs tff.learning.models.VariableModel
w następujący sposób:
Konstruktor, metody
forward_pass
ireport_local_unfinalized_metrics
powinny konstruować odpowiednio zmienne modelu, przepustkę do przodu i statystyki, które chcesz raportować. TensorFlow skonstruowany za pomocą tych metod musi być możliwy do serializacji, jak omówiono powyżej.Właściwość
input_spec
, a także 3 właściwości, które zwracają podzbiory zmiennych możliwych do nauczenia, niemożliwych do nauczenia i zmiennych lokalnych, reprezentują metadane. TFF wykorzystuje te informacje do określenia, w jaki sposób połączyć części twojego modelu z federacyjnymi algorytmami optymalizacji oraz do zdefiniowania wewnętrznych sygnatur typów, aby pomóc w weryfikacji poprawności skonstruowanego systemu (aby nie można było utworzyć instancji modelu na danych, które nie pasują do tego, co model jest przeznaczony do konsumpcji).
Ponadto abstrakcyjny interfejs tff.learning.models.VariableModel
udostępnia właściwość metric_finalizers
, która przyjmuje niesfinalizowane wartości metryki (zwrócone przez report_local_unfinalized_metrics()
) i zwraca sfinalizowane wartości metryki. Metody metric_finalizers
i report_local_unfinalized_metrics()
zostaną użyte razem do zbudowania agregatora metryk między klientami podczas definiowania federacyjnych procesów szkoleniowych lub obliczeń ewaluacyjnych. Na przykład prosty agregator tff.learning.metrics.sum_then_finalize
najpierw zsumuje niesfinalizowane wartości metryk od klientów, a następnie wywoła funkcje finalizatora na serwerze.
Przykłady definiowania własnego niestandardowego tff.learning.models.VariableModel
można znaleźć w drugiej części naszego samouczka dotyczącego klasyfikacji obrazów , a także w przykładowych modelach, których używamy do testowania w model_examples.py
.
Konwertery dla Keras
Prawie wszystkie informacje wymagane przez TFF można uzyskać, wywołując interfejsy tf.keras
, więc jeśli masz model Keras, możesz polegać na tff.learning.models.from_keras_model
, aby skonstruować tff.learning.models.VariableModel
.
Zauważ, że TFF nadal chce, abyś dostarczył konstruktora - bezargumentową funkcję modelu , taką jak następująca:
def model_fn():
keras_model = ...
return tff.learning.models.from_keras_model(keras_model, sample_batch, loss=...)
Oprócz samego modelu dostarczasz przykładową partię danych, których TFF używa do określenia typu i kształtu danych wejściowych twojego modelu. Gwarantuje to, że TFF może poprawnie utworzyć instancję modelu dla danych, które faktycznie będą obecne na urządzeniach klienckich (ponieważ zakładamy, że te dane nie są ogólnie dostępne w czasie, gdy tworzysz TensorFlow do serializacji).
Użycie opakowań Keras jest zilustrowane w naszych samouczkach dotyczących klasyfikacji obrazów i generowania tekstu .
Federacyjne konstruktory obliczeń
Pakiet tff.learning
zawiera kilka konstruktorów dla tff.Computation
s, które wykonują zadania związane z uczeniem się; spodziewamy się, że zbiór takich obliczeń będzie się rozszerzał w przyszłości.
Założenia architektoniczne
Wykonanie
Istnieją dwie odrębne fazy uruchamiania obliczeń federacyjnych.
Kompiluj : TFF najpierw kompiluje algorytmy uczenia federacyjnego w abstrakcyjną serializowaną reprezentację całego rozproszonego obliczenia. To wtedy ma miejsce serializacja TensorFlow, ale mogą wystąpić inne przekształcenia w celu obsługi bardziej wydajnego wykonywania. Serializowaną reprezentację emitowaną przez kompilator nazywamy obliczeniem stowarzyszonym .
Execute TFF zapewnia sposoby wykonywania tych obliczeń. Na razie wykonanie jest obsługiwane tylko przez lokalną symulację (np. w notebooku przy użyciu symulowanych zdecentralizowanych danych).
Obliczenia federacyjne generowane przez interfejs Federated Learning API TFF, takie jak algorytm szkoleniowy wykorzystujący uśrednianie modelu federacyjnego lub ocena federacyjna, obejmują szereg elementów, w szczególności:
Zserializowana postać kodu modelu, jak również dodatkowy kod TensorFlow skonstruowany przez platformę Federated Learning w celu kierowania pętlą szkolenia/oceny modelu (taką jak konstruowanie optymalizatorów, stosowanie aktualizacji modelu, iteracja po
tf.data.Dataset
s i obliczanie metryk, i zastosowanie zagregowanej aktualizacji na serwerze, by wymienić tylko kilka).Deklaratywna specyfikacja komunikacji między klientami a serwerem (zwykle różne formy agregacji na urządzeniach klienckich i nadawanie z serwera do wszystkich klientów) oraz sposób, w jaki ta rozproszona komunikacja jest przeplatana z wykonaniem lokalnym klienta lub serwera kodu TensorFlow.
Obliczenia federacyjne reprezentowane w tej postaci serializowanej są wyrażone w niezależnym od platformy języku wewnętrznym, innym niż Python, ale aby korzystać z API Federated Learning, nie musisz zajmować się szczegółami tej reprezentacji. Obliczenia są reprezentowane w kodzie Pythona jako obiekty typu tff.Computation
, które w większości można traktować jako nieprzezroczyste callable
w Pythonie s.
W samouczkach będziesz wywoływać te federacyjne obliczenia tak, jakby były zwykłymi funkcjami Pythona, które mają być wykonywane lokalnie. Jednak TFF jest przeznaczony do wyrażania obliczeń federacyjnych w sposób niezależny od większości aspektów środowiska wykonawczego, dzięki czemu można je potencjalnie wdrażać np. w grupach urządzeń z Android
lub w klastrach w centrum danych. Ponownie, główną konsekwencją tego są silne założenia dotyczące serializacji . W szczególności, gdy wywołasz jedną z metod build_...
opisanych poniżej, obliczenia są w pełni serializowane.
Stan modelowania
TFF jest funkcjonalnym środowiskiem programistycznym, jednak wiele procesów będących przedmiotem zainteresowania federacyjnego uczenia się jest stanowych. Na przykład pętla treningowa obejmująca wiele rund uśredniania modelu federacyjnego jest przykładem tego, co możemy sklasyfikować jako proces stanowy . W tym procesie stan, który ewoluuje z rundy na rundę, obejmuje zestaw parametrów modelu, które są szkolone, i ewentualnie dodatkowy stan związany z optymalizatorem (np. wektor pędu).
Ponieważ TFF jest funkcjonalny, procesy stanowe są modelowane w TFF jako obliczenia, które akceptują bieżący stan jako dane wejściowe, a następnie dostarczają zaktualizowany stan jako dane wyjściowe. Aby w pełni zdefiniować proces stanowy, należy również określić, skąd pochodzi stan początkowy (w przeciwnym razie nie możemy uruchomić procesu). Jest to ujęte w definicji klasy pomocniczej tff.templates.IterativeProcess
, z dwiema właściwościami initialize
i next
odpowiadającymi odpowiednio inicjalizacji i iteracji.
Dostępni budowniczowie
W tej chwili TFF zapewnia różne funkcje konstruktora, które generują federacyjne obliczenia na potrzeby federacyjnego szkolenia i oceny. Dwa godne uwagi przykłady to:
tff.learning.algorithms.build_weighted_fed_avg
, która przyjmuje jako dane wejściowe funkcję modelu i optymalizator klienta i zwraca stanowytff.learning.templates.LearningProcess
(którego podklasytff.templates.IterativeProcess
).tff.learning.build_federated_evaluation
pobiera funkcję modelu i zwraca pojedyncze obliczenie federacyjne dla federacyjnej oceny modeli, ponieważ ocena nie jest stanowa.
Zbiory danych
Założenia architektoniczne
Wybór klienta
W typowym scenariuszu uczenia federacyjnego mamy dużą populację potencjalnie setek milionów urządzeń klienckich, z których tylko niewielka część może być aktywna i dostępna do szkolenia w danym momencie (na przykład może to być ograniczone do klientów, którzy są podłączony do źródła zasilania, a nie do sieci z pomiarem i poza tym bezczynny). Ogólnie rzecz biorąc, programista nie ma kontroli nad zestawem klientów, którzy mogą uczestniczyć w szkoleniu lub ocenie. Ponadto, ponieważ koordynowanie milionów klientów jest niepraktyczne, typowa runda szkolenia lub oceny obejmie tylko ułamek dostępnych klientów, z których można wybrać losowo .
Kluczową konsekwencją tego jest to, że obliczenia federacyjne z założenia są wyrażane w sposób, który nie uwzględnia dokładnego zestawu uczestników; całe przetwarzanie jest wyrażone jako zagregowane operacje na abstrakcyjnej grupie anonimowych klientów , a ta grupa może się różnić w zależności od rundy szkolenia. Rzeczywiste powiązanie obliczeń z konkretnymi uczestnikami, a tym samym z konkretnymi danymi, które wprowadzają do obliczeń, jest zatem modelowane poza samymi obliczeniami.
Aby zasymulować realistyczne wdrożenie federacyjnego kodu szkoleniowego, zazwyczaj napiszesz pętlę szkoleniową, która wygląda następująco:
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
Aby to ułatwić, podczas korzystania z TFF w symulacjach dane federacyjne są akceptowane jako list
w języku Python, przy czym jeden element na uczestniczące urządzenie klienckie reprezentuje lokalny tf.data.Dataset
tego urządzenia.
Interfejsy abstrakcyjne
W celu ujednolicenia postępowania z symulowanymi federacyjnymi zestawami danych, TFF zapewnia abstrakcyjny interfejs tff.simulation.datasets.ClientData
, który pozwala wyliczyć zestaw klientów i skonstruować tf.data.Dataset
zawierający dane konkretnego klient. Te tf.data.Dataset
s mogą być podawane bezpośrednio jako dane wejściowe do wygenerowanych obliczeń federacyjnych w trybie przyspieszonym.
Należy zauważyć, że możliwość uzyskiwania dostępu do tożsamości klientów jest funkcją zapewnianą przez zbiory danych wyłącznie do użytku w symulacjach, gdzie może być potrzebna umiejętność uczenia się na danych z określonych podzbiorów klientów (np. symulacja dziennej dostępności różnych rodzaje klientów). Skompilowane obliczenia i bazowe środowisko uruchomieniowe nie obejmują żadnego pojęcia tożsamości klienta. Po wybraniu danych z określonego podzbioru klientów jako danych wejściowych, np. w wywołaniu tff.templates.IterativeProcess.next
, tożsamości klientów nie będą już w nim wyświetlane.
Dostępne zestawy danych
Przestrzeń nazw tff.simulation.datasets
przeznaczyliśmy dla zestawów danych, które implementują interfejs tff.simulation.datasets.ClientData
do użytku w symulacjach, i wypełniliśmy ją zestawami danych w celu obsługi samouczków klasyfikacji obrazów i generowania tekstu . Chcielibyśmy zachęcić Cię do wniesienia własnych zestawów danych na platformę.
Przegląd
W tym dokumencie przedstawiono interfejsy, które ułatwiają zadania związane z uczeniem federacyjnym, takie jak szkolenie federacyjne lub ocena z istniejącymi modelami uczenia maszynowego zaimplementowanymi w TensorFlow. Podczas projektowania tych interfejsów naszym głównym celem było umożliwienie eksperymentowania z uczeniem federacyjnym bez konieczności posiadania wiedzy o tym, jak to działa od podstaw, oraz ocena zaimplementowanych algorytmów uczenia federacyjnego na różnych istniejących modelach i danych. Zachęcamy do współtworzenia platformy. TFF został zaprojektowany z myślą o możliwości rozbudowy i komponowania, a my czekamy na wkład; jesteśmy podekscytowani, aby zobaczyć, co wymyślisz!
Interfejsy oferowane przez tę warstwę składają się z trzech kluczowych części:
modele . Klasy i funkcje pomocnicze, które umożliwiają zawijanie istniejących modeli do użytku z TFF. Zawijanie modelu może być tak proste, jak wywołanie pojedynczej funkcji zawijającej (np.
tff.learning.models.from_keras_model
) lub zdefiniowanie podklasy interfejsutff.learning.models.VariableModel
w celu uzyskania pełnej personalizacji.Konstruktorzy obliczeń stowarzyszonych . Funkcje pomocnicze, które konstruują obliczenia stowarzyszone na potrzeby szkolenia lub oceny przy użyciu istniejących modeli.
zestawy danych . Zbiory danych w puszkach, które można pobierać i uzyskiwać do nich dostęp w języku Python, do użytku w symulowaniu scenariuszy nauczania federacyjnego. Chociaż federacyjne uczenie się jest przeznaczone do użytku ze zdecentralizowanymi danymi, których nie można po prostu pobrać w scentralizowanej lokalizacji, na etapie badań i rozwoju często wygodnie jest przeprowadzić wstępne eksperymenty z wykorzystaniem danych, które można pobrać i manipulować lokalnie, zwłaszcza dla programistów, którzy mogą być nowe podejście.
Te interfejsy są zdefiniowane głównie w przestrzeni nazw tff.learning
, z wyjątkiem zestawów danych badawczych i innych możliwości związanych z symulacją, które zostały zgrupowane w tff.simulation
. Warstwa ta jest implementowana przy użyciu interfejsów niższego poziomu oferowanych przez Federated Core (FC) , który udostępnia również środowisko uruchomieniowe.
Przed kontynuowaniem zalecamy zapoznanie się z samouczkami dotyczącymi klasyfikacji obrazów i generowania tekstu , ponieważ wprowadzają one większość opisanych tutaj pojęć na konkretnych przykładach. Jeśli chcesz dowiedzieć się więcej o tym, jak działa TFF, możesz przejrzeć samouczek dotyczący algorytmów niestandardowych jako wprowadzenie do interfejsów niższego poziomu, których używamy do wyrażania logiki obliczeń stowarzyszonych, oraz do przestudiowania istniejącej implementacji interfejsy tff.learning
.
modele
Założenia architektoniczne
Serializacja
TFF ma na celu obsługę różnych scenariuszy uczenia rozproszonego, w których napisany kod modelu uczenia maszynowego może być wykonywany na dużej liczbie heterogenicznych klientów o różnych możliwościach. Chociaż na jednym krańcu spektrum, w niektórych aplikacjach klienci ci mogą być potężnymi serwerami baz danych, wiele ważnych zastosowań, które nasza platforma zamierza obsługiwać, dotyczy urządzeń mobilnych i wbudowanych o ograniczonych zasobach. Nie możemy zakładać, że te urządzenia są w stanie obsługiwać środowiska wykonawcze Pythona; jedyne, co możemy założyć w tym momencie, to to, że są w stanie obsługiwać lokalne środowisko uruchomieniowe TensorFlow. W związku z tym fundamentalnym założeniem architektonicznym, które przyjmujemy w TFF, jest to, że kod modelu musi nadawać się do serializacji jako wykres TensorFlow.
Możesz (i powinieneś) nadal rozwijać swój kod TF zgodnie z najnowszymi najlepszymi praktykami, takimi jak korzystanie z trybu gotowości. Jednak końcowy kod musi być możliwy do serializacji (np. może być opakowany jako tf.function
dla kodu w trybie chętnym). Gwarantuje to, że każdy stan Pythona lub przepływ sterowania wymagany w czasie wykonywania może zostać zserializowany (prawdopodobnie za pomocą Autograph ).
Obecnie TensorFlow nie obsługuje w pełni serializacji i deserializacji TensorFlow w trybie gotowości. W związku z tym serializacja w TFF jest obecnie zgodna ze wzorcem TF 1.0, w którym cały kod musi być skonstruowany wewnątrz tf.Graph
, który kontroluje TFF. Oznacza to, że obecnie TFF nie może korzystać z już skonstruowanego modelu; zamiast tego logika definicji modelu jest spakowana w funkcji bez argumentów, która zwraca tff.learning.models.VariableModel
. Ta funkcja jest następnie wywoływana przez TFF, aby upewnić się, że wszystkie komponenty modelu są serializowane. Ponadto, będąc środowiskiem silnie typowanym, TFF będzie wymagać trochę dodatkowych metadanych , takich jak specyfikacja typu danych wejściowych twojego modelu.
Zbiór
Zdecydowanie zalecamy większości użytkowników tworzenie modeli przy użyciu Keras, zobacz sekcję Konwertery dla Keras poniżej. Te opakowania obsługują agregację aktualizacji modelu, a także wszelkie metryki zdefiniowane dla modelu automatycznie. Jednak nadal przydatne może być zrozumienie sposobu obsługi agregacji dla ogólnego tff.learning.models.VariableModel
.
W federacyjnym uczeniu się zawsze istnieją co najmniej dwie warstwy agregacji: agregacja lokalna na urządzeniu i agregacja między urządzeniami (lub federacyjna):
Agregacja lokalna . Ten poziom agregacji odnosi się do agregacji wielu partii przykładów należących do pojedynczego klienta. Dotyczy to zarówno parametrów modelu (zmiennych), które nadal sekwencyjnie ewoluują, gdy model jest trenowany lokalnie, jak i statystyk, które obliczasz (takich jak średnia strata, dokładność i inne metryki), które twój model będzie ponownie aktualizował lokalnie podczas iteracji lokalnego strumienia danych każdego klienta.
Wykonywanie agregacji na tym poziomie jest obowiązkiem kodu modelu i jest realizowane przy użyciu standardowych konstrukcji TensorFlow.
Ogólna struktura przetwarzania jest następująca:
Model najpierw konstruuje
tf.Variable
s do przechowywania agregatów, takich jak liczba partii lub liczba przetworzonych przykładów, suma strat na partię lub na przykład itp.TFF wielokrotnie wywołuje metodę
forward_pass
na twoimModel
, sekwencyjnie na kolejnych partiach danych klienta, co pozwala aktualizować zmienne przechowujące różne agregaty jako efekt uboczny.Na koniec TFF wywołuje metodę
report_local_unfinalized_metrics
w twoim Modelu, aby umożliwić modelowi skompilowanie wszystkich zebranych statystyk podsumowujących w zwarty zestaw metryk do wyeksportowania przez klienta. W tym miejscu kod modelu może na przykład podzielić sumę strat przez liczbę przetworzonych przykładów w celu wyeksportowania średniej straty itp.
Agregacja federacyjna . Ten poziom agregacji odnosi się do agregacji na wielu klientach (urządzeniach) w systemie. Ponownie dotyczy to zarówno parametrów modelu (zmiennych), które są uśredniane przez klientów, jak i metryk wyeksportowanych przez Twój model w wyniku lokalnej agregacji.
Za przeprowadzenie agregacji na tym poziomie odpowiada TFF. Jako twórca modelu możesz jednak kontrolować ten proces (więcej na ten temat poniżej).
Ogólna struktura przetwarzania jest następująca:
Początkowy model i wszelkie parametry wymagane do szkolenia są dystrybuowane przez serwer do podzbioru klientów, którzy wezmą udział w rundzie szkolenia lub oceny.
Na każdym kliencie, niezależnie i równolegle, kod modelu jest wielokrotnie wywoływany w strumieniu lokalnych partii danych w celu utworzenia nowego zestawu parametrów modelu (podczas uczenia) oraz nowego zestawu lokalnych metryk, jak opisano powyżej (jest to zbiór).
TFF obsługuje rozproszony protokół agregacji w celu gromadzenia i agregowania parametrów modelu oraz lokalnie eksportowanych metryk w całym systemie. Ta logika jest wyrażona w sposób deklaratywny przy użyciu własnego federacyjnego języka obliczeniowego TFF (nie w TensorFlow). Zobacz samouczek algorytmów niestandardowych, aby uzyskać więcej informacji na temat interfejsu API agregacji.
Interfejsy abstrakcyjne
Ten podstawowy interfejs konstruktora i metadanych jest reprezentowany przez interfejs tff.learning.models.VariableModel
w następujący sposób:
Konstruktor, metody
forward_pass
ireport_local_unfinalized_metrics
powinny konstruować odpowiednio zmienne modelu, przepustkę do przodu i statystyki, które chcesz raportować. TensorFlow skonstruowany za pomocą tych metod musi być możliwy do serializacji, jak omówiono powyżej.Właściwość
input_spec
, a także 3 właściwości, które zwracają podzbiory zmiennych możliwych do nauczenia, niemożliwych do nauczenia i zmiennych lokalnych, reprezentują metadane. TFF wykorzystuje te informacje do określenia, w jaki sposób połączyć części twojego modelu z federacyjnymi algorytmami optymalizacji oraz do zdefiniowania wewnętrznych sygnatur typów, aby pomóc w weryfikacji poprawności skonstruowanego systemu (aby nie można było utworzyć instancji modelu na danych, które nie pasują do tego, co model jest przeznaczony do konsumpcji).
Ponadto abstrakcyjny interfejs tff.learning.models.VariableModel
udostępnia właściwość metric_finalizers
, która przyjmuje niesfinalizowane wartości metryki (zwrócone przez report_local_unfinalized_metrics()
) i zwraca sfinalizowane wartości metryki. Metody metric_finalizers
i report_local_unfinalized_metrics()
zostaną użyte razem do zbudowania agregatora metryk między klientami podczas definiowania federacyjnych procesów szkoleniowych lub obliczeń ewaluacyjnych. Na przykład prosty agregator tff.learning.metrics.sum_then_finalize
najpierw zsumuje niesfinalizowane wartości metryk od klientów, a następnie wywoła funkcje finalizatora na serwerze.
Przykłady definiowania własnego niestandardowego tff.learning.models.VariableModel
można znaleźć w drugiej części naszego samouczka dotyczącego klasyfikacji obrazów , a także w przykładowych modelach, których używamy do testowania w model_examples.py
.
Konwertery dla Keras
Prawie wszystkie informacje wymagane przez TFF można uzyskać, wywołując interfejsy tf.keras
, więc jeśli masz model Keras, możesz polegać na tff.learning.models.from_keras_model
, aby skonstruować tff.learning.models.VariableModel
.
Zauważ, że TFF nadal chce, abyś dostarczył konstruktora - bezargumentową funkcję modelu , taką jak następująca:
def model_fn():
keras_model = ...
return tff.learning.models.from_keras_model(keras_model, sample_batch, loss=...)
Oprócz samego modelu dostarczasz przykładową partię danych, których TFF używa do określenia typu i kształtu danych wejściowych twojego modelu. Gwarantuje to, że TFF może poprawnie utworzyć instancję modelu dla danych, które faktycznie będą obecne na urządzeniach klienckich (ponieważ zakładamy, że te dane nie są ogólnie dostępne w czasie, gdy tworzysz TensorFlow do serializacji).
Użycie opakowań Keras jest zilustrowane w naszych samouczkach dotyczących klasyfikacji obrazów i generowania tekstu .
Federacyjne konstruktory obliczeń
Pakiet tff.learning
zawiera kilka konstruktorów dla tff.Computation
s, które wykonują zadania związane z uczeniem się; spodziewamy się, że zbiór takich obliczeń będzie się rozszerzał w przyszłości.
Założenia architektoniczne
Wykonanie
Istnieją dwie odrębne fazy uruchamiania obliczeń federacyjnych.
Kompiluj : TFF najpierw kompiluje algorytmy uczenia federacyjnego w abstrakcyjną serializowaną reprezentację całego rozproszonego obliczenia. To wtedy ma miejsce serializacja TensorFlow, ale mogą wystąpić inne przekształcenia w celu obsługi bardziej wydajnego wykonywania. Serializowaną reprezentację emitowaną przez kompilator nazywamy obliczeniem stowarzyszonym .
Execute TFF zapewnia sposoby wykonywania tych obliczeń. Na razie wykonanie jest obsługiwane tylko przez lokalną symulację (np. w notebooku przy użyciu symulowanych zdecentralizowanych danych).
Obliczenia federacyjne generowane przez interfejs Federated Learning API TFF, takie jak algorytm szkoleniowy wykorzystujący uśrednianie modelu federacyjnego lub ocena federacyjna, obejmują szereg elementów, w szczególności:
Zserializowana postać kodu modelu, jak również dodatkowy kod TensorFlow skonstruowany przez platformę Federated Learning w celu kierowania pętlą szkolenia/oceny modelu (taką jak konstruowanie optymalizatorów, stosowanie aktualizacji modelu, iteracja po
tf.data.Dataset
s i obliczanie metryk, i zastosowanie zagregowanej aktualizacji na serwerze, by wymienić tylko kilka).Deklaratywna specyfikacja komunikacji między klientami a serwerem (zwykle różne formy agregacji na urządzeniach klienckich i nadawanie z serwera do wszystkich klientów) oraz sposób, w jaki ta rozproszona komunikacja jest przeplatana z wykonaniem lokalnym klienta lub serwera kodu TensorFlow.
Obliczenia federacyjne reprezentowane w tej postaci serializowanej są wyrażone w niezależnym od platformy języku wewnętrznym, innym niż Python, ale aby korzystać z API Federated Learning, nie musisz zajmować się szczegółami tej reprezentacji. Obliczenia są reprezentowane w kodzie Pythona jako obiekty typu tff.Computation
, które w większości można traktować jako nieprzezroczyste callable
w Pythonie s.
W samouczkach będziesz wywoływać te federacyjne obliczenia tak, jakby były zwykłymi funkcjami Pythona, które mają być wykonywane lokalnie. Jednak TFF jest przeznaczony do wyrażania obliczeń federacyjnych w sposób niezależny od większości aspektów środowiska wykonawczego, dzięki czemu można je potencjalnie wdrażać np. w grupach urządzeń z Android
lub w klastrach w centrum danych. Ponownie, główną konsekwencją tego są silne założenia dotyczące serializacji . W szczególności, gdy wywołasz jedną z metod build_...
opisanych poniżej, obliczenia są w pełni serializowane.
Stan modelowania
TFF jest funkcjonalnym środowiskiem programistycznym, jednak wiele procesów będących przedmiotem zainteresowania federacyjnego uczenia się jest stanowych. Na przykład pętla treningowa obejmująca wiele rund uśredniania modelu federacyjnego jest przykładem tego, co możemy sklasyfikować jako proces stanowy . W tym procesie stan, który ewoluuje z rundy na rundę, obejmuje zestaw parametrów modelu, które są szkolone, i ewentualnie dodatkowy stan związany z optymalizatorem (np. wektor pędu).
Ponieważ TFF jest funkcjonalny, procesy stanowe są modelowane w TFF jako obliczenia, które akceptują bieżący stan jako dane wejściowe, a następnie dostarczają zaktualizowany stan jako dane wyjściowe. Aby w pełni zdefiniować proces stanowy, należy również określić, skąd pochodzi stan początkowy (w przeciwnym razie nie możemy uruchomić procesu). Jest to ujęte w definicji klasy pomocniczej tff.templates.IterativeProcess
, z dwiema właściwościami initialize
i next
odpowiadającymi odpowiednio inicjalizacji i iteracji.
Dostępni budowniczowie
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.