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.
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.
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:
Read VV and VH in dB, tracking invalid pixels (nodata / NaN / ±Inf).
Derive VV−VH (dB difference) and stack as [VV, VH, VV−VH].
Fill invalid pixels with that channel's mean.
Normalize (x - mean) / std:
Channel
mean
std
VV
−12.59
5.26
VH
−20.26
5.91
VV−VH
10.5465
7.6855
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.