SawitGuard-GNN — Model Card

Trained weights for the SawitGuard-GNN oil palm risk-ranking pipeline (Datathon 2026, RISTEK Fasilkom UI, University Track Semifinal). Code: SawitGuard-GNN. Companion data: oil-palm-detection-data.

Licence note. The MIT tag above covers these weights. The datasets they were trained on carry their own upstream licences, one of which (Eg9PP, CC BY-SA 4.0) is share-alike — see the companion dataset card before redistributing anything derived from them.

Model description

SawitGuard-GNN is two independently-evaluated layers, deliberately not merged into one model:

  • Layer 1 (UAV imagery → per-tree crown inventory)
    • layer1/yolo12_runs/*/weights/best.pt — YOLOv12n crown detector (ds_B, Roboflow UAV tiles)
    • layer1/lightgbm_health/model.txt — LightGBM crown-health classifier (RGB colour/texture features)
    • ExG+Otsu crown-area segmentation is a parameter-free per-image algorithm (no trained weights)
    • layer1/anom_peru/ — the same YOLO architecture trained on an independent Peru dataset, a separate cross-site evidence line (never merged with the ds_B weights)
  • Layer 2 (per-tree contact graph → disease-spread forecast)
    • layer2/stgnn_final.pt — full model, 24 input features (self-history + genotype + neighbour state), trained on the Eg9PP 25-year field panel
    • layer2/stgnn_v3_photo.pt — single-photo variant, 1 input feature (neighbour symptomatic status only) — this is the checkpoint the demo actually runs, since a single UAV photo cannot supply the other 23 columns (18 of 24 are simply unfillable from one flight: 4 need a time axis, 14 are genotype, invisible from imagery)

Intended use

A ground-inspection prioritization demonstrator: given one UAV photo (or a sample tile), rank detected trees by estimated near-term BSR risk so a plantation can direct manual inspection instead of sweeping a whole block. It is not a certified BSR/Ganoderma diagnostic, and its Layer 1 "Unhealthy" label is generic crown-health from crowdsourced UAV annotation, not field-verified disease status.

Out of scope: any automated treatment/removal decision, any claim about trees outside the training sites/sensors, any performance number quoted from a live demo session (the demo checkpoint was never itself evaluated on held-out data — see Evaluation below).

Training data

See the companion dataset card (datasets/dataset_card.md in the sibling oil-palm-detection-data repo) for full provenance, licenses, and the tile-overlap deduplication procedure. In short: Layer 1 detector + health classifier train on layer1_uav_crowns (Roboflow ds_B, CC BY 4.0); Layer 1 Peru weights train on peru_palm_anomaly (CC BY 4.0); Layer 2 trains on layer2_eg9pp_panel (Tisné et al. 2017, CC BY-SA 4.0).

Evaluation

All numbers below are leave-one-orthomosaic-out (Layer 1, 3 folds) or leave-one-parcel-out (Layer 2, 2 folds) block cross-validation — never random splits, which leak on this data (tiles overlap ~30×). Significance is judged by the project's paired() rule everywhere: report mean±std across paired (fold, seed) units plus a sign-count, and call anything with |mean| < 1 std INCONCLUSIVE.

Layer 1 — crown detection & health (ds_B, primary)

Metric Value Note
Crown-centre F1 (primary metric) 0.960 ± 0.024 conf threshold 0.75, cross-fold selected
Precision / Recall 0.950 ± 0.019 / 0.971 ± 0.030
Centre RMSE 0.071 ± 0.011 × planting spacing
mAP50 0.687 ± 0.071 label-ceilinged — GT boxes are fixed-size stamps, not tight boxes; not directly comparable to detection literature
mAP50-95 0.425 ± 0.078
Crown-health PR-AUC 0.182 ± 0.059 LightGBM, random baseline ≈ 0.013
Crown-health ROC-AUC 0.861
Bridge degree, predicted vs. Layer 2 5.54 ± 0.12 vs. 5.74 3.5% apart — interface compatibility check, not a joined dataset

Layer 1 — Peru transfer (anom_peru/, supporting, ⚠ 1 fold / 1 seed only)

mAP50 0.9495, mAP50-95 0.7032. Not comparable to the ds_B numbers above — no mean±std exists for this run, so the paired-significance rule doesn't apply. Reported as qualitative cross-site support only. Two caveats travel with it: the "full" control (crown+context) scores worse than crown alone (ROC-AUC 0.880 vs. 0.952 — surrounding pixels dilute signal, not add it), and the detector over-predicts by 36% (1.72 boxes/image vs. 1.267 ground-truth), so the high mAP50 does not mean tree counting is accurate.

Layer 2 — Eg9PP full model (stgnn_final.pt, 24 features, W=3, pooled AP)

h (census horizon) STRUCTURE (true − random contact map) sign-count verdict
1 +0.0044 ± 0.0046 30/40 INCONCLUSIVE
2 +0.0098 ± 0.0060 37/40 POS
3 +0.0151 ± 0.0081 39/40 POS (paper-primary)
4 +0.0165 ± 0.0097 39/40 POS

Layer 2 — photo variant (stgnn_v3_photo.pt, 1 feature, W=1, within-census AP — the fair metric for ranking inside one snapshot, and what the demo evaluates against)

Metric Value Note
Within-census AP, correct graph 0.1015 ± 0.0079 (6-column ablation) / 0.0916 ± 0.0081 (1-column, demo config)
vs. full model (24-col) within-census AP 0.0973 ± 0.0107 photo variant is not weaker: +0.0042 ± 0.0035, 36/40 POS
STRUCTURE (true − random), within-census +0.0296 ± 0.0057, 40/40 POS 77% of the photo variant's skill comes specifically from the correct contact map
Lift over no-skill, clean input 1.45× (1-column) this is the demo's own configuration
Lift over no-skill, detector-noise input 1.27× (0.0800 AP) 59% of the signal survives substituting field status with detector output (recall 0.446, fpr 0.0094, measured on ds_B)
Within-family+parcel permutation null 0/200 permutations reach the observed value z=+6.04; 64% of the graph effect is spatial, 36% is family-relatedness contamination

Rejected/negative results, kept deliberately (do not silently re-claim these as positive):

  • SI(D) mechanistic head vs. plain STGNN: NEG at all 4 horizons (h=3: −0.029 ± 0.019, 4/40 positive)
  • Block-level (parcel) aggregation vs. per-tree ranking: lift 1.24× < per-tree 1.61× — rejected, per-tree list is the correct operational output
  • 2-hop diffusion: NEG
  • Per-class (Unhealthy) confidence threshold tuning vs. reusing the localisation threshold 0.75: F1 0.370 vs. 0.406 — rejected, keep 0.75

⚠ Never cite from a live demo run. The demo checkpoint (stgnn_v3_photo.pt) is the trained production model — it was fit on the full panel and was never itself scored on held-out data in that exact single-photo serving configuration. All performance numbers above come from the dedicated cross-validation scripts, not from the demo.

Known limitations

  • fold1 of the Layer 1 3-fold run (yolo12_runs/yolo12n_base_fold1_s42/) has no args.yaml (confirmed missing) — the exact Ultralytics training config for that fold is not recorded, only its weights and results.csv. Folds 0, 2, and the 1-fold verification run do have it.
  • Layer 1 "Unhealthy" is generic crowdsourced crown health, not field-verified BSR/Ganoderma — only the Layer 2 Eg9PP panel has field-verified disease labels.
  • Layer 1's F1 0.960±0.024 is measured leave-one-orthomosaic-out within one plantation. Imagery from a different estate, sensor, or flight altitude is an untested fourth domain.
  • Peru transfer numbers are 1 fold / 1 seed — do not compare to ds_B's 3-fold mean±std.
  • The photo-variant graph effect is 36% contaminated by family relatedness (measured, not assumed, via permutation null) — the remaining 64% is genuine spatial signal.
  • Detector-substitution cost is measured on ds_B's own detection error rates, not on Eg9PP's estate — the true end-to-end cost on a genuinely different site is not measured.
  • Layer 1 and Layer 2 are never joined at the data level (different estates, no georeferencing, no join key); only graph-structure compatibility is verified (5.54±0.12 vs. 5.74 mean degree).

License

Code: MIT (see the submission repository's LICENSE). Weights inherit the license of the data they were trained on for any redistribution of derived outputs — see the dataset card for per-dataset terms (CC BY 4.0 / CC BY-SA 4.0).

Citation

If you build on the Layer 2 weights (trained on the Eg9PP panel), please also cite:

Tisné, S. et al. (2017). Identification of Ganoderma disease resistance loci using natural field infection of an oil palm multiparental population. G3: Genes, Genomes, Genetics, 7(6), 1683–1692. https://doi.org/10.1534/g3.117.041764

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support