TensorFlow Federated: Comment régler la non-IIDness dans un jeu de données fédéré?

Nov 23 2020

Je teste certains algorithmes dans TensorFlow Federated (TFF). À cet égard, je voudrais les tester et les comparer sur le même ensemble de données fédérées avec différents «niveaux» d'hétérogénéité des données, c'est-à-dire non-IIDness.

Par conséquent, je voudrais savoir s'il existe un moyen de contrôler et d'ajuster le "niveau" de non-IIDness dans un ensemble de données fédéré spécifique, de manière automatique ou semi-automatique, par exemple au moyen d'API TFF ou simplement d'API TF traditionnelle (peut-être à l'intérieur des utilitaires du jeu de données).

Pour être plus pratique: par exemple, le jeu de données fédérées EMNIST fourni par TFF compte 3383 clients, chacun d'eux ayant ses caractères manuscrits. Cependant, ces données locales semblent assez équilibrées en termes de nombre d'exemples locaux et en termes de classes représentées (toutes les classes sont, plus ou moins, représentées localement). Si je souhaite avoir un ensemble de données fédéré (par exemple, en commençant par celui EMNIST du TFF), c'est:

  • Patologiquement non-IID, par exemple avoir des clients qui ne détiennent qu'une seule classe sur N classes (faisant toujours référence à une tâche de classification). Est-ce là le but de la tff.simulation.datasets.build_single_label_dataset documentation . Si tel est le cas, comment l'utiliser à partir d'un ensemble de données fédérées tel que ceux déjà fournis par TFF ?;
  • Déséquilibré en termes de quantité d'exemples locaux (par exemple, un client a 10 exemples, un autre a 100 exemples);
  • Les deux possibilités;

comment dois-je procéder dans le cadre TFF pour préparer un jeu de données fédéré avec ces caractéristiques?

Dois-je tout faire à la main? Ou certains d'entre vous ont-ils des conseils pour automatiser ce processus?

Une question supplémentaire: dans cet article "Measuring the Effects of Non-Identical Data Distribution for Federated Visual Classification" , par Hsu et al., Ils exploitent la distribution de Dirichlet pour synthétiser une population de clients non identiques, et ils utilisent un paramètre de concentration pour contrôler l'identité entre les clients. Cela semble être un moyen facile à régler pour produire des ensembles de données avec différents niveaux d'hétérogénéité. Tout conseil sur la façon de mettre en œuvre cette stratégie (ou une stratégie similaire) dans le framework TFF, ou simplement dans TensorFlow (Python) en considérant un jeu de données simple tel que EMNIST, serait également très utile.

Merci beaucoup.

Réponses

2 ZacharyGarrett Nov 25 2020 at 07:46

Pour les simulations Federated Learning, il est tout à fait raisonnable de configurer les ensembles de données client en Python, dans le pilote d'expérimentation, pour obtenir les distributions souhaitées. À un niveau élevé, TFF gère la modélisation de l'emplacement des données ("placements" dans le système de types) et la logique de calcul. Le remixage / génération d'un jeu de données de simulation n'est pas tout à fait au cœur de la bibliothèque, bien qu'il existe des bibliothèques utiles comme vous l'avez trouvé. Faire cela directement en python en manipulant tf.data.Datasetpuis en "poussant" les ensembles de données client dans un calcul TFF semble simple.

Étiquette non-IID

Oui, tff.simulation.datasets.build_single_label_datasetest destiné à cet effet.

Il prend a tf.data.Datasetet filtre essentiellement tous les exemples qui ne correspondent pas aux desired_labelvaleurs de label_key(en supposant que l'ensemble de données donne des dictstructures similaires).

Pour EMNIST, pour créer un ensemble de données de tous (quel que soit l'utilisateur), cela pourrait être réalisé en:

train_data, _ = tff.simulation.datasets.emnist.load_data()
ones = tff.simulation.datasets.build_single_label_dataset(
  train_data.create_tf_dataset_from_all_clients(),
  label_key='label', desired_label=1)
print(ones.element_spec)
>>> OrderedDict([('label', TensorSpec(shape=(), dtype=tf.int32, name=None)), ('pixels', TensorSpec(shape=(28, 28), dtype=tf.float32, name=None))])
print(next(iter(ones))['label'])
>>> tf.Tensor(1, shape=(), dtype=int32)

Déséquilibre des données

L'utilisation d'une combinaison de tf.data.Dataset.repeatet tf.data.Dataset.takepeut être utilisée pour créer des déséquilibres de données.

train_data, _ = tff.simulation.datasets.emnist.load_data()
datasets = [train_data.create_tf_dataset_for_client(id) for id in train_data.client_ids[:2]]
print([tf.data.experimental.cardinality(ds).numpy() for ds in datasets])
>>> [93, 109]
datasets[0] = datasets[0].repeat(5)
datasets[1] = datasets[1].take(5)
print([tf.data.experimental.cardinality(ds).numpy() for ds in datasets])
>>> [465, 5]