Apprentissage fédéré

Restez organisé à l'aide des collections Enregistrez et classez les contenus selon vos préférences.

Aperçu

Ce document présente des interfaces qui facilitent les tâches d'apprentissage fédéré, telles que la formation fédérée ou l'évaluation avec des modèles d'apprentissage automatique existants implémentés dans TensorFlow. Lors de la conception de ces interfaces, notre objectif principal était de rendre possible l'expérimentation de l'apprentissage fédéré sans nécessiter la connaissance de son fonctionnement sous le capot, et d'évaluer les algorithmes d'apprentissage fédéré mis en œuvre sur une variété de modèles et de données existants. Nous vous encourageons à contribuer à la plateforme. TFF a été conçu dans un souci d'extensibilité et de composabilité, et nous accueillons les contributions ; nous sommes impatients de voir ce que vous proposez !

Les interfaces offertes par cette couche se composent des trois éléments clés suivants :

  • Modèles . Classes et fonctions d'assistance qui vous permettent d'encapsuler vos modèles existants pour les utiliser avec TFF. L'encapsulation d'un modèle peut être aussi simple que d'appeler une seule fonction d'encapsulation (par exemple, tff.learning.from_keras_model ) ou de définir une sous-classe de l'interface tff.learning.models.VariableModel pour une personnalisation complète.

  • Constructeurs de calculs fédérés . Fonctions d'assistance qui construisent des calculs fédérés pour la formation ou l'évaluation, à l'aide de vos modèles existants.

  • Ensembles de données . Collections prédéfinies de données que vous pouvez télécharger et accéder en Python pour une utilisation dans la simulation de scénarios d'apprentissage fédéré. Bien que l'apprentissage fédéré soit conçu pour être utilisé avec des données décentralisées qui ne peuvent pas être simplement téléchargées à un emplacement centralisé, aux stades de la recherche et du développement, il est souvent pratique de mener des expériences initiales en utilisant des données qui peuvent être téléchargées et manipulées localement, en particulier pour les développeurs qui pourraient être nouveau dans l'approche.

Ces interfaces sont définies principalement dans l'espace de noms tff.learning , à l'exception des ensembles de données de recherche et d'autres fonctionnalités liées à la simulation qui ont été regroupées dans tff.simulation . Cette couche est implémentée à l'aide d'interfaces de niveau inférieur proposées par le Federated Core (FC) , qui fournit également un environnement d'exécution.

Avant de poursuivre, nous vous recommandons de consulter d'abord les didacticiels sur la classification d'images et la génération de texte , car ils présentent la plupart des concepts décrits ici à l'aide d'exemples concrets. Si vous souhaitez en savoir plus sur le fonctionnement de TFF, vous pouvez parcourir le didacticiel sur les algorithmes personnalisés en tant qu'introduction aux interfaces de niveau inférieur que nous utilisons pour exprimer la logique des calculs fédérés et pour étudier l'implémentation existante de la interfaces tff.learning .

Des modèles

Hypothèses architecturales

Sérialisation

TFF vise à prendre en charge une variété de scénarios d'apprentissage distribué dans lesquels le code du modèle d'apprentissage automatique que vous écrivez peut s'exécuter sur un grand nombre de clients hétérogènes avec des capacités diverses. Alors qu'à une extrémité du spectre, dans certaines applications, ces clients peuvent être de puissants serveurs de base de données, de nombreuses utilisations importantes que notre plate-forme entend prendre en charge impliquent des appareils mobiles et intégrés avec des ressources limitées. Nous ne pouvons pas supposer que ces appareils sont capables d'héberger des runtimes Python ; la seule chose que nous pouvons supposer à ce stade est qu'ils sont capables d'héberger un runtime TensorFlow local. Ainsi, une hypothèse architecturale fondamentale que nous faisons dans TFF est que votre code de modèle doit être sérialisable en tant que graphe TensorFlow.

