FTP-PRUE+ (EfficientNet-B3) β Fields of the Planet
3m PlanetScope field-boundary segmentation model from Fields of the Planet (FTP), a PlanetScope companion to Fields of the World v2 (FTW). This is the paper's main headline model.
U-Net decoder over an EfficientNet-B3 encoder, trained on paired early- and peak-season PlanetScope surface-reflectance imagery (8 input channels: 2 seasonal windows x 4 bands) to predict a 3-class field mask (background / field / boundary) at 3m ground sample distance.
- Repo: taylor-geospatial/ftw-planet
- Paper: Fields of the Planet: Field Boundary Mapping Beyond 10m
- Architecture:
smp.Unet(encoder_name="efficientnet-b3"),in_channels=8,classes=3 - Training resolution: 512x512 crops, 3m/px
- Loss: log-cosh Dice, class weights
[0.05, 0.2, 0.75],ignore_index=3 - Recipe: PRUE+ (geometry/noise augmentations, watershed post-processing, D4 TTA at eval)
Files
| File | Format | Notes |
|---|---|---|
config.json + model.safetensors |
segmentation_models_pytorch Hub format |
recommended for most users β safetensors (no pickle), self-describing architecture, needs only pip install segmentation-models-pytorch |
ftp-b3.ckpt |
PyTorch Lightning checkpoint | state_dict + hyper_parameters only β optimizer/scheduler state stripped |
ftp-b3.onnx |
ONNX (opset 17) | single-file, dynamic batch/H/W, needs onnxruntime (plain PyTorch cannot execute .onnx) |
ftp-b3.pt2 |
torch.export ExportedProgram |
standalone, dynamic batch / static 512x512, loads with torch.export.load β no ftw_planet install needed |
Usage
segmentation_models_pytorch (recommended)
import segmentation_models_pytorch as smp
model = smp.from_pretrained("taylor-geospatial/ftp-b3").eval()
logits = model(image) # image: (B, 8, H, W) float32, 2 seasonal windows x 4 bands
Lightning checkpoint (raw smp.Unet)
The checkpoint's state_dict is just an smp.Unet under a model. prefix β
unless you need the Lightning training wrapper, smp.from_pretrained above
is simpler.
import torch
import segmentation_models_pytorch as smp
ckpt = torch.load("ftp-b3.ckpt", map_location="cpu")
hp = ckpt["hyper_parameters"]
model = smp.Unet(encoder_name=hp["backbone"], encoder_weights=None, in_channels=hp["in_channels"], classes=hp["num_classes"])
model.load_state_dict({k.removeprefix("model."): v for k, v in ckpt["state_dict"].items()})
model.eval()
logits = model(image) # image: (B, 8, H, W) float, 2 seasonal windows x 4 bands
ONNX
import onnxruntime as ort
sess = ort.InferenceSession("ftp-b3.onnx", providers=["CPUExecutionProvider"])
logits = sess.run(None, {"image": image_np})[0] # image_np: (B, 8, H, W) float32
torch.export (standalone, no ftw_planet needed)
import torch
exported = torch.export.load("ftp-b3.pt2")
model = exported.module()
logits = model(image) # image: (B, 8, 512, 512) float32, any batch size
Output is 3-class logits (background / field / boundary); argmax + the
repo's watershed post-processing (scripts/eval/postprocess_eval.py)
recovers instance polygons.
Results
Macro-averaged over the 10 dense held-out FTW-v2 countries, true-polygon scoring at native 3m GSD (see paper Table 1): PQ 35.5, sub-0.5ha PQ 15.7, matched-boundary error 7.4m.
Citation
@misc{ftw-planet,
author = {Corley, Isaac and Robinson, Caleb and Marcus, Jennifer and Kerner, Hannah},
title = {Fields of the Planet: Field Boundary Mapping Beyond 10m},
year = {2026},
url = {https://github.com/taylor-geospatial/ftw-planet}
}
License
Weights: CC-BY-NC-4.0. Trained on PlanetScope imagery (c) Planet Labs PBC, exported under the NICFI / research program, and FTW v2 polygons (CC-BY-4.0). Refer to those source terms for any redistribution of the underlying data.
- Downloads last month
- -