DeepContrail segmentation: UPerNet + CAFormer-B36 (v0.1.0)

Contrail segmentation model for DeepContrail. It takes a GOES-16 ABI false-colour composite and returns, for each pixel, the probability that it shows a contrail. It was trained on the OpenContrails dataset (20250305 export).

Usage

Install the DeepContrail packages from git; they are not on PyPI yet:

pip install \
    "deepcontrail-core @ git+https://github.com/eurocontrol-asu/deepcontrail@v0.1.0#subdirectory=packages/core" \
    "deepcontrail-segmentation @ git+https://github.com/eurocontrol-asu/deepcontrail@v0.1.0#subdirectory=packages/segmentation"
import numpy as np
from deepcontrail.core import false_color_from_spectral, read_band_manifest
from deepcontrail.segmentation import load_pretrained, predict

model = load_pretrained("eurocontrol-asu/deepcontrail-segmentation", revision="v0.1.0")
bands = np.load(f"{root}/spectral_bands/test/{record_id}.npy")
composite = false_color_from_spectral(bands, model.config.false_color, read_band_manifest(root))
probabilities = predict(model, composite, tta=model.config.tta)  # (H, W), float32 in [0, 1]
mask = probabilities > model.config.threshold

root is a dataset in the DeepContrail format; the OpenContrails converter produces it from the raw TFRecords. predict also takes a batch (N, H, W, 3).

Model

  • Architecture: UPerNet decoder with a CAFormer-B36 encoder (timm caformer_b36.sail_in22k_ft_in1k_384), from segmentation-models-pytorch; 102.6 M parameters.
  • Input: a 3-channel composite in [0, 1] (below) of a 256 Γ— 256 scene, resized to 512 px and normalised with mean [0.485, 0.456, 0.406], std [0.229, 0.224, 0.225]. predict does this.
  • Output: contrail probability at the input's resolution; contrail where > 0.5.
  • Test-time augmentation: recommended; it averages the 8 flips and rotations.

Input composite (standard ash RGB)

Channel Bands Bounds (scaled to [0, 1], clipped)
R data_12um βˆ’ data_11um (GOES-16 ABI bands 15 βˆ’ 14) [βˆ’4, 2] K
G data_11um βˆ’ cloud_top (GOES-16 ABI bands 14 βˆ’ 11) [βˆ’4, 5] K
B data_11um (GOES-16 ABI band 14) [243, 303] K

The bands are referred to by their keys in the dataset's bands.json.

Training

  • Data: the OpenContrails 20250305 export. Of its 20,088 training scenes, 10% (2,009, seed
    1. were held out for validation, so the model trained on 18,079 scenes.
  • Labels: the per-pixel fraction of annotators who marked a contrail (soft labels).
  • Recipe: 40 epochs at 512 px, batch 32, AdamW (learning rate 1e-4, weight decay 1e-2), cosine schedule with 3 warm-up epochs, BCE + 0.2 Γ— Dice loss, bf16 mixed precision, flips, 90Β° rotations and small shift/scale/rotate augmentations. The checkpoint with the best validation Dice was kept. The full configuration is experiment.yaml.

Evaluation

Global Dice on the held-out test split: 1,879 scenes, the OpenContrails validation shards, never used for training or model selection.

Inference Threshold Test Dice
Single pass 0.5 0.6892
Single pass tuned on validation 0.6913
Test-time augmentation 0.5 0.6960
Test-time augmentation tuned on validation 0.6936

GPU training is not bit-for-bit reproducible. Four trainings of this exact configuration, with the same seed and data, scored 0.6916–0.6960 (test-time augmentation, threshold 0.5); this model is the best of the four.

Instance segmentation

This repository also holds the instance step tuned for this model, which splits its probability map into individual contrails (one mask and one score each):

  • instance_pipeline.yaml: the settings of the deepcontrail-instance pipeline (threshold, Mannstein line detection, growth);
  • score_model.json: a learned score that ranks the detected contrails, trained on this model's test-time-augmented predictions for 1,000 of its validation scenes.

They are not part of the v0.1.0 revision. They need deepcontrail-instance from the repository's main branch (not yet in a release):

pip install "deepcontrail-instance[map] @ git+https://github.com/eurocontrol-asu/deepcontrail#subdirectory=packages/instance"
from deepcontrail.instance import load_instance_step, to_coco_results

model = load_pretrained("eurocontrol-asu/deepcontrail-segmentation")  # main revision
step = load_instance_step(model.directory, tta=model.config.tta)
masks, scores = step(predict(model, composite, tta=model.config.tta))
results = to_coco_results(masks, scores, image_id=record_id)  # COCO results with RLE masks

On the 1,879 test scenes, scored against each annotator's contrails (2,700 annotator samples with at least one contrail), these settings reach a COCO segmentation mAP of 0.277 (averaged over IoU 0.25–0.75), with precision 0.516, recall 0.382 and F1 0.439 at IoU 0.5. The settings and the score were chosen on validation scenes only. The score model is valid only for this model's probabilities made with test-time augmentation on 256 Γ— 256 scenes; load_instance_step and the pipeline refuse other uses.

Limitations

  • Sensor and scene size. Trained on GOES-16 ABI scenes of 256 Γ— 256 pixels (about 2 km per pixel). predict resizes any input to 512 Γ— 512, so other sizes or non-square scenes are not supported yet.
  • Label convention. The 20250305 masks are aligned with the images. The older 20230419 export and the Kaggle competition data put the masks half a pixel down-right: on those, call predict(..., pixel_shift=0.5).
  • Other label sets. The 20250305 masks overlap the 20230419/Kaggle ones at an IoU of only about 0.78, so scores on the two are not directly comparable. An earlier training of this same configuration scored 0.6914 (private) / 0.6994 (public) on the hidden test set of the Kaggle Google Research – Identify Contrails to Reduce Global Warming competition.

Provenance

Training run upernet-caformer-b36-512-20250305-final
Checkpoint best-val_dice=0.6963.ckpt
Code DeepContrail 0.1.0
Data OpenContrails GOES-16 ABI TFRecords, export 20250305

Licence and attribution

The weights are released under the Apache License 2.0 by EUROCONTROL. If you redistribute them, as they are or modified, keep the NOTICE file with them. The DeepContrail code is under the EUPL-1.2.

If you use this model, please cite the OpenContrails dataset:

@article{Ng2024ContrailDO,
  title={Contrail Detection on GOES-16 ABI With the OpenContrails Dataset},
  author={Joe Yue-Hei Ng and Kevin McCloskey and Jian Cui and Vincent R. Meijer and Erica Brand and Aaron Sarna and Nita Goyal and Christopher Van Arsdale and Scott Geraedts},
  journal={IEEE Transactions on Geoscience and Remote Sensing},
  year={2024},
  volume={62},
  pages={1-14}
}
Downloads last month
-
Safetensors
Model size
0.1B params
Tensor type
F32
Β·
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support