Models
DeepTrees’ crown-delineation model is made of two sub-networks – a segmentation model
(predicts the tree-cover mask and crown outlines) and a distance model (predicts the
distance transform used to separate touching crowns). Both are built with
segmentation_models_pytorch
(SMP) and are fully configurable: you can switch the underlying architecture and encoder
backbone through the model.architecture and model.backbone keys in your config
YAML, without touching any code.
Supported architectures
Set via model.architecture. Every architecture below is available to both the
segmentation and distance sub-networks:
|
Notes |
|---|---|
|
Default. Classic encoder-decoder with skip connections. Good general-purpose choice. |
|
Unet with nested, densely-connected skip pathways. |
|
Lightweight encoder-decoder, cheaper than Unet. |
|
Feature Pyramid Network decoder. |
|
Pyramid Scene Parsing decoder. |
|
Pyramid Attention Network decoder. |
|
Atrous/dilated convolution decoder. |
|
DeepLabV3 with an added decoder for sharper boundaries. |
|
Transformer-based (SegFormer). Requires a Mix Vision Transformer backbone – see below. |
Backbones
Set via model.backbone. For every architecture except Segformer, this can be any
encoder supported by SMP – e.g. resnet18, resnet34, resnet50,
efficientnet-b0, and many more. See SMP’s own
encoder list for the full set.
Segformer is the one exception: it requires a Mix Vision Transformer backbone –
mit_b0 through mit_b5 (mit_b0 is the smallest/fastest, mit_b5 the
largest). Passing a CNN backbone (e.g. resnet18) with architecture: Segformer
will fail, since SMP’s Segformer decoder is only wired up for MiT-style encoder outputs.
Example: switching architectures
The default (Unet + resnet18), as used in the shipped predict/train configs:
model:
in_channels: 5
architecture: Unet
backbone: resnet18
Switching to a Segformer model instead only requires changing these two lines:
model:
in_channels: 5
architecture: Segformer
backbone: mit_b0
Everything else in the config (data, augmentation, postprocessing, trainer settings)
stays the same – architecture/backbone are the only knobs that change which
model gets built.
Encoder pretrained weights
Independently of which architecture/backbone you pick, model.encoder_weights
(train configs) controls whether the encoder starts from SMP’s ImageNet-pretrained
weights (imagenet) or random initialization (null). This is unrelated to loading
a full DeepTrees checkpoint (below) – it only affects the encoder, and only matters
when training a new model, not when loading an already-trained one.
Loading a pretrained DeepTrees checkpoint
This is the part that catches people out: the config’s architecture/backbone is not
read from the checkpoint file. It has to be set correctly before the checkpoint is
loaded, because the predict/inference code builds the model from
model.architecture/model.backbone first, and only then loads weights into that
already-built structure. Nothing inspects the checkpoint to figure out what produced it.
For prediction (config/predict/*.yaml), the checkpoint is set via:
model:
in_channels: 5
architecture: Segformer # must match how the checkpoint was trained
backbone: mit_b0 # must match how the checkpoint was trained
download_pretrained_model: False
pretrained_model_path: ./pretrained_models
pretrained_model_name: my_segformer_checkpoint_jitted.pt
For training/fine-tuning (config/train/*.yaml), the equivalent is the top-level
pretrained block (pretrained.path / pretrained.model).
If architecture/backbone don’t match what the checkpoint actually is, loading
fails loudly and immediately with a RuntimeError listing missing/mismatched state
dict keys (e.g. a ResNet checkpoint loaded against a Segformer-configured model
will complain about missing keys like encoder.conv1.weight, which only exist in a
ResNet encoder). This is a safe failure mode – it will not silently produce a broken
or nonsensical model – but there’s no upfront check; you only find out at load time.
in_channels must match the checkpoint too, for the same reason.
Note
Different pretrained checkpoints are not interchangeable just because they’re both
.pt files. A Unet/resnet18 checkpoint only loads into a
Unet/resnet18-configured model, and likewise for Segformer/mit_b0.
Keep track of which architecture/backbone each of your checkpoints was trained with.
Known limitations
Segformer training does not currently work on Apple’s MPS backend. It hits a PyTorch/MPS operator gap in a transformer reshape operation (
view size is not compatible with input tensor's size and stride). Training falls back to CPU, which works correctly but without GPU acceleration on Mac. CUDA GPUs are unaffected.