A PID-controlled defense against label-flipping poisoning attacks in Federated Learning, built on the Flower framework and evaluated on the PathMNIST medical imaging dataset.
In Federated Learning, a subset of clients can poison the global model by
flipping their local labels before submitting updates. Standard FedAvg
has no way to tell a poisoned update from a legitimate one, so it blends
malicious weights straight into the global model every round.
We simulate 20 clients (8 poisoned) training on a non-IID partition of
PathMNIST, and compare plain FedAvg against PIDFedAvg — a custom
aggregation strategy that treats each client's L2 distance from the global
weight centroid as a control signal. A PID controller (proportional +
integral + derivative terms on that distance) scores every client each
round; clients whose score crosses a threshold are excluded from
aggregation (capped at 30% of clients per round, with a 10-round warm-up
before filtering kicks in).
Each configuration is swept across six label-flip severities — 0%, 10%, 25%, 50%, 75%, 100% — of the poisoned clients' local labels.
Final global model accuracy after 50 rounds, by attack severity:
| Flip rate | Final accuracy |
|---|---|
| 0% (no attack) | 82.6% |
| 10% | 89.6% |
| 25% | 87.4% |
| 50% | 73.6% |
| 75% | 80.0% |
| 100% | 79.4% |
Full per-round curves, per-client breakdowns, and exclusion logs are under
results/attacks/, one subfolder per flip rate.
Notable finding: accuracy dips hardest around 50% flip severity, not 100%. At full corruption, poisoned clients' weight updates deviate so sharply from the centroid that the PID controller flags and excludes them easily. At moderate severity, the corruption is subtle enough to blend in, making it the harder case to defend against.
.
├── src/
│ └── federated_learning_security.ipynb # end-to-end pipeline (data, attack, defense, sweep)
└── results/
└── attacks/
├── flip_0 ... flip_100/ # per-round metrics + plots per severity
├── pid_severity_summary.png # headline result
└── loss_accuracy_vs_severity.xlsx
- Data — PathMNIST (9-class tissue classification), deduplicated via SHA-256 hashing, split non-IID across 20 clients with a Dirichlet(α=0.8) partition.
- Attack — 8 of 20 clients have a configurable fraction of their local labels flipped before each training round.
- Model — a compact 3-layer CNN, centrally pretrained once to give all clients a shared, clean initialization.
- Defense (
PIDFedAvg) — computes each client's weight-update distance from the round's global centroid, runs it through a PID controller, and excludes clients whose score exceedspid_threshold(after a 10-round warm-up). - Sweep — repeats the full FL run for each flip rate, checkpointing progress so a sweep can resume if interrupted.
The notebook is written for Google Colab (GPU runtime recommended) and installs its own dependencies in the first cell. To run locally instead:
pip install -r requirements.txt
jupyter notebook src/federated_learning_security.ipynbNo manual dataset download is needed — PathMNIST is fetched automatically
via the medmnist package on first run.
Python, PyTorch, Flower (flwr[simulation]), MedMNIST,
scikit-learn, torchvision, pandas, matplotlib.
Neha Rani — Computer Science, Rochester Institute of Technology
Developed as part of a course project on Federated Learning security.
