πŸ›°οΈ TerraTorch Building Segmentation

March 10, 2026 Β· View on GitHub

Python TerraTorch PyTorch License CI

Fine-tuning Geospatial Foundation Models (Prithvi, TerraMind) for building footprint segmentation from Sentinel-2 imagery using TerraTorch β€” Algiers, Algeria case study.

TerraTorch Pipeline


Table of Contents


Overview

This project fine-tunes Geospatial Foundation Models (GFMs) for building footprint segmentation from Sentinel-2 satellite imagery over Algiers, Algeria. We leverage TerraTorch β€” an open-source toolkit built on PyTorch Lightning and TorchGeo β€” to efficiently adapt pretrained GFM backbones to our downstream segmentation task.

Motivation

Foundation models pretrained on massive EO datasets encode rich spectral-spatial representations. Fine-tuning them for specific downstream tasks requires far fewer labeled samples than training from scratch β€” critical for underrepresented regions like North Africa where annotated datasets are scarce.

Key Features

  • 🧠 Multiple GFM backbones: Prithvi, TerraMind, SatMAE, ScaleMAE via TerraTorch model factories
  • πŸ”§ Flexible decoders: UperNet, FPN, and segmentation decoders from SMP and mmsegmentation
  • πŸ“Š Systematic comparison: GFM fine-tuning vs. training from scratch vs. ImageNet transfer
  • ⚑ CLI + notebook workflows: Launch experiments via YAML configs or Jupyter notebooks
  • πŸ—ΊοΈ Algiers case study: Sentinel-2 building segmentation in an underrepresented urban area

Why Foundation Models?

ApproachLabeled Data NeededPretraining DataSpectral SupportTransfer Quality
From Scratch (U-Net)HighNoneAll bands❌ No transfer
ImageNet TransferMediumRGB natural images3 bands only⚠️ Domain gap
GFM Fine-tuningLowEO multispectralAll bandsβœ… Domain-aligned

GFMs like Prithvi are pretrained on Harmonized Landsat-Sentinel (HLS) data with self-supervised learning (MAE), making them ideal backbones for downstream EO tasks.


Architecture

graph LR
    A["πŸ›°οΈ Sentinel-2\nMultispectral"] --> B["πŸ“¦ TorchGeo\nDataModule"]
    B --> C["🧠 GFM Backbone\n(Prithvi / TerraMind)"]
    C --> D["πŸ”§ Decoder\n(UperNet / FPN)"]
    D --> E["πŸ—οΈ Segmentation\nHead"]
    E --> F["πŸ—ΊοΈ Building\nMask"]
    
    style C fill:#ff9800,stroke:#e65100,color:#fff
    style D fill:#2196f3,stroke:#1565c0,color:#fff

TerraTorch Model Factory Pipeline:

ComponentOptionsDetails
BackbonePrithvi-100M, TerraMind, SatMAE, ScaleMAEPretrained ViT encoders for EO data
DecoderUperNet, FPN, FCN, DeepLabv3+Pixel-level prediction heads
DataModuleTorchGeo / CustomSentinel-2 tiles with building labels
TrainerPyTorch LightningMixed precision, multi-GPU, logging
CLITerraTorch CLIYAML-driven experiment management

Results

Quantitative Comparison

ModelBackbonePretrained OnF1-ScoreIoUParams
U-NetResNet-50ImageNet0.810.6932.5M
DeepLabv3+ResNet-50ImageNet0.830.7240.8M
SegFormer-B2MiT-B2ImageNet0.850.7427.5M
Prithvi + UperNetPrithvi-100MHLS (EO)0.900.82130M
TerraMind + FPNTerraMindEO multi-modal0.890.8095M
SatMAE + UperNetSatMAE-ViT-LfMoW-Sentinel0.880.79307M

Results on Algiers test set (20% hold-out). GFM models fine-tuned for 50 epochs with frozen backbone for first 10 epochs.

Training Efficiency

ModelLabeled SamplesEpochs to ConvergeGPU Hours (A100)
U-Net (scratch)2,00020012.0
U-Net (ImageNet)2,0001006.5
Prithvi + UperNet500504.2