Vous pouvez (et devriez) toujours développer votre code TF en suivant les dernières meilleures pratiques comme l'utilisation du mode impatient. Cependant, le code final doit être sérialisable (par exemple, peut être enveloppé comme une tf.function pour le code en mode impatient). Cela garantit que tout état Python ou flux de contrôle nécessaire au moment de l'exécution peut être sérialisé (éventuellement à l'aide de Autograph ).

Actuellement, TensorFlow ne prend pas entièrement en charge la sérialisation et la désérialisation de TensorFlow en mode impatient. Ainsi, la sérialisation dans TFF suit actuellement le modèle TF 1.0, où tout le code doit être construit à l'intérieur d'un tf.Graph que TFF contrôle. Cela signifie qu'actuellement, TFF ne peut pas utiliser un modèle déjà construit ; à la place, la logique de définition du modèle est empaquetée dans une fonction sans argument qui renvoie un tff.learning.models.VariableModel . Cette fonction est ensuite appelée par TFF pour s'assurer que tous les composants du modèle sont sérialisés. De plus, étant un environnement fortement typé, TFF nécessitera un peu de métadonnées supplémentaires, telles qu'une spécification du type d'entrée de votre modèle.

Agrégation

Nous recommandons fortement à la plupart des utilisateurs de construire des modèles à l'aide de Keras, voir la section Convertisseurs pour Keras ci-dessous. Ces wrappers gèrent automatiquement l'agrégation des mises à jour du modèle ainsi que toutes les métriques définies pour le modèle. Cependant, il peut toujours être utile de comprendre comment l'agrégation est gérée pour un tff.learning.models.VariableModel général.

Il existe toujours au moins deux couches d'agrégation dans l'apprentissage fédéré : l'agrégation locale sur l'appareil et l'agrégation inter-appareils (ou fédérée) :

  • Agrégation locale . Ce niveau d'agrégation fait référence à l'agrégation de plusieurs lots d'exemples appartenant à un client individuel. Il s'applique à la fois aux paramètres du modèle (variables), qui continuent d'évoluer séquentiellement au fur et à mesure que le modèle est formé localement, ainsi qu'aux statistiques que vous calculez (telles que la perte moyenne, la précision et d'autres mesures), que votre modèle mettra à nouveau à jour localement. car il itère sur le flux de données local de chaque client individuel.

    L'agrégation à ce niveau relève de la responsabilité du code de votre modèle et s'effectue à l'aide de constructions TensorFlow standard.

    La structure générale du traitement est la suivante :

    • Le modèle construit d'abord tf.Variable s pour contenir des agrégats, tels que le nombre de lots ou le nombre d'exemples traités, la somme des pertes par lot ou par exemple, etc.

    • TFF appelle plusieurs fois la méthode forward_pass sur votre Model , de manière séquentielle sur les lots suivants de données client, ce qui vous permet de mettre à jour les variables contenant divers agrégats comme effet secondaire.

    • Enfin, TFF appelle la méthode report_local_unfinalized_metrics sur votre modèle pour permettre à votre modèle de compiler toutes les statistiques récapitulatives qu'il a collectées dans un ensemble compact de métriques à exporter par le client. C'est là que votre code de modèle peut, par exemple, diviser la somme des pertes par le nombre d'exemples traités pour exporter la perte moyenne, etc.

  • Agrégation fédérée . Ce niveau d'agrégation fait référence à l'agrégation sur plusieurs clients (appareils) du système. Encore une fois, cela s'applique à la fois aux paramètres du modèle (variables), dont la moyenne est calculée sur les clients, ainsi qu'aux métriques que votre modèle a exportées à la suite de l'agrégation locale.

    L'agrégation à ce niveau relève de la responsabilité de la TFF. En tant que créateur de modèle, cependant, vous pouvez contrôler ce processus (plus d'informations à ce sujet ci-dessous).

    La structure générale du traitement est la suivante :

    • Le modèle initial et tous les paramètres requis pour la formation sont distribués par un serveur à un sous-ensemble de clients qui participeront à un cycle de formation ou d'évaluation.

    • Sur chaque client, indépendamment et en parallèle, votre code de modèle est appelé à plusieurs reprises sur un flux de lots de données locaux pour produire un nouvel ensemble de paramètres de modèle (lors de la formation) et un nouvel ensemble de métriques locales, comme décrit ci-dessus (c'est local agrégation).

    • TFF exécute un protocole d'agrégation distribué pour accumuler et agréger les paramètres du modèle et les métriques exportées localement à travers le système. Cette logique est exprimée de manière déclarative à l'aide du propre langage de calcul fédéré de TFF (pas dans TensorFlow). Consultez le didacticiel sur les algorithmes personnalisés pour en savoir plus sur l'API d'agrégation.

Interfaces abstraites

Cette interface constructeur + métadonnées de base est représentée par l'interface tff.learning.models.VariableModel , comme suit :

  • Les méthodes constructeur, forward_pass et report_local_unfinalized_metrics doivent construire les variables de modèle, la passe avant et les statistiques que vous souhaitez signaler, en conséquence. Le TensorFlow construit par ces méthodes doit être sérialisable, comme indiqué ci-dessus.

  • La propriété input_spec , ainsi que les 3 propriétés qui renvoient des sous-ensembles de vos variables entraînables, non entraînables et locales représentent les métadonnées. TFF utilise ces informations pour déterminer comment connecter des parties de votre modèle aux algorithmes d'optimisation fédérés et pour définir des signatures de type internes pour aider à vérifier l'exactitude du système construit (afin que votre modèle ne puisse pas être instancié sur des données qui ne correspondent pas à ce le modèle est conçu pour consommer).

De plus, l'interface abstraite tff.learning.models.VariableModel expose une propriété metric_finalizers qui prend les valeurs non finalisées d'une métrique (renvoyées par report_local_unfinalized_metrics() ) et renvoie les valeurs de métrique finalisées. Les méthodes metric_finalizers et report_local_unfinalized_metrics() seront utilisées ensemble pour créer un agrégateur de métriques inter-clients lors de la définition des processus de formation fédérés ou des calculs d'évaluation. Par exemple, un simple agrégateur tff.learning.metrics.sum_then_finalize additionnera d'abord les valeurs de métrique non finalisées des clients, puis appellera les fonctions de finalisation sur le serveur.

Vous pouvez trouver des exemples de définition de votre propre tff.learning.models.VariableModel personnalisé dans la deuxième partie de notre didacticiel de classification d'images , ainsi que dans les exemples de modèles que nous utilisons pour les tests dans model_examples.py .

Convertisseurs pour Keras

Presque toutes les informations requises par TFF peuvent être dérivées en appelant les interfaces tf.keras , donc si vous avez un modèle Keras, vous pouvez compter sur tff.learning.from_keras_model pour construire un tff.learning.models.VariableModel .

Notez que TFF souhaite toujours que vous fournissiez un constructeur - une fonction de modèle sans argument telle que la suivante :

def model_fn():
  keras_model = ...
  return tff.learning.from_keras_model(keras_model, sample_batch, loss=...)

En plus du modèle lui-même, vous fournissez un exemple de lot de données que TFF utilise pour déterminer le type et la forme de l'entrée de votre modèle. Cela garantit que TFF peut correctement instancier le modèle pour les données qui seront réellement présentes sur les appareils clients (puisque nous supposons que ces données ne sont généralement pas disponibles au moment où vous construisez le TensorFlow à sérialiser).

L'utilisation des wrappers Keras est illustrée dans nos tutoriels de classification d'images et de génération de texte .

Générateurs de calculs fédérés

Le package tff.learning fournit plusieurs générateurs pour tff.Computation qui effectuent des tâches liées à l'apprentissage ; nous nous attendons à ce que l'ensemble de ces calculs se développe à l'avenir.

Hypothèses architecturales

Exécution

Il existe deux phases distinctes dans l'exécution d'un calcul fédéré.

  • Compiler : TFF compile d'abord les algorithmes d'apprentissage fédéré en une représentation sérialisée abstraite de l'ensemble du calcul distribué. C'est à ce moment que la sérialisation de TensorFlow se produit, mais d'autres transformations peuvent se produire pour prendre en charge une exécution plus efficace. Nous appelons calcul fédéré la représentation sérialisée émise par le compilateur.

  • Execute TFF fournit des moyens d' exécuter ces calculs. Pour l'instant, l'exécution n'est prise en charge que via une simulation locale (par exemple, dans un notebook utilisant des données décentralisées simulées).

Un calcul fédéré généré par l'API d'apprentissage fédéré de TFF, tel qu'un algorithme de formation qui utilise la moyenne d'un modèle fédéré ou une évaluation fédérée, comprend un certain nombre d'éléments, notamment :

  • Une forme sérialisée de votre code de modèle ainsi que du code TensorFlow supplémentaire construit par le framework d'apprentissage fédéré pour piloter la boucle de formation/d'évaluation de votre modèle (comme la construction d'optimiseurs, l'application de mises à jour de modèle, l'itération sur tf.data.Dataset s et le calcul de métriques, et appliquer la mise à jour agrégée sur le serveur, pour n'en nommer que quelques-uns).

  • Une spécification déclarative de la communication entre les clients et un serveur (généralement diverses formes d' agrégation entre les appareils clients et la diffusion du serveur à tous les clients), et comment cette communication distribuée est entrelacée avec l'exécution client-local ou serveur-local du code TensorFlow.

Les calculs fédérés représentés sous cette forme sérialisée sont exprimés dans un langage interne indépendant de la plate-forme distinct de Python, mais pour utiliser l'API d'apprentissage fédéré, vous n'aurez pas besoin de vous préoccuper des détails de cette représentation. Les calculs sont représentés dans votre code Python sous la forme d'objets de type tff.Computation , que vous pouvez pour la plupart traiter comme des s callable Python opaques.

Dans les didacticiels, vous invoquerez ces calculs fédérés comme s'il s'agissait de fonctions Python normales, à exécuter localement. Cependant, TFF est conçu pour exprimer des calculs fédérés d'une manière indépendante de la plupart des aspects de l'environnement d'exécution, de sorte qu'ils peuvent potentiellement être déployés, par exemple, sur des groupes d'appareils exécutant Android ou sur des clusters dans un centre de données. Encore une fois, la principale conséquence de ceci sont des hypothèses fortes sur la sérialisation . En particulier, lorsque vous appelez l'une des méthodes build_... décrites ci-dessous, le calcul est entièrement sérialisé.

État de modélisation

TFF est un environnement de programmation fonctionnel, mais de nombreux processus d'intérêt dans l'apprentissage fédéré sont avec état. Par exemple, une boucle de formation qui implique plusieurs cycles de calcul de la moyenne d'un modèle fédéré est un exemple de ce que nous pourrions classer comme un processus avec état . Dans ce processus, l'état qui évolue d'un cycle à l'autre comprend l'ensemble des paramètres du modèle qui sont en cours d'apprentissage, et éventuellement un état supplémentaire associé à l'optimiseur (par exemple, un vecteur d'impulsion).

Puisque TFF est fonctionnel, les processus avec état sont modélisés dans TFF comme des calculs qui acceptent l'état actuel comme entrée, puis fournissent l'état mis à jour comme sortie. Afin de définir complètement un processus avec état, il faut également spécifier d'où vient l'état initial (sinon nous ne pouvons pas amorcer le processus). Ceci est capturé dans la définition de la classe d'assistance tff.templates.IterativeProcess , avec les 2 propriétés initialize et next correspondant respectivement à l'initialisation et à l'itération.

Constructeurs disponibles

À l'heure actuelle, TFF fournit diverses fonctions de création qui génèrent des calculs fédérés pour la formation et l'évaluation fédérées. Deux exemples notables incluent:

Jeux de données

Hypothèses architecturales

Sélection des clients

Dans le scénario d'apprentissage fédéré typique, nous avons une grande population de centaines de millions d'appareils clients, dont seule une petite partie peut être active et disponible pour la formation à un moment donné (par exemple, cela peut être limité aux clients qui sont branché à une source d'alimentation, pas sur un réseau mesuré, et autrement inactif). Généralement, l'ensemble des clients disponibles pour participer à la formation ou à l'évaluation est hors du contrôle du développeur. De plus, comme il n'est pas pratique de coordonner des millions de clients, un cycle typique de formation ou d'évaluation n'inclura qu'une fraction des clients disponibles, qui peuvent être échantillonnés au hasard .

La principale conséquence de ceci est que les calculs fédérés, par conception, sont exprimés d'une manière qui ne tient pas compte de l'ensemble exact de participants ; tous les traitements sont exprimés sous forme d'opérations agrégées sur un groupe abstrait de clients anonymes, et ce groupe peut varier d'un cycle de formation à l'autre. La liaison réelle du calcul aux participants concrets, et donc aux données concrètes qu'ils alimentent dans le calcul, est ainsi modélisée en dehors du calcul lui-même.

Afin de simuler un déploiement réaliste de votre code d'apprentissage fédéré, vous écrirez généralement une boucle de formation qui ressemble à ceci :

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

Afin de faciliter cela, lors de l'utilisation de TFF dans des simulations, les données fédérées sont acceptées en tant que list Python, avec un élément par périphérique client participant pour représenter le tf.data.Dataset local de ce périphérique.

Interfaces abstraites

Afin de normaliser le traitement des ensembles de données fédérés simulés, TFF fournit une interface abstraite tff.simulation.datasets.ClientData , qui permet d'énumérer l'ensemble de clients et de construire un tf.data.Dataset qui contient les données d'un particulier client. Ces tf.data.Dataset s peuvent être alimentés directement en entrée des calculs fédérés générés en mode impatient.

Il convient de noter que la possibilité d'accéder aux identités des clients est une fonctionnalité fournie uniquement par les ensembles de données à utiliser dans les simulations, où la capacité de s'entraîner sur les données de sous-ensembles spécifiques de clients peut être nécessaire (par exemple, pour simuler la disponibilité diurne de différents type de clientèle). Les calculs compilés et le runtime sous-jacent n'impliquent aucune notion d'identité du client. Une fois que les données d'un sous-ensemble spécifique de clients ont été sélectionnées comme entrée, par exemple, dans un appel à tff.templates.IterativeProcess.next , les identités des clients n'y apparaissent plus.

Ensembles de données disponibles

Nous avons dédié l'espace de noms tff.simulation.datasets aux ensembles de données qui implémentent l'interface tff.simulation.datasets.ClientData pour une utilisation dans les simulations, et l'avons ensemencé avec des ensembles de données pour prendre en charge les didacticiels de classification d'images et de génération de texte . Nous aimerions vous encourager à contribuer vos propres ensembles de données à la plate-forme.