Instructions to use rohitm9/surfaceWaterGlobal_flood with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- fastai
How to use rohitm9/surfaceWaterGlobal_flood with fastai:
from huggingface_hub import from_pretrained_fastai learn = from_pretrained_fastai("rohitm9/surfaceWaterGlobal_flood") - Notebooks
- Google Colab
- Kaggle
Surface Water Global – Flood
This repository has two flood-water segmentation models. Each predicts a per-pixel probability of water (permanent water and flood water together) from one Sentinel-1 scene:
| Model | Folder | Inputs | Threshold |
|---|---|---|---|
| S1 + AEF | seed42/ |
Sentinel-1 + AlphaEarth Foundations (AEF) annual embedding | 0.10 |
| S1-only | s1_only/seed42/ |
Sentinel-1 only | 0.04 |
The two models were trained on the same data (W + O), with the same procedure and trainer. The only difference is whether the AEF embedding is an input, so the comparison below shows what AEF adds. The related surface-water model is at rohitm9/surfaceWaterGlobal.
Which model to use
- S1-only needs no AEF download. Its accuracy is about the same as S1 + AEF on PS9, FP60, Kuro Siwo and Bolivia (differences between −0.031 and +0.017 IoU, all intervals include zero). It finds more flood water on land that is normally dry, but it also makes more false alarms on dry land: on PS9 the false-alarm rate on normally dry land is 0.115, against 0.072 for S1 + AEF.
- S1 + AEF is better where a scene contains much normal (permanent) water. On PS53 its IoU is 0.087 [+0.044, +0.132] higher, and on C2S-MS it is about 0.08 higher (the interval includes zero). It makes fewer false alarms on every test set.
If AEF is easy to get for your area and year, use S1 + AEF. If you do not want to download AEF for every area, S1-only gives similar flood-water results on most test sets but more false alarms.
Model details
| Field | Value |
|---|---|
| Training data | W + O: 6,994 training chips (3,994 W + 3,000 O), 504 validation chips (86 W + 418 O) |
| Architecture | FastAI ResNet-34 U-Net |
| S1 + AEF input | 3 S1 bands + 64 AEF bands; AEF reduced 64 → 16 channels by a learned 1×1 convolution; 19 channels into the U-Net |
| S1-only input | 3 S1 bands |
| AEF dropout | none (0.0) |
| Loss | cross-entropy + Dice |
| Output | float32 GeoTIFF of P(water) (nodata −9999) |
| Released checkpoints | seed 42 of each model; the evaluation reports means over 3 training seeds (42, 43, 44) |
| Internal run names | FC_AEF_WO and FC_S1_WO (full_coverage_v1) |
Training sets
- W: Sen1Floods11 weakly labelled flood chips (512 px) for training, and Sen1Floods11 hand-labelled chips for validation.
- O: our global post-flood chips (2,072 px, EPSG:3857). Their labels are the Dynamic World
labelband, all water classes.
Training procedure: each epoch covers every 512 × 512 tile of every training chip once, and pixels are weighted by area. Pixels where VV or VH is missing are ignored in the loss. The saved checkpoint is the best over all training stages, judged by water IoU averaged equally over the two validation sources.
Files
surfaceWaterGlobal_flood/
README.md this file
LICENSE, THIRD_PARTY_NOTICES.md, requirements.txt
MODEL_INFO.json machine-readable summary
checksums.sha256 SHA-256 of the checkpoints, band_stats.npz files and the code
src/infer.py inference program for both models (run this)
src/train.py exact trainer that produced both checkpoints; infer.py imports it to build the network
seed42/ S1 + AEF model
models/s1aef_bottleneck_resnet34_best.pth weights (165 MB)
band_stats.npz 67-band normalization (mean, std)
s1aef_bottleneck_resnet34_eval_summary.json validation results and the selected threshold
s1aef_bottleneck_resnet34_threshold_sweep.csv
s1aef_bottleneck_resnet34_history.csv
aef_bottleneck_report.json
s1_only/seed42/ S1-only model
models/s1dw_resnet34_best.pth weights (165 MB)
band_stats.npz 3-band normalization (mean, std)
s1dw_resnet34_eval_summary.json validation results and the selected threshold
s1dw_resnet34_threshold_sweep.csv
s1dw_resnet34_history.csv
evaluation/
summary_all_tests.csv all test sets, both models and reference models, mean and SD over seeds
per_seed.csv both models, each training seed separately (column model = s1_aef / s1_only)
per_event.csv both models, IoU / precision / recall per event and seed, with pixel counts
contrasts_event_bootstrap.csv paired differences with 95 % event-bootstrap intervals
Installation
Python 3.10 or newer is recommended. Inference runs on CPU; a CUDA GPU is faster, at about 3 s per 768 × 768 scene with test-time augmentation on an A100.
pip install -U "huggingface_hub[cli]"
hf download rohitm9/surfaceWaterGlobal_flood --local-dir surfaceWaterGlobal_flood
cd surfaceWaterGlobal_flood
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
sha256sum -c checksums.sha256
To download only one model (about 165 MB instead of 330 MB), repeat --include for each pattern:
# S1-only model
hf download rohitm9/surfaceWaterGlobal_flood --local-dir surfaceWaterGlobal_flood \
--include "src/*" --include "s1_only/*" --include "requirements.txt" --include "checksums.sha256"
# S1 + AEF model
hf download rohitm9/surfaceWaterGlobal_flood --local-dir surfaceWaterGlobal_flood \
--include "src/*" --include "seed42/*" --include "requirements.txt" --include "checksums.sha256"
With a partial download, sha256sum -c checksums.sha256 --ignore-missing checks only the files present.
The checkpoints were trained and tested with Python 3.11, PyTorch 2.x and fastai 2.7.
Input data
- Sentinel-1 (both models): one 3-band GeoTIFF per scene, named
s1_YYYY-MM-DD.tif, with bands in the orderVV,VH,angle. The training data came from Earth EngineCOPERNICUS/S1_GRD(backscatter in dB, 10 m). Another processing chain (different calibration, terrain correction or speckle filter) gives different inputs, and the models have not been tested on them. - AlphaEarth (S1 + AEF model only): one 64-band annual embedding GeoTIFF (
GOOGLE/SATELLITE_EMBEDDING/V1/ANNUAL) in the original band order. Use raw values, not PCA-reduced values.- Which year: the model was trained and tested with the AEF year before the Sentinel-1 acquisition (year − 1), using 2017 when the acquisition is in 2017 or earlier. For a flood in 2024, use the 2023 embedding.
- This means the embedding describes the land before the flood.
- All S1 scenes in one run must share the same CRS, transform, width and height. The AEF raster may use another grid;
infer.pyreprojects it (bilinear) onto the S1 grid.
Pixels where S1 (or AEF, for the S1 + AEF model) is missing are written as nodata (−9999).
Example layout:
my_event/
s1/
s1_2024-09-28.tif
alphaearth_2023.tif (only for S1 + AEF)
Running inference
S1 + AEF:
python src/infer.py \
--model-kind s1aef \
--run-dir seed42 \
--scenes-root my_event/s1 \
--aef-path my_event/alphaearth_2023.tif \
--output-root outputs \
--tile 512 --overlap 64 --batch-size 4
The output is outputs/s1_aef_tta/probabilities/<year>/s1_<date>_prob.tif.
S1-only (no --aef-path):
python src/infer.py \
--model-kind s1 \
--run-dir s1_only/seed42 \
--scenes-root my_event/s1 \
--output-root outputs \
--tile 512 --overlap 64 --batch-size 4
The output is outputs/s1_only_tta/probabilities/<year>/s1_<date>_prob.tif.
Both commands also write run_config.json, scene_manifest.csv and scene_summary.csv.
- Add
--validate-onlyto check the files and grids without running the model. --device cpuforces CPU;--no-ttaturns off the four-flip test-time augmentation, which is faster but differs slightly from the evaluated setting.
Threshold
The output is a probability, not a mask. A water mask is P(water) >= threshold, with the threshold that maximized pooled water IoU on the 504 validation chips (sweep 0.005–0.80, with test-time augmentation):
| Model (seed 42) | Threshold | Validation water IoU | Precision | Recall |
|---|---|---|---|---|
| S1 + AEF | 0.10 | 0.736 | 0.834 | 0.862 |
| S1-only | 0.04 | 0.707 | 0.807 | 0.851 |
The evaluation below thresholds each training seed at its own validation value:
- S1 + AEF: 0.10, 0.05 and 0.10 for seeds 42, 43 and 44.
- S1-only: 0.04, 0.05 and 0.04 for seeds 42, 43 and 44.
The probabilities are not calibrated, and the best threshold also varies between test sets. For example, on C2S-MS the test-best threshold for models trained without P was 0.5–0.95. We recommend checking the threshold on labelled data from the target area if any are available.
Every number below is a single-model result averaged over the three training seeds. Results for seed 42 alone are in evaluation/per_seed.csv. For each model they are within 0.02 of the mean on every test set.
Evaluation
All results below use 10 m inference and each seed's validation threshold, and none of the test data were used for training, checkpoint selection or threshold selection. Within each test set, every model is scored on the same pixels. The event-mean IoU is computed by pooling IoU within each event and then averaging over events; values are the mean ± SD over the 3 seeds.
Test sets
| Test | Chips | Events | Label source | Water type |
|---|---|---|---|---|
| PS9 | 141 | 9 | PlanetScope (3 m) hand labels | flood + permanent |
| C2S-MS new7, S2 labels | 455 | 7 | hand labels drawn on Sentinel-2 | flood + permanent |
| C2S-MS new7, S1 labels | 455 | 7 | hand labels drawn on Sentinel-1 | flood + permanent |
| Bolivia (Sen1Floods11), S2 labels | 15 | 1 | hand labels drawn on Sentinel-2 | flood + permanent |
| Bolivia (Sen1Floods11), S1 labels | 15 | 1 | hand labels drawn on Sentinel-1 | flood + permanent |
| FP60 (FloodPlanet) | 60 | 6 | PlanetScope hand labels | flood + permanent |
| Kuro Siwo, 7 test events | 1,241 | 7 | labels drawn on Sentinel-1 | flood + permanent (scored together) |
| PS53 | 53 | 53 scenes | PlanetScope hand labels | normal surface water (no flood) |
Labels drawn on Sentinel-1 (C2S-MS S1, Bolivia S1 and Kuro Siwo) favour models that agree with what the radar shows. For this reason, we treat PS9 and C2S-MS with S2 labels as the main flood tests.
The C2S-MS events are Congo 2020, Czechia–Austria 2020, Houston 2017, Lake Victoria 2018, Nebraska 2019, Niger 2019 and Queensland 2019. The Kuro Siwo activations are 1111002, 205, 321, 411, 445, 561 and 562.
S1 + AEF compared with S1-only
Event-mean IoU (mean ± SD over 3 seeds). The difference is S1 + AEF minus S1-only, with its 95 % event-bootstrap interval (for Bolivia, a chip bootstrap):
| Test | S1 + AEF | S1-only | Difference [95 % interval] |
|---|---|---|---|
| PS9 | 0.506 ± 0.003 | 0.502 ± 0.004 | +0.004 [−0.019, +0.034] |
| C2S-MS new7, S2 labels | 0.639 ± 0.013 | 0.559 ± 0.005 | +0.080 [−0.006, +0.183] |
| C2S-MS new7, S1 labels | 0.722 ± 0.016 | 0.637 ± 0.007 | +0.085 [−0.006, +0.199] |
| Bolivia, S2 labels | 0.515 ± 0.018 | 0.536 ± 0.007 | −0.031 [−0.104, +0.023] |
| Bolivia, S1 labels | 0.608 ± 0.009 | 0.620 ± 0.011 | −0.017 [−0.077, +0.025] |
| FP60 | 0.515 ± 0.004 | 0.513 ± 0.001 | +0.002 [−0.021, +0.029] |
| Kuro Siwo | 0.648 ± 0.012 | 0.631 ± 0.007 | +0.017 [−0.024, +0.053] |
| PS53 (surface water) | 0.664 ± 0.014 | 0.577 ± 0.006 | +0.087 [+0.044, +0.132] |
Only the PS53 interval excludes zero. Each flood test has only 6 to 9 events, so most differences are not statistically resolved.
Pooled precision and recall (mean over seeds):
| Test | S1 + AEF precision / recall | S1-only precision / recall |
|---|---|---|
| PS9 | 0.767 / 0.676 | 0.732 / 0.698 |
| C2S-MS new7, S2 labels | 0.762 / 0.938 | 0.714 / 0.945 |
| C2S-MS new7, S1 labels | 0.838 / 0.963 | 0.792 / 0.972 |
| Bolivia, S2 labels | 0.689 / 0.671 | 0.663 / 0.736 |
| Bolivia, S1 labels | 0.766 / 0.748 | 0.727 / 0.809 |
| FP60 | 0.865 / 0.613 | 0.835 / 0.631 |
| Kuro Siwo | 0.699 / 0.901 | 0.655 / 0.945 |
| PS53 | 0.800 / 0.969 | 0.650 / 0.955 |
On every test set S1 + AEF has the higher precision and S1-only has the higher recall, except PS53, where S1 + AEF is higher on both. On Kuro Siwo, pooled F1 for all water (the metric of the Kuro Siwo paper) is 0.787 for S1 + AEF and 0.774 for S1-only.
Where the models make errors
Recall and false alarms by type of land, from the JRC Global Surface Water occurrence layer (rec_dry_mean, rec_wat_mean and far_dry_mean in summary_all_tests.csv):
| Test | Recall, normally dry land (S1 + AEF / S1-only) | Recall, normally water (S1 + AEF / S1-only) | False-alarm rate, normally dry land (S1 + AEF / S1-only) |
|---|---|---|---|
| PS9 | 0.46 / 0.51 | 1.00 / 0.99 | 0.072 / 0.115 |
| C2S-MS new7, S2 | 0.71 / 0.76 | 1.00 / 1.00 | 0.020 / 0.036 |
| FP60 | 0.25 / 0.29 | 0.99 / 0.98 | 0.045 / 0.072 |
| Kuro Siwo (flood class) | 0.89 / 0.94 | 0.94 / 0.95 | – |
Both models find almost all permanent water. Most errors are in flood water on land that is normally dry, which both models miss often. S1-only finds more of that flood water, but it also labels more dry land as water.
Comparison with other models (event-mean IoU, mean over seeds)
| Test | S1 + AEF | S1-only | S1 + AEF, W+O+P, AEF dropout | External |
|---|---|---|---|---|
| PS9 | 0.506 | 0.502 | 0.493 | |
| C2S-MS new7, S2 | 0.639 | 0.559 | 0.669 | |
| C2S-MS new7, S1 | 0.722 | 0.637 | 0.758 | |
| Bolivia, S2 | 0.515 | 0.536 | 0.444 | |
| Bolivia, S1 | 0.608 | 0.620 | 0.528 | |
| FP60 | 0.515 | 0.513 | 0.505 | OPERA DSWx-S1 0.443 |
| Kuro Siwo | 0.648 | 0.631 | 0.638 | Kuro Siwo FloodViT 0.724, SNUNet 0.738 |
| PS53 | 0.664 | 0.577 | 0.714 |
The AEF-dropout reference model (not released here) used the same training procedure. The Kuro Siwo checkpoints were trained on Kuro Siwo data, so this test set is in their training distribution.
Other paired differences (evaluation/contrasts_event_bootstrap.csv):
- S1 + AEF minus OPERA DSWx-S1 on FP60: +0.072 [−0.038, +0.171].
- S1 + AEF minus the Kuro Siwo FloodViT checkpoint on Kuro Siwo: −0.076 [−0.157, −0.010].
Limitations
- The models were trained on Earth Engine Sentinel-1 GRD inputs in dB, and the S1 + AEF model on AEF from the year before the image. Other inputs have not been tested.
- The training labels come from Dynamic World (O) and from Sen1Floods11 weak labels (W), not from field observations.
- Flooded vegetation, flooded urban areas and wet soil were not evaluated separately; C-band SAR methods in general have difficulty with them. The S1-only model may also label radar-dark dry surfaces (for example sand or smooth bare soil) as water, as the S1-only surface-water model did on arid terrain.
- Probabilities are not calibrated, and the best threshold depends on the test set.
- Do not use the output as the only basis for emergency-response, safety, regulatory or legal decisions.
Reproducibility check
src/infer.py reproduced the saved evaluation probabilities exactly (maximum absolute difference 0) for both released checkpoints, on three PS9 chips: Bangladesh 2017, Bolivia 2018 and Cambodia 2018.
License and attribution
The code and weights are released under Apache-2.0. See LICENSE and THIRD_PARTY_NOTICES.md. The training data also include Sen1Floods11 (Bonafilia et al., 2020); see https://github.com/cloudtostreet/Sen1Floods11 for its terms.