Published 2026 | Version v1
Software Restricted

Cross-Dataset Plant Disease Classification Under Field Conditions: Reproducible Unsupervised Domain Adaptation and Pareto-Guided Model Selection

  • 1. ROR icon Arab Academy for Science, Technology, and Maritime Transport

Contributors

  • 1. ROR icon Arab Academy for Science, Technology, and Maritime Transport

Description

Plant Swarm is a reproducible research stack for transfer-aware plant disease detection and classification. It combines curated dataset loaders, Ultralytics YOLO detection wrappers, TIMM-based classifiers, and mixed-variable multi-objective swarm search so that Pareto-optimal configurations can be surfaced for both laboratory and in-field imagery.

Overview

The framework targets experiments where PlantDoc provides heterogeneous web imagery for supervised training and FieldPlant contributes expert-annotated, in-field images for transfer evaluation. Mixed-variable Particle Swarm Optimisation (PSO/MOPSO) explores hyperparameters, preprocessing switches (CLAHE, Retinex, HSV jitter), and model families (YOLOv8/YOLOv8s, ResNet, EfficientNet) while respecting latency and size constraints.

 

Methodology

Data ingestion & preprocessing

Deterministic dataset recipes in configs/dataset/plantdoc.yaml and configs/dataset/fieldplant.yaml define folder layouts, splits, augmentations, and Albumentations equivalents so cross-validation runs are reproducible. PlantDoc operates in folder-labelled classification mode, whereas FieldPlant accepts a _classes.csv annotation file with multi-label columns. The optional configs/dataset/cross.yaml trains on PlantDoc while reserving FieldPlant for evaluation-only transfer.

Label spaces differ across benchmarks; configs/labels/fieldplant_to_plantdoc.json records a mapping for collapsing FieldPlant labels into PlantDoc’s taxonomy when needed. During ingestion the loaders surface deterministic 80/10/10 splits (configurable via split_ratios) and honour environment overrides (FIELDPLANT_PATH).

Model families

Classification uses TIMM backbones through plantswarm/models/cls_timm.py with linear heads for efficient fine-tuning or frozen-feature evaluation. Detection experiments rely on Ultralytics YOLO wrappers in plantswarm/models/det_yolo.py and the training helper in plantswarm/training/det_loop.py so YOLOv8 variants can be called programmatically inside the search loop.

Optimisation strategy

The plantswarm/search/ package implements a hierarchy of swarm optimisers:

  • pso_base.py defines particles, velocity updates, and convergence utilities for continuous search.
  • mopso.py and pso_ndwpso.py extend this base to multi-objective settings that preserve non-dominated archives.
  • qd_mapelites.py adds quality-diversity (QD) archiving so distinct high-performing solutions are retained alongside the Pareto front.

Continuous hyperparameters (learning rate, HSV jitter) and discrete switches (model family, CLAHE variants) are encoded jointly through plantswarm/search/spaces.py, allowing mixed-variable exploration inside each particle vector.

Multi-objective search setup

Search configuration files describe which objectives and design variables are active. For example, configs/search/mopso_transfer.yaml targets detection transfer with the mixed space defined in configs/space/joint.yaml:

Objective key Description Source
mAP_in PlantDoc validation mean Average Precision Ultralytics evaluation inside each YOLO run
mAP_xfer FieldPlant evaluation mAP using the same checkpoint --external-test fieldplant evaluation hooks
latency_ms Median inference latency on the evaluation device Timing wrapper inside the evaluator
params_M Total learnable parameters in millions Model summary from TIMM/Ultralytics

Mixed-variable search spaces combine continuous and categorical descriptors. In configs/space/joint.yaml the swarm jointly tunes learning rate bounds and HSV augmentation intensity alongside discrete toggles for the YOLO variant and CLAHE grid size (off, grid4, grid8). Alternative spaces such as configs/space/cls.yaml restrict the search to classification-only backbones, while configs/space/preproc.yaml isolates preprocessing ablations.

Pareto archiving & quality diversity

MOPSO maintains an external archive of non-dominated solutions. Each particle’s objective vector is compared against the archive; solutions with worse accuracy or higher latency are discarded so the Pareto frontier remains compact. When the archive becomes dense, crowding-distance pruning is applied to preserve coverage across the trade-off surface. The optional MOPSO_QD mode (see configs/search/qd_mopso.yaml) hybridises Pareto selection with MAP-Elites-style bins from plantswarm/search/qd_mapelites.py, ensuring that rare but practically valuable configurations (e.g., ultra-low latency) stay discoverable for deployment studies.

Training & evaluation workflow

Classification branch

The CLI supports deterministic classification training with TIMM backbones, Albumentations augmentation, and optional cross-dataset evaluation:

# Train on PlantDoc and evaluate its validation split
plantswarm train --dataset plantdoc --epochs 20 --ckpt runs/plantdoc.pt

# Cross-dataset evaluation using FieldPlant without fine-tuning
plantswarm eval runs/plantdoc.pt fieldplant --split test

# Joint configuration: train on PlantDoc, validate on FieldPlant during training
plantswarm train --dataset plantdoc --epochs 20 \
  --external-test fieldplant --ckpt runs/plantdoc_fieldplant.pt
 

Hyperparameters (--lr, --weight-decay, cosine scheduling) inherit defaults from the dataset YAMLs and can be overridden per run. Albumentations pipelines in the YAML files are activated automatically; --no-albumentations falls back to torchvision-only augmentations for ablation studies.

Detection branch

Ultralytics models plug into the same infrastructure via the dedicated wrappers:

# Minimal YOLOv8n training on a YOLO-format dataset definition
python - <<'PY'
from pathlib import Path
from plantswarm.models.det_yolo import create_model
from plantswarm.training import det_loop

