TensorFlow Federated: Jak dostroić brak IIDness w sfederowanym zbiorze danych?
Testuję niektóre algorytmy w TensorFlow Federated (TFF). W związku z tym chciałbym przetestować i porównać je na tym samym sfederowanym zbiorze danych z różnymi „poziomami” heterogeniczności danych, tj. Brakiem IID.
W związku z tym chciałbym wiedzieć, czy istnieje sposób kontrolowania i dostrajania „poziomu” braku IIDness w określonym sfederowanym zbiorze danych, w sposób automatyczny lub półautomatyczny, np. Za pomocą TFF API lub po prostu tradycyjnego TF API (być może wewnątrz narzędzi Dataset).
Aby być bardziej praktycznym: na przykład sfederowany zbiór danych EMNIST dostarczony przez TFF ma 3383 klientów, a każdy z nich ma swoje odręczne znaki. Jednak ten lokalny zbiór danych wydaje się być dość zrównoważony pod względem liczby lokalnych przykładów i pod względem reprezentowanych klas (wszystkie klasy są w mniejszym lub większym stopniu reprezentowane lokalnie). Jeśli chciałbym mieć sfederowany zbiór danych (np. Zaczynając od zbioru EMNIST TFF), to jest:
- Patologicznie nie-IID, na przykład klienci, którzy mają tylko jedną klasę z N klas (zawsze odnosząc się do zadania klasyfikacyjnego). Czy taki jest cel
tff.simulation.datasets.build_single_label_dataset
dokumentacji tutaj . Jeśli tak, w jaki sposób powinienem go używać ze sfederowanego zbioru danych, takiego jak te już udostępnione przez TFF ?; - Niezrównoważony pod względem ilości lokalnych przykładów (np. Jeden klient ma 10 przykładów, inny 100);
- Obie możliwości;
jak powinienem postępować w ramach TFF, aby przygotować federacyjny zestaw danych o takich cechach?
Czy powinienem zrobić wszystko ręcznie? A może ktoś z was ma jakieś rady, jak zautomatyzować ten proces?
Dodatkowe pytanie: w tym artykule „Measuring the Effects of Non-Identical Data Distribution for Federated Visual Classification” , autorstwa Hsu i wsp., Wykorzystują oni rozkład Dirichleta do syntezy populacji nieidentycznych klientów i używają parametru stężenia do kontrolowania identyczności wśród klientów. Wydaje się, że jest to niezbyt dostosowany sposób tworzenia zbiorów danych o różnych poziomach heterogeniczności. Wszelkie porady dotyczące wdrażania tej strategii (lub podobnej) wewnątrz frameworka TFF lub po prostu w TensorFlow (Python), biorąc pod uwagę prosty zestaw danych, taki jak EMNIST, byłyby również bardzo przydatne.
Dziękuję bardzo.
Odpowiedzi
W przypadku symulacji Federated Learning całkiem rozsądne jest skonfigurowanie zestawów danych klienta w Pythonie, w sterowniku eksperymentu, w celu uzyskania pożądanych rozkładów. Na niektórych wysokim poziomie TFF zajmuje się modelowaniem lokalizacji danych („umiejscowienia” w systemie typów) i logiką obliczeniową. Ponowne mieszanie / generowanie zestawu danych symulacji nie jest do końca podstawą biblioteki, chociaż istnieją pomocne biblioteki, jak znalazłeś. Robienie tego bezpośrednio w Pythonie poprzez manipulowanie, tf.data.Dataset
a następnie „wypychanie” zestawów danych klienta do obliczenia TFF wydaje się proste.
Etykieta inna niż IID
Tak, tff.simulation.datasets.build_single_label_datasetjest przeznaczony do tego celu.
Pobiera a tf.data.Dataset
i zasadniczo odfiltrowuje wszystkie przykłady, które nie pasują do desired_label
wartości dla label_key
(zakładając, że zbiór danych daje dict
podobne struktury).
W przypadku EMNIST, aby utworzyć zbiór danych wszystkich (niezależnie od użytkownika), można to osiągnąć poprzez:
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)
Brak równowagi danych
Używanie kombinacji tf.data.Dataset.repeati tf.data.Dataset.takemoże służyć do tworzenia nierównowagi danych.
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]