TensorFlow Federated: Comment régler la non-IIDness dans un jeu de données fédéré?
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
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.Dataset
puis 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.Dataset
et filtre essentiellement tous les exemples qui ne correspondent pas aux desired_label
valeurs de label_key
(en supposant que l'ensemble de données donne des dict
structures 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]