SAR_3_band_model / README.md
2320sharon's picture
Update README.md
6db94e7 verified
|
Raw
History Blame Contribute Delete
5.28 kB
---
license: cc0-1.0
tags:
- remote-sensing
- sentinel-1
- sar
- semantic-segmentation
- water-segmentation
- shoreline
- onnx
- torchgeo
library_name: onnx
---
# SAR_3_band_model
Binary **land/water semantic segmentation** for Sentinel-1 SAR imagery. A U-Net with a
ResNet-50 encoder, fine-tuned from the SSL4EO-S12 Sentinel-1 MOCO weights
(`ResNet50_Weights.SENTINEL1_GRD_MOCO`) on a 3-band composite: **VV, VH, VV−VH (dB)**.
Built for shoreline delineation: the water mask is vectorized and intersected with
shore-normal transects to give a shoreline position per Sentinel-1 acquisition.
## Model details
| | |
|---|---|
| Architecture | U-Net decoder + ResNet-50 encoder (TorchGeo `SemanticSegmentationTask`) |
| Encoder init | `ResNet50_Weights.SENTINEL1_GRD_MOCO` (SSL4EO-S12, self-supervised) |
| Input | 3 channels: VV, VH, VV−VH (**dB scale**, normalized) |
| Classes | `0 = land`, `1 = water` (`255 = ignore/nodata`) |
| Training | 50 epochs, cross-entropy, AdamW (lr 1e-3), batch 8, 512×512 chips, 16-mixed precision |
| Checkpoint | `epoch=46-val_loss=0.0719` |
| Format | ONNX, dynamic batch/height/width (~130 MB) |
## Performance
Held-out validation split (113 scenes, site-disjoint from training):
| Overall acc. | Overall IoU | Water IoU | Land IoU |
|---|---|---|---|
| 0.9724 | 0.9462 | 0.9571 | 0.9280 |
End-to-end shoreline accuracy against an independent optical shoreline dataset
(16 US coastal sites, ~97,500 transect observations): **RMSE 60.1 m, MAE 25.2 m,
bias +9.8 m**. Excluding two sites with known reference-data problems: RMSE 37.0 m,
MAE 21.3 m.
This 3-band, no-speckle-filter configuration was the best of four variants tested
(2-band vs 3-band × with/without a Refined Lee filter), winning 12 of 16 sites.
Applying a speckle filter before the network consistently hurt accuracy.
## Inputs and outputs
```
input image float32 [batch, 3, H, W] (normalized)
output logits float32 [batch, 2, H, W]
water_prob float32 [batch, 1, H, W] softmax(logits)[:, 1] = P(water)
```
`H` and `W` must be **multiples of 32** (encoder stride). Pad bottom/right with 0.0
and crop the output back.
## Classes
The model predicts two classes per pixel. The `logits` channel axis is in this order:
| Index | Class | Meaning |
|---|---|---|
| 0 | `land` | Anything that is not open water: beach, dune, vegetation, buildings, bare soil, and exposed intertidal flats. Generally high or variable SAR backscatter. |
| 1 | `water` | Open water: ocean, bay, estuary, river, lake, and standing floodwater. Generally low SAR backscatter, because a smooth water surface reflects the radar pulse away from the sensor. |
Take `argmax(logits, axis=1)` for a hard class map, or threshold `water_prob`
(which is P(class 1)) at 0.5 for the same result with control over the operating
point. Raise the threshold for a more conservative water mask, lower it to catch
more wind-roughened water.
Because the classes are defined by backscatter, the land/water boundary this model
finds is the **instantaneous waterline at the time of acquisition**, not a tidal
datum. Correct for tide separately if you need a datum-based shoreline.
A third value, **255 = nodata/ignore**, appears in the training labels and in the
prediction rasters this project writes, but **the model never outputs it**. It marks
pixels with no valid input: outside the scene footprint, or nodata/NaN in VV or VH.
Carry your input validity mask through inference and stamp 255 into those pixels
yourself after `argmax`.
## ⚠️ Preprocessing is NOT in the graph
The graph starts at the normalized tensor. Do this yourself, in order:
1. Read VV and VH in **dB**, tracking invalid pixels (nodata / NaN / ±Inf).
2. Derive `VV−VH` (dB difference) and stack as `[VV, VH, VV−VH]`.
3. Fill invalid pixels with that channel's mean.
4. Normalize `(x - mean) / std`:
| Channel | mean | std |
|---|---|---|
| VV | −12.59 | 5.26 |
| VH | −20.26 | 5.91 |
| VV−VH | 10.5465 | 7.6855 |
5. Pad `H`/`W` up to a multiple of 32.
**No speckle filter.** This model was trained on raw dB, so do not apply Lee/Refined
Lee before inference.
Preprocessing facts are also embedded in the ONNX `metadata_props`:
## Training data
792 Sentinel-1 IW GRD scenes (10 m, VV+VH, dB) over US coastal sites: 679 train and
113 validation, split by site so no site appears in both. Labels are a random-forest
water/land classification of Lee-ENL-filtered composites, manually reviewed and
re-labelled for problematic sites.
Augmentation: random horizontal/vertical flips (p=0.5), random 90° rotations,
Gaussian noise (σ=0.1). Scenes are randomly cropped/padded to 512×512 and never
globally resized, which would smear SAR edges and corrupt categorical labels.
## Limitations
- **Sentinel-1 IW GRD in dB only.** Linear amplitude/power, other sensors, or a
different speckle-filter state will degrade results.
- Trained on US coastal sites; performance elsewhere (ice, very sheltered/vegetated
water, extreme incidence angles) is untested.
- Wind-roughened water and radar shadow on steep terrain are the common failure
modes for SAR water segmentation generally.
- Slight landward shoreline bias (~+10 m) relative to optical references.