model = create_model(name="yolov8n", num_classes=15, pretrained=True)
det_loop.train(model, data=Path("data/fieldplant/yolo.yaml"), epochs=50, imgsz=640,
               project="runs/det", name="fieldplant_yolov8n")

# Evaluate the resulting checkpoint on PlantDoc-style export
metrics = model.val(data="data/plantdoc/yolo.yaml", imgsz=640)
print(metrics.results_dict)
PY
 

The dataset argument accepts any Ultralytics-compatible YAML, enabling PlantDoc or FieldPlant splits exported to bounding-box format. During multi-objective search these wrappers run inside the evaluator so that mAP, latency, and parameter counts are collected consistently. Detection metrics contribute to the same Pareto archive (mAP_in, mAP_xfer) alongside resource objectives, allowing direct comparison with classification baselines during joint search experiments.

Domain adaptation recipe

Unsupervised domain adaptation (UDA) can be invoked directly from the CLI. PlantDoc remains the labelled source dataset while FieldPlant images provide the unlabeled target domain:

plantswarm train --dataset plantdoc --epochs 15 --uda \
  --uda-method pseudo --uda-threshold 0.6 --uda-epochs 5 --uda-lr 1e-4 \
  --external-test fieldplant --ckpt runs/uda_pseudo.pt
 

The helper script benchmarks/uda_sweep.py automates sweeps over --uda-threshold, --uda-epochs, --uda-lr, and --uda-method (pseudo-labels, entropy minimisation, DANN) to profile sensitivity. It now exposes the supervised training epochs, optional dataset size cap, and pretrained toggle as CLI arguments so the default invocation runs a publication-grade sweep:

python benchmarks/uda_sweep.py --train-epochs 20 --uda-epochs 10 15 --uda-lrs 3e-4 1e-4
 

Results are written to runs/uda_sweep_results.json for tables and plots. Pass --dataset-size 2 --train-epochs 1 --no-pretrained to reproduce the lightweight smoke test used in CI.

Swarm sweep for hyperparameter refinement

Once supervised and UDA baselines are in place, run the built-in particle swarm helper to explore a handful of learning-rate, weight-decay, and augmentation knobs without writing a custom script:

plantswarm swarm \
  --dataset plantdoc \
  --iters 15 \
  --ckpt runs/swarm/plantdoc_swarm.pt \
  --verbose
 

The command maintains a small population of particles, iteratively updates them against PlantDoc validation accuracy, and writes three artefacts next to the provided checkpoint path:

  • plantdoc_swarm.pt – validation-best weights for the best-performing particle.
  • plantdoc_swarm.sweep.csv – iteration-by-iteration metrics for every particle.
  • plantdoc_swarm.params.json – hyperparameters associated with the best checkpoint.

Store swarm results in dedicated subdirectories (as shown above with runs/swarm/) so their metadata files do not collide with other checkpoints. Use the CSV/JSON outputs to compare against the UDA runs and decide which configurations should seed the more advanced search scripts under configs/search/*.yaml.

Interpretability & artifacts

Every run captures deterministic splits, metric logs, and checkpoints under runs/. Search executions emit per-particle summaries including metric vectors and configuration dictionaries, enabling Pareto-front visualisation. Optional confident-learning passes flag likely label issues before optimisation, while exported YOLO validation visualisations and Grad-CAM overlays (produced through the evaluation helpers) support qualitative analyses for paper figures.

Reproduction checklist

  1. Sync datasets – Download PlantDoc and FieldPlant, arrange them according to configs/dataset/*.yaml expectations, and confirm _classes.csv aligns with configs/labels/fieldplant_to_plantdoc.json when running transfer experiments.
  2. Baseline training – Reproduce the classification baselines with plantswarm train using the dataset configs above. Export accuracy/F1 tables for both in-domain and cross-domain splits.
  3. Domain adaptation sweep – Execute benchmarks/uda_sweep.py with full-dataset defaults (or adjusted arguments for your hardware budget) to select UDA hyperparameters. Record runs/uda_sweep_results.json for supplementary materials.
  4. Swarm sweep – Run plantswarm swarm after locking in supervised/UDA baselines to capture quick PSO refinements. Archive the .pt, .sweep.csv, and .params.json artefacts under a dedicated directory such as runs/swarm/.
  5. Search configuration – Choose a search template from configs/search/*.yaml and adjust objective weights or iteration counts. Modify the design variables through configs/space/*.yaml if additional preprocessing toggles are required.
  6. Launch PSO/MOPSO/QD runs – Follow the commands in docs/search.md to execute classification-only, detection-only, or joint searches. Archive the emitted Pareto fronts and configuration JSON for reproducibility.
  7. Report artefacts – Collect qualitative figures (Grad-CAM, YOLO detection overlays), confident-learning audit reports, and metric summaries to accompany paper-ready documentation.

Documentation & support

  • User guide – docs/user_guide.md covers dataset preparation, CLI walkthroughs, and troubleshooting tips.
  • Dataset notes – docs/datasets.md expands on data layouts, augmentation policies, and validation splits.
  • Search methodology – docs/search.md details the PSO/MOPSO/QD implementations, configuration knobs, and execution recipes for the optimisation stack.
  • Full documentation site – Visit docs/index.md (rendered via MkDocs) for roadmaps, CLI references, and planning spreadsheets.

Ready-made commands, YAML templates, and detailed diagrams are designed so you can cite this repository in academic work and reproduce cross-dataset optimisation studies out of the box.

Files

Restricted

The record is publicly accessible, but files are restricted. Log in to check if you have access.