Skip to main content
Article
federated-learningflower-frameworkpythonmachine-learningdata-privacydistributed-trainingtensorflow

Build a Federated Learning System with Python and Flower

Implement a basic Federated Learning system using the Flower framework. This guide shows you how to train a single machine learning model across two simulated clients without sharing their local data, demonstrating the core principles of privacy-preserving AI.

intermediate30 min4 steps
The play
  1. Install Dependencies
    Set up your Python environment by installing Flower and a machine learning framework like TensorFlow. Flower orchestrates the federated process, and TensorFlow will be used to define and train the local models on each client.
  2. Define the ML Model and Data
    Create a simple Keras model and generate dummy datasets for two clients. In a real-world Federated Learning scenario, this data would reside on separate devices and never be moved to a central location.
  3. Create a Flower Client
    Implement a Flower client class. This class wraps your local model and data, defining how it trains (fit), evaluates (evaluate), and communicates model weight updates with the central server.
  4. Start the Federated Learning Simulation
    Use Flower's simulation engine to start the Federated Learning process. The server will coordinate multiple training rounds. In each round, it sends the global model to clients, they train it on their local data, and send their updates back for aggregation.
Starter code
import flwr as fl
import tensorflow as tf
import numpy as np
from typing import Tuple, Dict, List

# 1. Define a simple model and compile it
model = tf.keras.models.Sequential([
    tf.keras.layers.Dense(10, activation='relu', input_shape=(10,)),
    tf.keras.layers.Dense(1, activation='sigmoid')
])
model.compile("adam", "binary_crossentropy", metrics=["accuracy"])

# 2. Create dummy datasets for two clients
# In a real scenario, this data would be on separate devices.
(x_train_1, y_train_1) = (np.random.rand(100, 10).astype(np.float32), np.random.randint(0, 2, 100))
(x_train_2, y_train_2) = (np.random.rand(100, 10).astype(np.float32), np.random.randint(0, 2, 100))
client_data = { "0": (x_train_1, y_train_1), "1": (x_train_2, y_train_2) }

# 3. Define the Flower client
class FlowerClient(fl.client.NumPyClient):
    def __init__(self, model, x_train, y_train):
        self.model = model
        self.x_train, self.y_train = x_train, y_train

    def get_parameters(self, config: Dict[str, str]) -> List[np.ndarray]:
        # Return the current local model weights
        return self.model.get_weights()

    def fit(self, parameters: List[np.ndarray], config: Dict[str, str]) -> Tuple[List[np.ndarray], int, Dict]:
        # Set the local model weights from the server
        self.model.set_weights(parameters)
        # Train the model on local data
        self.model.fit(self.x_train, self.y_train, epochs=1, batch_size=32, verbose=0)
        # Return the updated model weights, number of examples, and an empty metrics dict
        return self.model.get_weights(), len(self.x_train), {}

    def evaluate(self, parameters: List[np.ndarray], config: Dict[str, str]) -> Tuple[float, int, Dict]:
        # Set the local model weights from the server
        self.model.set_weights(parameters)
        # Evaluate the model on local data
        loss, accuracy = self.model.evaluate(self.x_train, self.y_train, verbose=0)
        # Return the loss, number of examples, and accuracy metric
        return float(loss), len(self.x_train), {"accuracy": float(accuracy)}

# 4. Define a function to instantiate a client for a given ID
def client_fn(cid: str) -> FlowerClient:
    # Get the data for the client ID
    x_train, y_train = client_data[cid]
    # Create and return a new client
    return FlowerClient(model, x_train, y_train)

# 5. Start the simulation
print("Starting Federated Learning simulation...")
history = fl.simulation.start_simulation(
    client_fn=client_fn,
    num_clients=2, # Number of clients to simulate
    config=fl.server.ServerConfig(num_rounds=3), # Number of training rounds
    strategy=fl.server.strategy.FedAvg(), # Aggregation strategy
)

print("Simulation finished.")
print(f"Aggregated loss: {history.losses_distributed}")
Build a Federated Learning System with Python and Flower — Action Pack