Skip to content

0.14.0

Compare
Choose a tag to compare
@danieljanes danieljanes released this 18 Feb 12:59
· 2358 commits to main since this release
e38e8a8

What's new?

  • Generalized Client.fit and Client.evaluate return values (#610, #572, #633)

    Clients can now return an additional dictionary mapping str keys to values of the following types: bool, bytes, float, int, str. This means one can return almost arbitrary values from fit/evaluate and make use of them on the server side!

    This improvement also allowed for more consistent return types between fit and evaluate: evaluate should now return a tuple (float, int, dict) representing the loss, number of examples, and a dictionary holding arbitrary problem-specific values like accuracy.

    In case you wondered: this feature is compatible with existing projects, the additional dictionary return value is optional. New code should however migrate to the new return types to be compatible with upcoming Flower releases (fit: List[np.ndarray], int, Dict[str, Scalar], evaluate: float, int, Dict[str, Scalar]). See the example below for details.

    Code example: note the additional dictionary return values in both FlwrClient.fit and FlwrClient.evaluate:

    class FlwrClient(fl.client.NumPyClient):
        def fit(self, parameters, config):
            net.set_parameters(parameters)
            train_loss = train(net, trainloader)
            return net.get_weights(), len(trainloader), {"train_loss": train_loss}
    
        def evaluate(self, parameters, config):
            net.set_parameters(parameters)
            loss, accuracy, custom_metric = test(net, testloader)
            return loss, len(testloader), {"accuracy": accuracy, "custom_metric": custom_metric}
  • Generalized config argument in Client.fit and Client.evaluate (#595)

    The config argument used to be of type Dict[str, str], which means that dictionary values were expected to be strings. The new release generalizes this to enable values of the following types: bool, bytes, float, int, str.

    This means one can now pass almost arbitrary values to fit/evaluate using the config dictionary. Yay, no more str(epochs) on the server-side and int(config["epochs"]) on the client side!

    Code example: note that the config dictionary now contains non-str values in both Client.fit and Client.evaluate:

    class FlwrClient(fl.client.NumPyClient):
        def fit(self, parameters, config):
            net.set_parameters(parameters)
            epochs: int = config["epochs"]
            train_loss = train(net, trainloader, epochs)
            return net.get_weights(), len(trainloader), {"train_loss": train_loss}
    
        def evaluate(self, parameters, config):
            net.set_parameters(parameters)
            batch_size: int = config["batch_size"]
            loss, accuracy = test(net, testloader, batch_size)
            return loss, len(testloader), {"accuracy": accuracy}