@kariminem/dronesar-fl

0
1
flwr new @kariminem/dronesar-fl

Multi-Agency SAR Drone Swarm — Federated Survivor Detection

60% alone → 92% federated. Zero footage shared.

Five search-and-rescue drones, each operated by a different agency over different terrain, train a shared survivor-detection model without any agency handing over a single frame of thermal footage. Only model coefficients are exchanged, aggregated with FedAvg.

This is a federated learning problem for a reason that is easy to state and easy to measure.

Why a single drone fails

Every candidate detection is either a real survivor or a false positive, and each agency's terrain produces its own kind of false positive:

AgencyTerrainIts false positiveThe cue that gives it away
Park Serviceforestcampfiredoesn't move
Coast Guardcoastalsun-heated rockwrong thermal band
Fire Depturban edgevehicle enginetoo large
Mountain Rescuealpinegeothermal ventno human silhouette
Volunteer Corpsfarmlandlivestockno human gait

A real survivor scores well on all five human cues. Each false positive scores well on four and fails exactly one — a different one per agency.

So a drone that trains only on its own data learns to reject exactly one of the five. Fly it over unfamiliar ground — which is what a multi-agency search is — and it starts calling campfires survivors. On a mixed-terrain test set it scores 60%, which is just the arithmetic: it accepts all survivors and rejects one false-positive type in five.

Federating teaches every drone all five tells, without anyone sharing raw data. Same test sets, same model class: ~92%.

For reference, pooling everyone's raw data into one dataset scores 94.9%. Federation captures nearly all of the benefit while the footage never leaves the drone — which is the entire argument.

What is actually federated

client_app.py loads that drone's own sensor rows and never puts them in a Message. Only an ArrayRecord of model coefficients and a few scalar metrics go back. The privacy claim is enforced by what the file does and does not send, not by a promise in a README.

Each round, every drone reports both numbers — how the global model scores on its local test set, and what it would score training entirely alone — so the comparison is visible live rather than asserted at the end. The solo baseline is a fully-converged model on the same local data, i.e. the strongest possible "go it alone", making the comparison conservative.

A note on making FedAvg work here

The clients are pathologically non-IID by construction, and that broke the obvious approach. Letting each drone train to convergence locally and then averaging produces a model that accepts everything (~50%): each client converges on "only my one cue matters", and averaging five such models yields five weak weights against an intercept calibrated for one strong one.

What works is proper FedAvg — one local SGD epoch per round, so clients never drift that far — plus centering the cue scores so the intercept isn't doing all the work. With those two changes the accuracy climbs smoothly from 50% to ~92% over 40 rounds instead of oscillating or crawling.

Run it

uv sync
uv run flwr run . supergrid --federation <your-simulation-federation> --stream

Fewer rounds for a quicker demo (the curve still reads clearly, it just lands a little lower):

uv run flwr run . --run-config 'num-server-rounds=20' --stream

The server prints a per-round accuracy line and finishes with a ##FL_RESULT## JSON summary containing the accuracy trajectory and the scored candidate detections, which is what the companion swarm-sar-commander AgentApp consumes to draft a rescue dispatch plan for a human to approve.

Honest scope

The sensor data is synthetic and deliberately constructed so the non-IID effect is legible. The point being demonstrated is the mechanism — that agencies with differently-biased local data get materially better together without pooling it — not a validated survivor-detection model. Real thermal SAR data would need real validation.