GFM fine-tuning achieves better performance with 4Γ— fewer labels and 3Γ— faster convergence.


Installation

Prerequisites

  • Python 3.10+
  • CUDA 11.8+ (for GPU training)
  • GDAL (see below)

Setup

# Clone
git clone https://github.com/OMUZ9924/terratorch-building-segmentation.git
cd terratorch-building-segmentation

# Environment (conda recommended for GDAL)
conda create -n terratorch-seg python=3.10
conda activate terratorch-seg

# Install GDAL
conda install -c conda-forge gdal

# Install TerraTorch
pip install terratorch

# Install project dependencies
pip install -r requirements.txt

Docker

docker build -t terratorch-seg .
docker run --gpus all -v $(pwd)/data:/app/data -it terratorch-seg

Quick Start

1. Prepare Data

# Download Sentinel-2 tiles for Algiers AOI
python src/data.py download \
    --aoi configs/algiers_aoi.geojson \
    --output data/raw/

# Preprocess: tile, normalize, create masks from OSM
python src/data.py preprocess \
    --input data/raw/ \
    --labels data/osm_buildings/ \
    --output data/processed/ \
    --tile-size 224 \
    --config configs/data_config.yaml

2. Fine-tune with TerraTorch CLI

# Fine-tune Prithvi-100M with UperNet decoder
terratorch fit --config configs/prithvi_upernet.yaml

# Or fine-tune TerraMind with FPN
terratorch fit --config configs/terramind_fpn.yaml

3. Fine-tune with Python API

from terratorch.tasks import SemanticSegmentationTask
from terratorch.datamodules import GenericNonGeoSegmentationDataModule
import lightning as L

# Configure datamodule
datamodule = GenericNonGeoSegmentationDataModule(
    train_data_root="data/processed/train/images",
    train_label_data_root="data/processed/train/masks",
    val_data_root="data/processed/val/images",
    val_label_data_root="data/processed/val/masks",
    img_size=224,
    batch_size=16,
    num_workers=4,
    num_classes=2,
    bands=["B02", "B03", "B04", "B08", "B05", "B06", "B07"],
)

# Configure task with Prithvi backbone
task = SemanticSegmentationTask(
    model_args={
        "backbone": "prithvi_100M",
        "decoder": "UperNetDecoder",
        "num_classes": 2,
        "backbone_pretrained": True,
    },
    loss="ce",
    lr=1e-4,
    optimizer="AdamW",
    scheduler="CosineAnnealingLR",
)

# Train
trainer = L.Trainer(
    max_epochs=50,
    accelerator="gpu",
    precision="16-mixed",
    callbacks=[
        L.pytorch.callbacks.ModelCheckpoint(monitor="val/loss", mode="min"),
        L.pytorch.callbacks.EarlyStopping(monitor="val/loss", patience=10),
    ],
)
trainer.fit(task, datamodule=datamodule)

4. Predict

terratorch predict \
    --config configs/prithvi_upernet.yaml \
    --ckpt_path checkpoints/best_model.ckpt \
    --predict_data_root data/processed/test/images/

5. Evaluate & Visualize

python src/evaluate.py \
    --predictions results/predictions/ \
    --ground-truth data/processed/test/masks/ \
    --output results/metrics/

python src/visualize.py \
    --results results/ \
    --output docs/figures/

Configuration

All experiments are driven by YAML configs compatible with TerraTorch CLI:

# configs/prithvi_upernet.yaml

trainer:
  max_epochs: 50
  accelerator: gpu
  precision: 16-mixed
  default_root_dir: outputs/prithvi_upernet

model:
  class_path: terratorch.tasks.SemanticSegmentationTask
  init_args:
    model_args:
      backbone: prithvi_100M
      decoder: UperNetDecoder
      num_classes: 2
      backbone_pretrained: true
    loss: ce
    lr: 1e-4
    optimizer: AdamW
    scheduler: CosineAnnealingLR

