DĂ©marrage rapide de TensorFlow#

Construisons un système d’apprentissage fédéré en moins de 20 lignes de code !

Avant de pouvoir importer une fleur, nous devons l’installer :

$ pip install flwr

Comme nous voulons utiliser l’API Keras de TensorFlow (TF), nous devons également installer TF :

$ pip install tensorflow

Client de la fleur#

Ensuite, dans un fichier appelé client.py, importe Flower et TensorFlow :

import flwr as fl
import tensorflow as tf

Nous utilisons les utilitaires Keras de TF pour charger CIFAR10, un ensemble de données de classification d’images colorées populaire pour l’apprentissage automatique. L’appel à tf.keras.datasets.cifar10.load_data() télécharge CIFAR10, le met en cache localement, puis renvoie l’ensemble d’entraînement et de test sous forme de NumPy ndarrays.

(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()

Ensuite, nous avons besoin d’un modèle. Pour les besoins de ce tutoriel, nous utilisons MobilNetV2 avec 10 classes de sortie :

model = tf.keras.applications.MobileNetV2((32, 32, 3), classes=10, weights=None)
model.compile("adam", "sparse_categorical_crossentropy", metrics=["accuracy"])

Le serveur Flower interagit avec les clients par le biais d’une interface appelée Client. Lorsque le serveur sélectionne un client particulier pour la formation, il envoie des instructions de formation sur le réseau. Le client reçoit ces instructions et appelle l’une des méthodes Client pour exécuter ton code (c’est-à-dire pour former le réseau neuronal que nous avons défini plus tôt).

Flower fournit une classe de commodité appelée NumPyClient qui facilite la mise en œuvre de l’interface Client lorsque ta charge de travail utilise Keras. L’interface NumPyClient définit trois méthodes qui peuvent être mises en œuvre de la manière suivante :

class CifarClient(fl.client.NumPyClient):
    def get_parameters(self, config):
        return model.get_weights()

    def fit(self, parameters, config):
        model.set_weights(parameters)
        model.fit(x_train, y_train, epochs=1, batch_size=32, steps_per_epoch=3)
        return model.get_weights(), len(x_train), {}

    def evaluate(self, parameters, config):
        model.set_weights(parameters)
        loss, accuracy = model.evaluate(x_test, y_test)
        return loss, len(x_test), {"accuracy": float(accuracy)}

Nous pouvons maintenant créer une instance de notre classe CifarClient et ajouter une ligne pour exécuter ce client :

fl.client.start_numpy_client(server_address="[::]:8080", client=CifarClient())

C’est tout pour le client. Il nous suffit d’implémenter Client ou NumPyClient et d’appeler fl.client.start_client() ou fl.client.start_numpy_client(). La chaîne "[: :]:8080" indique au client à quel serveur se connecter. Dans notre cas, nous pouvons exécuter le serveur et le client sur la même machine, c’est pourquoi nous utilisons "[: :]:8080". Si nous exécutons une charge de travail véritablement fédérée avec le serveur et les clients fonctionnant sur des machines différentes, tout ce qui doit changer est l’adresse server_address vers laquelle nous dirigeons le client.

Serveur de Flower#

Pour les charges de travail simples, nous pouvons démarrer un serveur Flower et laisser toutes les possibilités de configuration à leurs valeurs par défaut. Dans un fichier nommé server.py, importe Flower et démarre le serveur :

import flwr as fl

fl.server.start_server(config=fl.server.ServerConfig(num_rounds=3))

Entraîne le modèle, fédéré !#

Le client et le serveur étant prêts, nous pouvons maintenant tout exécuter et voir l’apprentissage fédéré en action. Les systèmes FL ont généralement un serveur et plusieurs clients. Nous devons donc commencer par démarrer le serveur :

$ python server.py

Une fois que le serveur fonctionne, nous pouvons démarrer les clients dans différents terminaux. Ouvre un nouveau terminal et démarre le premier client :

$ python client.py

Ouvre un autre terminal et démarre le deuxième client :

$ python client.py

Chaque client aura son propre ensemble de données.

Tu devrais maintenant voir comment la formation se déroule dans le tout premier terminal (celui qui a démarré le serveur) :

INFO flower 2021-02-25 14:15:46,741 | app.py:76 | Flower server running (insecure, 3 rounds)
INFO flower 2021-02-25 14:15:46,742 | server.py:72 | Getting initial parameters
INFO flower 2021-02-25 14:16:01,770 | server.py:74 | Evaluating initial parameters
INFO flower 2021-02-25 14:16:01,770 | server.py:87 | [TIME] FL starting
DEBUG flower 2021-02-25 14:16:12,341 | server.py:165 | fit_round: strategy sampled 2 clients (out of 2)
DEBUG flower 2021-02-25 14:21:17,235 | server.py:177 | fit_round received 2 results and 0 failures
DEBUG flower 2021-02-25 14:21:17,512 | server.py:139 | evaluate: strategy sampled 2 clients
DEBUG flower 2021-02-25 14:21:29,628 | server.py:149 | evaluate received 2 results and 0 failures
DEBUG flower 2021-02-25 14:21:29,696 | server.py:165 | fit_round: strategy sampled 2 clients (out of 2)
DEBUG flower 2021-02-25 14:25:59,917 | server.py:177 | fit_round received 2 results and 0 failures
DEBUG flower 2021-02-25 14:26:00,227 | server.py:139 | evaluate: strategy sampled 2 clients
DEBUG flower 2021-02-25 14:26:11,457 | server.py:149 | evaluate received 2 results and 0 failures
DEBUG flower 2021-02-25 14:26:11,530 | server.py:165 | fit_round: strategy sampled 2 clients (out of 2)
DEBUG flower 2021-02-25 14:30:43,389 | server.py:177 | fit_round received 2 results and 0 failures
DEBUG flower 2021-02-25 14:30:43,630 | server.py:139 | evaluate: strategy sampled 2 clients
DEBUG flower 2021-02-25 14:30:53,384 | server.py:149 | evaluate received 2 results and 0 failures
INFO flower 2021-02-25 14:30:53,384 | server.py:122 | [TIME] FL finished in 891.6143046000007
INFO flower 2021-02-25 14:30:53,385 | app.py:109 | app_fit: losses_distributed [(1, 2.3196680545806885), (2, 2.3202896118164062), (3, 2.1818180084228516)]
INFO flower 2021-02-25 14:30:53,385 | app.py:110 | app_fit: accuracies_distributed []
INFO flower 2021-02-25 14:30:53,385 | app.py:111 | app_fit: losses_centralized []
INFO flower 2021-02-25 14:30:53,385 | app.py:112 | app_fit: accuracies_centralized []
DEBUG flower 2021-02-25 14:30:53,442 | server.py:139 | evaluate: strategy sampled 2 clients
DEBUG flower 2021-02-25 14:31:02,848 | server.py:149 | evaluate received 2 results and 0 failures
INFO flower 2021-02-25 14:31:02,848 | app.py:121 | app_evaluate: federated loss: 2.1818180084228516
INFO flower 2021-02-25 14:31:02,848 | app.py:125 | app_evaluate: results [('ipv4:127.0.0.1:57158', EvaluateRes(loss=2.1818180084228516, num_examples=10000, accuracy=0.0, metrics={'accuracy': 0.21610000729560852})), ('ipv4:127.0.0.1:57160', EvaluateRes(loss=2.1818180084228516, num_examples=10000, accuracy=0.0, metrics={'accuracy': 0.21610000729560852}))]
INFO flower 2021-02-25 14:31:02,848 | app.py:127 | app_evaluate: failures [] flower 2020-07-15 10:07:56,396 | app.py:77 | app_evaluate: failures []

Congratulations! You’ve successfully built and run your first federated learning system. The full source code for this can be found in examples/quickstart-tensorflow/client.py.