Use strategies¶
Flower allows full customization of the learning process through the Strategy
abstraction. A number of built-in strategies are provided in the core framework.
There are three ways to customize the way Flower orchestrates the learning process on the server side:
Use an existing strategy, for example,
FedAvg
Customize an existing strategy with callback functions
Implement a novel strategy
Use an existing strategy¶
Flower comes with a number of popular federated learning Strategies which can be instantiated as follows:
from flwr.common import Context
from flwr.server.strategy import FedAvg
from flwr.server import ServerApp, ServerAppComponents, ServerConfig
def server_fn(context: Context):
# Optional context-based parameters specification
num_rounds = context.run_config["num-server-rounds"]
config = ServerConfig(num_rounds=num_rounds)
# Instantiate FedAvg strategy
strategy = FedAvg(
fraction_fit=context.run_config["fraction-fit"],
fraction_evaluate=1.0,
)
# Create and return ServerAppComponents
return ServerAppComponents(strategy=strategy, config=config)
# Create ServerApp
app = ServerApp(server_fn=server_fn)
To make the ServerApp
use this strategy, pass a server_fn
function to the
ServerApp
constructor. The server_fn
function should return a
ServerAppComponents
object that contains the strategy instance and a
ServerConfig
instance.
Both Strategy
and ServerConfig
classes can be configured with parameters. The
Context
object passed to server_fn
contains the values specified in the
[tool.flwr.app.config]
table in your pyproject.toml
(a snippet is shown below).
To access these values, use context.run_config
.
# ...
[tool.flwr.app.config]
num-server-rounds = 10
fraction-fit = 0.5
# ...
Customize an existing strategy with callback functions¶
Existing strategies provide several ways to customize their behavior. Callback functions allow strategies to call user-provided code during execution. This approach enables you to modify the strategy’s partial behavior without rewriting the whole class from zero.
Configuring client fit and client evaluate¶
The server can pass new configuration values to the client each round by providing a
function to on_fit_config_fn
. The provided function will be called by the strategy
and must return a dictionary of configuration key value pairs that will be sent to the
client. It must return a dictionary of arbitrary configuration values client.fit
and
client.evaluate
functions during each round of federated learning.
from flwr.common import Context
from flwr.server.strategy import FedAvg
from flwr.server import ServerApp, ServerAppComponents, ServerConfig
def get_on_fit_config_fn() -> Callable[[int], Dict[str, str]]:
"""Return a function which returns training configurations."""
def fit_config(server_round: int) -> Dict[str, str]:
"""Return a configuration with static batch size and (local) epochs."""
config = {
"learning_rate": str(0.001),
"batch_size": str(32),
}
return config
return fit_config
def server_fn(context: Context):
# Read num_rounds from context
num_rounds = context.run_config["num-server-rounds"]
config = ServerConfig(num_rounds=num_rounds)
# Instantiate FedAvg strategy
strategy = FedAvg(
fraction_fit=context.run_config["fraction-fit"],
fraction_evaluate=1.0,
on_fit_config_fn=get_on_fit_config_fn(),
)
# Create and return ServerAppComponents
return ServerAppComponents(strategy=strategy, config=config)
# Create ServerApp
app = ServerApp(server_fn=server_fn)
The on_fit_config_fn
can be used to pass arbitrary configuration values from server
to client and potentially change these values each round, for example, to adjust the
learning rate. The client will receive the dictionary returned by the
on_fit_config_fn
in its own client.fit()
function. And while the values can be
also passed directly via the context this function can be a place to implement finer
control over the fit behaviour that may not be achieved by the context, which sets
fixed values.
Similar to on_fit_config_fn
, there is also on_evaluate_config_fn
to customize
the configuration sent to client.evaluate()
Configuring server-side evaluation¶
Server-side evaluation can be enabled by passing an evaluation function to
evaluate_fn
.
Implement a novel strategy¶
Writing a fully custom strategy is a bit more involved, but it provides the most flexibility. Read the Implementing Strategies guide to learn more.