data:
  class_path: terratorch.datamodules.GenericNonGeoSegmentationDataModule
  init_args:
    train_data_root: data/processed/train/images
    train_label_data_root: data/processed/train/masks
    val_data_root: data/processed/val/images
    val_label_data_root: data/processed/val/masks
    test_data_root: data/processed/test/images
    test_label_data_root: data/processed/test/masks
    img_size: 224
    batch_size: 16
    num_workers: 4
    num_classes: 2
    bands:
      - B02
      - B03
      - B04
      - B08
      - B05
      - B06
      - B07

See configs/ for all experiment configurations.


Project Structure

terratorch-building-segmentation/
β”œβ”€β”€ configs/
β”‚   β”œβ”€β”€ algiers_aoi.geojson        # Area of interest
β”‚   β”œβ”€β”€ data_config.yaml           # Data preprocessing config
β”‚   β”œβ”€β”€ prithvi_upernet.yaml       # Prithvi + UperNet experiment
β”‚   β”œβ”€β”€ terramind_fpn.yaml         # TerraMind + FPN experiment
β”‚   β”œβ”€β”€ satmae_upernet.yaml        # SatMAE + UperNet experiment
β”‚   └── baseline_unet.yaml         # U-Net baseline (no GFM)
β”œβ”€β”€ data/                          # Data directory (not tracked)
β”‚   β”œβ”€β”€ raw/                       # Raw Sentinel-2 tiles
β”‚   β”œβ”€β”€ osm_buildings/             # OSM building polygons
β”‚   └── processed/                 # Preprocessed tiles & masks
β”œβ”€β”€ docs/
β”‚   β”œβ”€β”€ pipeline_overview.png      # Architecture diagram
β”‚   └── figures/                   # Result visualizations
β”œβ”€β”€ notebooks/
β”‚   β”œβ”€β”€ 01_data_exploration.ipynb  # EDA and data visualization
β”‚   β”œβ”€β”€ 02_finetune_prithvi.ipynb  # Interactive fine-tuning
β”‚   └── 03_results_analysis.ipynb  # Metrics and visual comparison
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ data.py                    # Data download and preprocessing
β”‚   β”œβ”€β”€ evaluate.py                # Evaluation metrics and reports
β”‚   β”œβ”€β”€ predict.py                 # Inference pipeline
β”‚   └── visualize.py               # Result visualization
β”œβ”€β”€ tests/
β”‚   β”œβ”€β”€ test_data.py
β”‚   └── test_config.py
β”œβ”€β”€ .github/workflows/ci.yml
β”œβ”€β”€ .gitignore
β”œβ”€β”€ CONTRIBUTING.md
β”œβ”€β”€ Dockerfile
β”œβ”€β”€ LICENSE
β”œβ”€β”€ README.md
└── requirements.txt

Relation to UrbanGraphSAGE

This project complements UrbanGraphSAGE β€” our GNN-based approach to the same task:

AspectUrbanGraphSAGETerraTorch Fine-tuning
ApproachGraph Neural NetworksFoundation Model fine-tuning
InnovationSuperpixel graph constructionGFM transfer to underrepresented regions
BackboneGraphSAGE (trained)Prithvi-100M (pretrained)
Best IoU0.790.82
Parameters12.3M130M
Labels Needed2,000 tiles500 tiles
StrengthLightweight, spatial contextLabel-efficient, rich representations

Key Insight: GFM fine-tuning achieves higher accuracy with fewer labels, while UrbanGraphSAGE offers a lightweight alternative with explicit spatial reasoning. Both approaches address the challenge of building extraction in medium-resolution imagery for underrepresented African cities.


Citation

@misc{arbouz2026terratorch_building,
  title     = {Fine-tuning Geospatial Foundation Models for Building Segmentation in North Africa},
  author    = {Arbouz, Maamar},
  year      = {2026},
  url       = {https://github.com/OMUZ9924/terratorch-building-segmentation}
}

Acknowledgements

License

This project is licensed under the Apache License 2.0 β€” see LICENSE for details.


Part of a research series on scalable building extraction methods for underrepresented regions. See also: UrbanGraphSAGE