TensorFlow Federated: Wie kann ich die Nicht-IIDness im Verbunddatensatz optimieren?

Nov 23 2020

Ich teste einige Algorithmen in TensorFlow Federated (TFF). In diesem Zusammenhang möchte ich sie auf demselben Verbunddatensatz mit unterschiedlichen "Ebenen" der Datenheterogenität, dh Nicht-IIDness, testen und vergleichen.

Daher möchte ich wissen, ob es eine Möglichkeit gibt, das "Niveau" der Nicht-IIDness in einem bestimmten Verbunddatensatz automatisch oder halbautomatisch zu steuern und abzustimmen, z. B. mithilfe von TFF-APIs oder nur mit herkömmlichen TF-APIs (Möglicherweise in den Dataset-Dienstprogrammen).

Praktischer ausgedrückt: Der von TFF bereitgestellte EMNIST-Verbunddatensatz enthält beispielsweise 3383 Clients, von denen jeder seine handgeschriebenen Zeichen hat. Dieser lokale Datensatz scheint jedoch in Bezug auf die Anzahl der lokalen Beispiele und die dargestellten Klassen ziemlich ausgewogen zu sein (alle Klassen sind mehr oder weniger lokal vertreten). Wenn ich einen Verbunddatensatz haben möchte (z. B. beginnend mit dem EMNIST-Datensatz des TFF), ist dies:

  • Patologisch nicht IID, zum Beispiel mit Clients, die nur eine Klasse von N Klassen halten (immer bezogen auf eine Klassifizierungsaufgabe). Ist dies der Zweck der tff.simulation.datasets.build_single_label_dataset Dokumentation hier . Wenn ja, wie soll ich es aus einem Verbunddatensatz verwenden, wie er bereits von TFF bereitgestellt wurde?;
  • Unausgewogen in Bezug auf die Anzahl der lokalen Beispiele (z. B. hat ein Kunde 10 Beispiele, ein anderer 100 Beispiele);
  • Beide Möglichkeiten;

Wie soll ich innerhalb des TFF-Frameworks vorgehen, um einen Verbunddatensatz mit diesen Merkmalen vorzubereiten?

Soll ich das alles von Hand machen? Oder haben einige von Ihnen Ratschläge, um diesen Prozess zu automatisieren?

Eine zusätzliche Frage: In diesem Artikel "Messung der Auswirkungen nicht identischer Datenverteilung auf die föderierte visuelle Klassifizierung" von Hsu et al. Nutzen sie die Dirichlet-Verteilung, um eine Population nicht identischer Clients zu synthetisieren, und verwenden einen Konzentrationsparameter die Identität zwischen Kunden zu kontrollieren. Dies scheint eine unkomplizierte Methode zu sein, um Datensätze mit unterschiedlichem Grad an Heterogenität zu erstellen. Alle Ratschläge zur Implementierung dieser Strategie (oder einer ähnlichen Strategie) innerhalb des TFF-Frameworks oder nur in TensorFlow (Python) unter Berücksichtigung eines einfachen Datensatzes wie EMNIST wären ebenfalls sehr nützlich.

Vielen Dank.

Antworten

2 ZacharyGarrett Nov 25 2020 at 07:46

Für Federated Learning-Simulationen ist es durchaus sinnvoll, die Client-Datasets in Python im Experiment-Treiber einzurichten, um die gewünschten Verteilungen zu erzielen. Auf einer höheren Ebene übernimmt TFF die Modellierung der Datenposition ("Platzierungen" im Typsystem) und die Berechnungslogik. Das erneute Mischen / Generieren eines Simulationsdatensatzes ist nicht ganz der Kern der Bibliothek, obwohl es hilfreiche Bibliotheken gibt, wie Sie gefunden haben. Dies direkt in Python zu tun, tf.data.Datasetindem die Client-Datasets manipuliert und dann in eine TFF-Berechnung "verschoben" werden, scheint unkompliziert.

Nicht-IID kennzeichnen

Ja, tff.simulation.datasets.build_single_label_datasetist für diesen Zweck vorgesehen.

Es dauert ein tf.data.Datasetund filtert im Wesentlichen alle Beispiele heraus, die nicht mit den desired_labelWerten für übereinstimmen label_key(vorausgesetzt, der Datensatz liefert dictähnliche Strukturen).

Für EMNIST kann dies erreicht werden, um einen Datensatz aller (unabhängig vom Benutzer) zu erstellen :

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)

Datenungleichgewicht

Mithilfe einer Kombination von tf.data.Dataset.repeatund tf.data.Dataset.takekönnen Datenungleichgewichte erstellt werden.

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]