diff --git a/datasets/doc/source/how-to-use-with-pytorch.rst b/datasets/doc/source/how-to-use-with-pytorch.rst index 613f00a9a059..4228ead2a281 100644 --- a/datasets/doc/source/how-to-use-with-pytorch.rst +++ b/datasets/doc/source/how-to-use-with-pytorch.rst @@ -63,7 +63,7 @@ expected by a model with a convolutional layer. If you want to divide the dataset, you can use (at any point before passing the dataset to the DataLoader):: - partition_train_test = partition.train_test_split(test_size=0.2) + partition_train_test = partition.train_test_split(test_size=0.2, seed=42) partition_train = partition_train_test["train"] partition_test = partition_train_test["test"] diff --git a/datasets/e2e/pytorch/pytorch_test.py b/datasets/e2e/pytorch/pytorch_test.py index 5bac8f770f23..1f5e4cbb3ad1 100644 --- a/datasets/e2e/pytorch/pytorch_test.py +++ b/datasets/e2e/pytorch/pytorch_test.py @@ -65,7 +65,7 @@ def _create_trainloader(self, batch_size: int) -> DataLoader: partition_id = 0 fds = FederatedDataset(dataset=self.dataset_name, partitioners={"train": 100}) partition = fds.load_partition(partition_id, "train") - partition_train_test = partition.train_test_split(test_size=0.2) + partition_train_test = partition.train_test_split(test_size=0.2, seed=42) partition_train_test = partition_train_test.map( lambda img: {"img": self.transforms(img)}, input_columns="img" ) diff --git a/datasets/e2e/scikit-learn/sklearn_test.py b/datasets/e2e/scikit-learn/sklearn_test.py index e5e6d347ee37..7ce4659b6cd8 100644 --- a/datasets/e2e/scikit-learn/sklearn_test.py +++ b/datasets/e2e/scikit-learn/sklearn_test.py @@ -29,7 +29,7 @@ def _get_partition_data(self): fds = FederatedDataset(dataset=self.dataset_name, partitioners={"train": 10}) partition = fds.load_partition(partition_id, "train") partition.set_format("numpy") - partition_train_test = partition.train_test_split(test_size=0.2) + partition_train_test = partition.train_test_split(test_size=0.2, seed=42) X_train, y_train = partition_train_test["train"]["image"], partition_train_test[ "train"]["label"] X_test, y_test = partition_train_test["test"]["image"], partition_train_test[ diff --git a/dev/update-examples.sh b/dev/update-examples.sh index c802e21503b7..07cb90932875 100755 --- a/dev/update-examples.sh +++ b/dev/update-examples.sh @@ -16,20 +16,47 @@ echo "---" >> $INDEX echo "maxdepth: 1" >> $INDEX echo "---" >> $INDEX -rm -f "examples/doc/source/*.md" +rm -f examples/doc/source/*.md cd examples/ for d in $(printf '%s\n' */ | sort -V); do example=${d%/} - # For each example, copy the README into the source of the Example docs - [[ $example != doc ]] && cp $example/README.md $ROOT/examples/doc/source/$example.md 2>&1 >/dev/null - # For each example, copy all images of the _static folder into the examples - # docs static folder - [[ $example != doc ]] && [ -d "$example/_static" ] && { - cp $example/_static/**.{jpg,png,jpeg} $ROOT/examples/doc/source/_static/ 2>/dev/null || true - } - # For each example, insert the name of the example into the index file - [[ $example != doc ]] && (echo $INSERT_LINE; echo a; echo $example; echo .; echo wq) | ed $INDEX 2>&1 >/dev/null + + if [[ $example != doc ]]; then + + for file in $example/*.md; do + # For each example, copy the README into the source of the Example docs + if [[ $(basename "$file") = "README.md" ]]; then + cp $file $ROOT/examples/doc/source/$example.md 2>&1 >/dev/null + else + # If the example contains other markdown files, copy them to the source of the Example docs + cp $file $ROOT/examples/doc/source/$(basename "$file") 2>&1 >/dev/null + fi + done + + gh_text="[\"View](https://github.com/adap/flower/blob/main/examples/$example)" + readme_file="$ROOT/examples/doc/source/$example.md" + + if ! grep -Fq "$gh_text" "$readme_file"; then + awk -v text="$gh_text" ' + /^# / && !found { + print $0 "\n" text; + found=1; + next; + } + { print } + ' "$readme_file" > tmpfile && mv tmpfile "$readme_file" + fi + + # For each example, copy all images of the _static folder into the examples + # docs static folder + [ -d "$example/_static" ] && { + cp $example/_static/**.{jpg,png,jpeg} $ROOT/examples/doc/source/_static/ 2>/dev/null || true + } + # For each example, insert the name of the example into the index file + (echo $INSERT_LINE; echo a; echo $example; echo .; echo wq) | ed $INDEX 2>&1 >/dev/null + + fi done echo "\`\`\`" >> $INDEX diff --git a/doc/source/tutorial-series-get-started-with-flower-pytorch.ipynb b/doc/source/tutorial-series-get-started-with-flower-pytorch.ipynb index 2b8dd382bb79..6f3d24286c99 100644 --- a/doc/source/tutorial-series-get-started-with-flower-pytorch.ipynb +++ b/doc/source/tutorial-series-get-started-with-flower-pytorch.ipynb @@ -145,7 +145,7 @@ " for partition_id in range(NUM_CLIENTS):\n", " partition = fds.load_partition(partition_id, \"train\")\n", " partition = partition.with_transform(apply_transforms)\n", - " partition = partition.train_test_split(train_size=0.8)\n", + " partition = partition.train_test_split(train_size=0.8, seed=42)\n", " trainloaders.append(DataLoader(partition[\"train\"], batch_size=BATCH_SIZE))\n", " valloaders.append(DataLoader(partition[\"test\"], batch_size=BATCH_SIZE))\n", " testset = fds.load_split(\"test\").with_transform(apply_transforms)\n", diff --git a/examples/advanced-pytorch/client.py b/examples/advanced-pytorch/client.py index d4c8abe3d404..7c1420a2cecd 100644 --- a/examples/advanced-pytorch/client.py +++ b/examples/advanced-pytorch/client.py @@ -46,7 +46,7 @@ def fit(self, parameters, config): batch_size: int = config["batch_size"] epochs: int = config["local_epochs"] - train_valid = self.trainset.train_test_split(self.validation_split) + train_valid = self.trainset.train_test_split(self.validation_split, seed=42) trainset = train_valid["train"] valset = train_valid["test"] diff --git a/examples/advanced-pytorch/utils.py b/examples/advanced-pytorch/utils.py index fd9dab19a70d..c47b4fa38593 100644 --- a/examples/advanced-pytorch/utils.py +++ b/examples/advanced-pytorch/utils.py @@ -14,7 +14,7 @@ def load_partition(partition_id, toy: bool = False): fds = FederatedDataset(dataset="cifar10", partitioners={"train": 10}) partition = fds.load_partition(partition_id) # Divide data on each node: 80% train, 20% test - partition_train_test = partition.train_test_split(test_size=0.2) + partition_train_test = partition.train_test_split(test_size=0.2, seed=42) partition_train_test = partition_train_test.with_transform(apply_transforms) return partition_train_test["train"], partition_train_test["test"] diff --git a/examples/advanced-tensorflow/client.py b/examples/advanced-tensorflow/client.py index 17d1d2306270..b658a1f9ea04 100644 --- a/examples/advanced-tensorflow/client.py +++ b/examples/advanced-tensorflow/client.py @@ -123,7 +123,7 @@ def load_partition(idx: int): partition.set_format("numpy") # Divide data on each node: 80% train, 20% test - partition = partition.train_test_split(test_size=0.2) + partition = partition.train_test_split(test_size=0.2, seed=42) x_train, y_train = partition["train"]["img"] / 255.0, partition["train"]["label"] x_test, y_test = partition["test"]["img"] / 255.0, partition["test"]["label"] return x_train, y_train, x_test, y_test diff --git a/examples/app-pytorch/client.py b/examples/app-pytorch/client.py index ebbe977ecab1..eb84968bb986 100644 --- a/examples/app-pytorch/client.py +++ b/examples/app-pytorch/client.py @@ -18,7 +18,6 @@ # Define FlowerClient and client_fn class FlowerClient(NumPyClient): - def fit(self, parameters, config): set_weights(net, parameters) results = train(net, trainloader, testloader, epochs=1, device=DEVICE) diff --git a/examples/custom-mods/README.md b/examples/custom-mods/README.md index b0ad668c2dec..6b03abcfbfe0 100644 --- a/examples/custom-mods/README.md +++ b/examples/custom-mods/README.md @@ -288,7 +288,7 @@ $ tree . pip install -r requirements.txt ``` -For [W&B](wandb.ai) you will also need a valid account. +For [W&B](https://wandb.ai) you will also need a valid account. ### Start the long-running Flower server (SuperLink) @@ -328,7 +328,7 @@ flower-server-app server:app --insecure ### Check the results -For W&B, you will need to login to the [website](wandb.ai). +For W&B, you will need to login to the [website](https://wandb.ai). For TensorBoard, you will need to run the following command in your terminal: diff --git a/examples/custom-mods/client.py b/examples/custom-mods/client.py index 2b87a24da19d..614daef6bcf6 100644 --- a/examples/custom-mods/client.py +++ b/examples/custom-mods/client.py @@ -86,7 +86,6 @@ def wandb_mod(msg: Message, context: Context, app: ClientAppCallable) -> Message # if the `ClientApp` just processed a "fit" message, let's log some metrics to W&B if reply.metadata.message_type == MessageType.TRAIN and reply.has_content(): - metrics = reply.content.configs_records results_to_log = dict(metrics.get("fitres.metrics", ConfigsRecord())) diff --git a/examples/doc/source/_static/.gitignore b/examples/doc/source/_static/.gitignore index c2412a5912cc..887023baf484 100644 --- a/examples/doc/source/_static/.gitignore +++ b/examples/doc/source/_static/.gitignore @@ -3,3 +3,4 @@ !favicon.ico !flower-logo.png !tmux_jtop_view.gif +!view-gh.png diff --git a/examples/doc/source/_static/view-gh.png b/examples/doc/source/_static/view-gh.png new file mode 100644 index 000000000000..afc3f07bc2d5 Binary files /dev/null and b/examples/doc/source/_static/view-gh.png differ diff --git a/examples/embedded-devices/client_pytorch.py b/examples/embedded-devices/client_pytorch.py index 6bd69c16567e..411052bfb1ea 100644 --- a/examples/embedded-devices/client_pytorch.py +++ b/examples/embedded-devices/client_pytorch.py @@ -108,7 +108,7 @@ def apply_transforms(batch): for partition_id in range(NUM_CLIENTS): partition = fds.load_partition(partition_id, "train") # Divide data on each node: 90% train, 10% test - partition = partition.train_test_split(test_size=0.1) + partition = partition.train_test_split(test_size=0.1, seed=42) partition = partition.with_transform(apply_transforms) trainsets.append(partition["train"]) validsets.append(partition["test"]) diff --git a/examples/embedded-devices/client_tf.py b/examples/embedded-devices/client_tf.py index 49c63ce5d9dc..3df75f76312b 100644 --- a/examples/embedded-devices/client_tf.py +++ b/examples/embedded-devices/client_tf.py @@ -44,7 +44,7 @@ def prepare_dataset(use_mnist: bool): partition = fds.load_partition(partition_id, "train") partition.set_format("numpy") # Divide data on each node: 90% train, 10% test - partition = partition.train_test_split(test_size=0.1) + partition = partition.train_test_split(test_size=0.1, seed=42) x_train, y_train = ( partition["train"][img_key] / 255.0, partition["train"]["label"], diff --git a/examples/fl-dp-sa/fl_dp_sa/task.py b/examples/fl-dp-sa/fl_dp_sa/task.py index 3d506263d5a3..64ba10f20376 100644 --- a/examples/fl-dp-sa/fl_dp_sa/task.py +++ b/examples/fl-dp-sa/fl_dp_sa/task.py @@ -42,7 +42,7 @@ def load_data(partition_id): fds = FederatedDataset(dataset="mnist", partitioners={"train": 100}) partition = fds.load_partition(partition_id) # Divide data on each node: 80% train, 20% test - partition_train_test = partition.train_test_split(test_size=0.2) + partition_train_test = partition.train_test_split(test_size=0.2, seed=42) pytorch_transforms = Compose([ToTensor(), Normalize((0.5,), (0.5,))]) def apply_transforms(batch): diff --git a/examples/flower-via-docker-compose/helpers/load_data.py b/examples/flower-via-docker-compose/helpers/load_data.py index 1f2784946868..b7d6b0de26c5 100644 --- a/examples/flower-via-docker-compose/helpers/load_data.py +++ b/examples/flower-via-docker-compose/helpers/load_data.py @@ -25,7 +25,7 @@ def load_data(data_sampling_percentage=0.5, client_id=1, total_clients=2): partition.set_format("numpy") # Divide data on each client: 80% train, 20% test - partition = partition.train_test_split(test_size=0.2) + partition = partition.train_test_split(test_size=0.2, seed=42) x_train, y_train = partition["train"]["img"] / 255.0, partition["train"]["label"] x_test, y_test = partition["test"]["img"] / 255.0, partition["test"]["label"] diff --git a/examples/pytorch-from-centralized-to-federated/cifar.py b/examples/pytorch-from-centralized-to-federated/cifar.py index 277a21da2e70..c592b63b0042 100644 --- a/examples/pytorch-from-centralized-to-federated/cifar.py +++ b/examples/pytorch-from-centralized-to-federated/cifar.py @@ -56,7 +56,7 @@ def load_data(partition_id: int): fds = FederatedDataset(dataset="cifar10", partitioners={"train": 10}) partition = fds.load_partition(partition_id) # Divide data on each node: 80% train, 20% test - partition_train_test = partition.train_test_split(test_size=0.2) + partition_train_test = partition.train_test_split(test_size=0.2, seed=42) pytorch_transforms = Compose( [ToTensor(), Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))] ) diff --git a/examples/quickstart-huggingface/client.py b/examples/quickstart-huggingface/client.py index 9be08d0cbcf4..db8bf51d36da 100644 --- a/examples/quickstart-huggingface/client.py +++ b/examples/quickstart-huggingface/client.py @@ -22,7 +22,7 @@ def load_data(partition_id): fds = FederatedDataset(dataset="imdb", partitioners={"train": 1_000}) partition = fds.load_partition(partition_id) # Divide data: 80% train, 20% test - partition_train_test = partition.train_test_split(test_size=0.2) + partition_train_test = partition.train_test_split(test_size=0.2, seed=42) tokenizer = AutoTokenizer.from_pretrained(CHECKPOINT) diff --git a/examples/quickstart-mlcube/dev/mnist.py b/examples/quickstart-mlcube/dev/mnist.py index e52e2cba85c7..55fb8fae62a7 100644 --- a/examples/quickstart-mlcube/dev/mnist.py +++ b/examples/quickstart-mlcube/dev/mnist.py @@ -36,6 +36,7 @@ def create_directory(path: str) -> None: def download(task_args: List[str]) -> None: """Task: download. + Input parameters: --data_dir """ @@ -81,6 +82,7 @@ def download(task_args: List[str]) -> None: def train(task_args: List[str]) -> None: """Task: train. + Input parameters: --data_dir, --log_dir, --model_dir, --parameters_file """ @@ -175,6 +177,7 @@ def train(task_args: List[str]) -> None: def evaluate(task_args: List[str]) -> None: """Task: train. + Input parameters: --data_dir, --log_dir, --model_dir, --parameters_file """ diff --git a/examples/quickstart-mlx/client.py b/examples/quickstart-mlx/client.py index faba2b94d6bd..344cfc65e42d 100644 --- a/examples/quickstart-mlx/client.py +++ b/examples/quickstart-mlx/client.py @@ -107,7 +107,7 @@ def evaluate(self, parameters, config): fds = FederatedDataset(dataset="mnist", partitioners={"train": 3}) partition = fds.load_partition(partition_id=args.partition_id) - partition_splits = partition.train_test_split(test_size=0.2) + partition_splits = partition.train_test_split(test_size=0.2, seed=42) partition_splits["train"].set_format("numpy") partition_splits["test"].set_format("numpy") diff --git a/examples/quickstart-pytorch-lightning/mnist.py b/examples/quickstart-pytorch-lightning/mnist.py index 95342f4fb9b3..2f6100fe94cc 100644 --- a/examples/quickstart-pytorch-lightning/mnist.py +++ b/examples/quickstart-pytorch-lightning/mnist.py @@ -82,9 +82,11 @@ def load_data(partition): partition = partition.with_transform(apply_transforms) # 20 % for on federated evaluation - partition_full = partition.train_test_split(test_size=0.2) + partition_full = partition.train_test_split(test_size=0.2, seed=42) # 60 % for the federated train and 20 % for the federated validation (both in fit) - partition_train_valid = partition_full["train"].train_test_split(train_size=0.75) + partition_train_valid = partition_full["train"].train_test_split( + train_size=0.75, seed=42 + ) trainloader = DataLoader( partition_train_valid["train"], batch_size=32, diff --git a/examples/quickstart-pytorch/client.py b/examples/quickstart-pytorch/client.py index e58dbf7ea0bc..be4be88b8f8d 100644 --- a/examples/quickstart-pytorch/client.py +++ b/examples/quickstart-pytorch/client.py @@ -74,7 +74,7 @@ def load_data(partition_id): fds = FederatedDataset(dataset="cifar10", partitioners={"train": 3}) partition = fds.load_partition(partition_id) # Divide data on each node: 80% train, 20% test - partition_train_test = partition.train_test_split(test_size=0.2) + partition_train_test = partition.train_test_split(test_size=0.2, seed=42) pytorch_transforms = Compose( [ToTensor(), Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))] ) diff --git a/examples/quickstart-tensorflow/client.py b/examples/quickstart-tensorflow/client.py index 6ef11898f0b0..a906e9865d3b 100644 --- a/examples/quickstart-tensorflow/client.py +++ b/examples/quickstart-tensorflow/client.py @@ -30,7 +30,7 @@ partition.set_format("numpy") # Divide data on each node: 80% train, 20% test -partition = partition.train_test_split(test_size=0.2) +partition = partition.train_test_split(test_size=0.2, seed=42) x_train, y_train = partition["train"]["img"] / 255.0, partition["train"]["label"] x_test, y_test = partition["test"]["img"] / 255.0, partition["test"]["label"] diff --git a/examples/simulation-pytorch/sim.ipynb b/examples/simulation-pytorch/sim.ipynb index 6dda1ef9319d..d225069cb444 100644 --- a/examples/simulation-pytorch/sim.ipynb +++ b/examples/simulation-pytorch/sim.ipynb @@ -497,7 +497,7 @@ " client_dataset = dataset.load_partition(int(cid), \"train\")\n", "\n", " # Now let's split it into train (90%) and validation (10%)\n", - " client_dataset_splits = client_dataset.train_test_split(test_size=0.1)\n", + " client_dataset_splits = client_dataset.train_test_split(test_size=0.1, seed=42)\n", "\n", " trainset = client_dataset_splits[\"train\"]\n", " valset = client_dataset_splits[\"test\"]\n", diff --git a/examples/simulation-pytorch/sim.py b/examples/simulation-pytorch/sim.py index 6fb750f2e59c..db68e75653fc 100644 --- a/examples/simulation-pytorch/sim.py +++ b/examples/simulation-pytorch/sim.py @@ -94,7 +94,7 @@ def client_fn(cid: str) -> fl.client.Client: client_dataset = dataset.load_partition(int(cid), "train") # Now let's split it into train (90%) and validation (10%) - client_dataset_splits = client_dataset.train_test_split(test_size=0.1) + client_dataset_splits = client_dataset.train_test_split(test_size=0.1, seed=42) trainset = client_dataset_splits["train"] valset = client_dataset_splits["test"] diff --git a/examples/simulation-tensorflow/sim.ipynb b/examples/simulation-tensorflow/sim.ipynb index 797e2dcc603e..26b7260b5f1c 100644 --- a/examples/simulation-tensorflow/sim.ipynb +++ b/examples/simulation-tensorflow/sim.ipynb @@ -179,7 +179,7 @@ " client_dataset = dataset.load_partition(int(cid), \"train\")\n", "\n", " # Now let's split it into train (90%) and validation (10%)\n", - " client_dataset_splits = client_dataset.train_test_split(test_size=0.1)\n", + " client_dataset_splits = client_dataset.train_test_split(test_size=0.1, seed=42)\n", "\n", " trainset = client_dataset_splits[\"train\"].to_tf_dataset(\n", " columns=\"image\", label_cols=\"label\", batch_size=32\n", diff --git a/examples/simulation-tensorflow/sim.py b/examples/simulation-tensorflow/sim.py index e94e5ec96850..4014e3c6be72 100644 --- a/examples/simulation-tensorflow/sim.py +++ b/examples/simulation-tensorflow/sim.py @@ -83,7 +83,7 @@ def client_fn(cid: str) -> fl.client.Client: client_dataset = dataset.load_partition(int(cid), "train") # Now let's split it into train (90%) and validation (10%) - client_dataset_splits = client_dataset.train_test_split(test_size=0.1) + client_dataset_splits = client_dataset.train_test_split(test_size=0.1, seed=42) trainset = client_dataset_splits["train"].to_tf_dataset( columns="image", label_cols="label", batch_size=32 diff --git a/examples/vertical-fl/README.md b/examples/vertical-fl/README.md index 78588180d3d6..d8c599d617c4 100644 --- a/examples/vertical-fl/README.md +++ b/examples/vertical-fl/README.md @@ -123,7 +123,7 @@ In `task.py`, you'll find the preprocessing functions we'll apply to our data: 'Adult' for ages between 11 and 40, and 'Elderly' for those over 40. If the age isn't listed, we'll label it as 'Unknown'. - ```python3 + ```python def _bin_age(age_series): bins = [-np.inf, 10, 40, np.inf] labels = ["Child", "Adult", "Elderly"] @@ -138,7 +138,7 @@ In `task.py`, you'll find the preprocessing functions we'll apply to our data: understand social status and family roles, simplifying rare titles into a single 'Rare' category and converting any French titles to their English equivalents. - ```python3 + ```python def _extract_title(name_series): titles = name_series.str.extract(" ([A-Za-z]+)\.", expand=False) rare_titles = { @@ -170,7 +170,7 @@ In `task.py`, you'll find the preprocessing functions we'll apply to our data: 'Pclass', 'Embarked', 'Title', 'Cabin', and the binned 'Age' into One-Hot encodings. - ```python3 + ```python def _create_features(df): # Convert 'Age' to numeric, coercing errors to NaN df["Age"] = pd.to_numeric(df["Age"], errors="coerce") @@ -190,7 +190,7 @@ In `task.py`, you'll find the preprocessing functions we'll apply to our data: In `task.py`, we also partition our data for our 3 clients to mirror real-life collaborations where different organizations hold different feature sets: -```python3 +```python def _partition_data(df, all_keywords): partitions = [] keywords_sets = [{"Parch", "Cabin", "Pclass"}, {"Sex", "Title"}] @@ -236,7 +236,7 @@ collective intelligence without sharing sensitive information. Note that our final data processing function looks like that: -```python3 +```python def get_partitions_and_label(): df = pd.read_csv("_static/data/train.csv") processed_df = df.dropna(subset=["Embarked", "Fare"]).copy() @@ -259,7 +259,7 @@ Each client's model is a neural network designed to operate on a distinct subset of features held by a client. In this example we will use simple linear regression models. -```python3 +```python class ClientModel(nn.Module): def __init__(self, input_size): super(ClientModel, self).__init__() @@ -281,7 +281,7 @@ The server's model acts as the central aggregator in the VFL system. It's also a neural network but with a slightly different architecture tailored to its role in aggregating the client models' outputs. -```python3 +```python class ServerModel(nn.Module): def __init__(self): super(ServerModel, self).__init__() @@ -305,7 +305,7 @@ a probability score indicative of the likelihood of survival. The strategy we will write to perform the aggregation will inherit from `FedAvg` and set the following additional attributes: -```python3 +```python self.model = ServerModel(12) self.initial_parameters = ndarrays_to_parameters( [val.cpu().numpy() for _, val in self.model.state_dict().items()] @@ -319,7 +319,7 @@ With `labels` given as an argument to the strategy. We then redefine the `aggregate_fit` method: -```python3 +```python def aggregate_fit( self, rnd, @@ -406,7 +406,7 @@ The last thing we have to do is to redefine the `aggregate_evaluate` function to disable distributed evaluation (as the clients do not hold any labels to test their local models). -```python3 +```python def aggregate_evaluate( self, rnd, @@ -420,7 +420,7 @@ def aggregate_evaluate( Our `FlowerClient` class is going to be quite straight forward. -```python3 +```python class FlowerClient(fl.client.NumPyClient): def __init__(self, cid, data): self.cid = cid @@ -487,7 +487,7 @@ the `aggregate_evaluate` function of the strategy. Putting everything together, to start our simulation we use the following function: -```python3 +```python hist = fl.simulation.start_simulation( client_fn=client_fn, num_clients=3, diff --git a/examples/vit-finetune/client.py b/examples/vit-finetune/client.py index 68d98926feeb..bf91fa0c4328 100644 --- a/examples/vit-finetune/client.py +++ b/examples/vit-finetune/client.py @@ -8,9 +8,7 @@ class FedViTClient(NumPyClient): - def __init__(self, trainset): - self.trainset = trainset self.model = get_model() diff --git a/examples/vit-finetune/main.py b/examples/vit-finetune/main.py index 1257246304a1..c629a6f68980 100644 --- a/examples/vit-finetune/main.py +++ b/examples/vit-finetune/main.py @@ -19,7 +19,6 @@ def main(): - args = parser.parse_args() # To control the degree of parallelism diff --git a/examples/whisper-federated-finetuning/utils.py b/examples/whisper-federated-finetuning/utils.py index 21fe0309151c..117cf7100ddd 100644 --- a/examples/whisper-federated-finetuning/utils.py +++ b/examples/whisper-federated-finetuning/utils.py @@ -107,10 +107,10 @@ def prepare_silences_dataset(train_dataset, ratio_silence: float = 0.1) -> Datas """Generate silences for the train set. One of the classes in the SpeechCommands datatset is `silence`. However, the dataset - does not include clips of silence. It does however include 5 long files with different - background sounds. The taks of this function is to extract several (defined by `ratio_silence`) - one-second long clips from those background audio files. Later, those audio clips will be - included into the training set. + does not include clips of silence. It does however include 5 long files with + different background sounds. The taks of this function is to extract several + (defined by `ratio_silence`) one-second long clips from those background audio + files. Later, those audio clips will be included into the training set. """ # retrieve original silence audio clips silences = [d for d in train_dataset if d["label"] == 35] @@ -138,9 +138,9 @@ def prepare_silences_dataset(train_dataset, ratio_silence: float = 0.1) -> Datas def construct_client_mapping(full_trainset, num_clients: int = 100): """Create a mapping to partition the dataset into `num_client` buckets. - These buckets contain the same number of `spekaer_id` but likely different - number of training exampes since each `speaker_id` in SpeechCommands does - provide different amounts of data to the dataset. + These buckets contain the same number of `spekaer_id` but likely different number of + training exampes since each `speaker_id` in SpeechCommands does provide different + amounts of data to the dataset. """ client_ids = list(set(full_trainset["speaker_id"])) client_ids.remove( @@ -191,7 +191,7 @@ def set_params(model: torch.nn.ModuleList, params: List[fl.common.NDArrays]): def get_model(device, num_classes, compile: bool = True): - """Create model: Whisper-tiny Encoder + classification head""" + """Create model: Whisper-tiny Encoder + classification head.""" encoder = WhisperForConditionalGeneration.from_pretrained( "openai/whisper-tiny" ).get_encoder() diff --git a/src/py/flwr/cli/new/templates/app/code/task.pytorch.py.tpl b/src/py/flwr/cli/new/templates/app/code/task.pytorch.py.tpl index 85460564b6ef..b30c65a285b5 100644 --- a/src/py/flwr/cli/new/templates/app/code/task.pytorch.py.tpl +++ b/src/py/flwr/cli/new/templates/app/code/task.pytorch.py.tpl @@ -39,7 +39,7 @@ def load_data(partition_id, num_partitions): fds = FederatedDataset(dataset="cifar10", partitioners={"train": num_partitions}) partition = fds.load_partition(partition_id) # Divide data on each node: 80% train, 20% test - partition_train_test = partition.train_test_split(test_size=0.2) + partition_train_test = partition.train_test_split(test_size=0.2, seed=42) pytorch_transforms = Compose( [ToTensor(), Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))] ) diff --git a/src/py/flwr/client/app.py b/src/py/flwr/client/app.py index 1720405ab867..4fa9c80c6cdf 100644 --- a/src/py/flwr/client/app.py +++ b/src/py/flwr/client/app.py @@ -456,12 +456,13 @@ def _load_client_app() -> ClientApp: continue log(INFO, "") - log( - INFO, - "[RUN %s, ROUND %s]", - message.metadata.run_id, - message.metadata.group_id, - ) + if len(message.metadata.group_id) > 0: + log( + INFO, + "[RUN %s, ROUND %s]", + message.metadata.run_id, + message.metadata.group_id, + ) log( INFO, "Received: %s message %s", diff --git a/src/py/flwr/common/retry_invoker.py b/src/py/flwr/common/retry_invoker.py index 7cec319e7906..d12124b89840 100644 --- a/src/py/flwr/common/retry_invoker.py +++ b/src/py/flwr/common/retry_invoker.py @@ -261,6 +261,7 @@ def try_call_event_handler( try: ret = target(*args, **kwargs) except self.recoverable_exceptions as err: + state.exception = err # Check if giveup event should be triggered max_tries_exceeded = try_cnt == self.max_tries max_time_exceeded = (