Imported from nikih94/fungseg (
AGENTS.md). Install upstream withnpx skills add nikih94/fungseg. Copyright stays with the author.
Agent Guide for fungseg
This file is the repository-level working agreement for coding agents. It applies to the entire repository unless a more specific AGENTS.md is added in a subdirectory.
Mission and source of truth
fungseg is a config-driven PyTorch project for patch-based fungal-network segmentation. It supports:
- binary segmentation of one configured target (
lociorinoculum); and - multiclass segmentation with background
0, loci1, and inoculum2.
When documentation and implementation disagree, inspect the code, active YAML configurations, and tests first. Then update the documentation in the same change. Do not preserve a stale behavior in docs merely because it appears in an older document.
Repository structure
.
├── AGENTS.md # agent instructions and maintenance rules
├── README.md # user quickstart and operational guide
├── DESCRIPTION.md # architecture and module map
├── PATCHING_DESCRIPTION.md # detailed patch-generation behavior
├── FIVES_REMOVAL.md # removal checklist for optional FIVES training support
├── config.yaml # current binary experiment
├── multiclass-config.yaml # multiclass U-Net++/ResNet50 experiment
├── multiclass-config-HRNet.yaml # matching multiclass HRNetV2-W32 experiment
├── multiclass-config-deeplabV3+.yaml # matching multiclass DeepLabV3+/ResNet50 experiment
├── multiclass-config-segformer.yaml # matching multiclass SegFormer MiT-B3 experiment
├── multiclass-config-1080.yaml # related 1080-oriented multiclass experiment
├── multiclass-segformer-mit-b1-refinement-config.yaml # multiclass MiT-B1 refinement experiment
├── multiclass-segformer-mit-b2-refinement-config.yaml # multiclass MiT-B2 refinement experiment
├── multiclass-segformer-config.yaml # multiclass SegFormer MiT-B5 experiment
├── multiclass-segformer-mit-b3-geometry-config.yaml # obsolete MiT-B3 geometry-loss compatibility experiment
├── config_segformer_mit_b3.yaml # binary SegFormer MiT-B3 experiment
├── requirements.txt # runtime dependencies
├── data/ # local datasets and split metadata
├── src/ # application code
│ ├── analyze_soft_skeleton_iterations.py # Soft-clDice iteration diagnostic
│ ├── build_soft_cldice_iteration_map.py # Exact per-loci-mask iteration CSV
│ ├── add_soft_cldice_iteration_margin.py # Safety-margin training CSV
│ ├── benchmark_cldice.py # Reference Zhang CPU/CUDA diagnostic benchmark
│ ├── benchmark_cldice_patches.py # Batched foreground-patch hard-clDice benchmark
│ ├── data/soft_cldice_iterations.py # Per-mask training-iteration CSV mapping
│ ├── data/patch_cache.py # Run-level training and fold-local validation caches
│ ├── utils/run_resume.py # Atomic fold-resume state and cleanup helpers
│ ├── inference/ # inference, recursive prediction, and evaluation workflows
│ ├── models/hrnet.py # MMSeg HRNetV2-W32 plus plain FCN-head adapter
│ ├── models/segformer_refinement.py # MiT-B1/B2/B3 full-resolution refinement model
│ └── ... # data, engine, models, patching, metrics, and utilities
├── tests/ # unit and integration tests
├── runs/ # generated training runs
├── outputs/ # generated inference/diagnostic outputs
├── extract-mask.py # standalone mask-extraction utility
└── venv/ # local virtual environment, if present
Archives, historical output folders, checkpoints, generated images, __pycache__, and the local virtual environment are artifacts rather than application modules. Do not edit or commit generated artifacts unless the task explicitly requires it.
Data organization
The default dataset is organized as follows:
data/
├── FIVES/ # optional training-only retinal images and masks
│ ├── Original/
│ └── Ground truth/
├── images/ # source microscopy/macroscopy images
├── loci_masks/ # binary loci masks, matched by filename stem
├── inoculum_masks/ # binary inoculum masks, matched by filename stem
├── join_masks/ # optional sparse join-region masks, matched by filename stem
├── image_splits.csv # filename,split assignments for train/validation/test
├── other-test-data/ # external paper image collections for inference
├── small-test/ # auxiliary local test data
└── test/ # auxiliary local test data
Rules:
- Training discovery is top-level within the configured image and mask directories; matching is by filename stem.
- Binary mode uses the directory selected by
segmentation.targetandpaths.mask_dirs. - Multiclass mode uses only complete, dimension-matched image/loci-mask/inoculum-mask sets. Training and evaluation exclude incomplete or mismatched required sets with named warnings. Configured join masks are optional per image; valid masks can be merged into loci for training, or loaded only by CSV test evaluation for join metrics and red overlay boundaries. Absent masks leave targets unchanged and dimension-mismatched optional masks are ignored with warnings.
data/image_splits.csvmust containfilename,split. Forward-looking rows without a currently usable pair are validated, named in a warning, and ignored. Every currently usable pair must be assigned to exactly one non-emptytrain,validation/val, ortestsplit. Incsv_kfoldmode, test membership remains fixed in every fold while the combined train/validation pool is partitioned for cross-validation.- Split membership is assigned to original images, never to individual patches. Never introduce patch-level leakage between train and validation/test.
data/other-test-data/is recursively processed bysrc.inference.other_test_data_evaluation; its generated results belong under its results directory and must not be treated as training data.data/FIVES/is optional auxiliary training data controlled bydata.use_fives; it never participates in fungal splits, validation, or test evaluation.data/small-test/anddata/test/are auxiliary local data locations, not inputs to the defaultconfig.yamlrun unless a configuration explicitly points to them.
Do not commit private datasets, large archives, checkpoints, or generated masks unless the repository explicitly requires them.
Code organization
Entrypoints
src/train.py: discovery, split construction, loaders, model/loss/optimizer/scheduler construction, fold execution, per-fold test evaluation and aggregation, and optional qualitative evaluation.src/benchmark_cldice_patches.py: seeded foreground-patch CPU/CUDA hard-clDice timing and per-patch equivalence artifacts.src/benchmark_cldice.py: paper-reference Zhang CPU/CUDA diagnostic timing and equivalence overlays for a prediction/target mask pair; production hard-clDice uses scikit-image on CPU.src/inference/__main__.py: single-image or non-recursive directory inference with overlapping-patch stitching.src/inference/recursive_masks.py: recursive binary/multiclass mask-only inference into a mirrored sibling directory.src/inference/in_folder.py: legacy recursive binary inference that writes masks next to source images.src/inference/other_test_data_evaluation.py: recursive inference for external paper image collections.src/inference/test_evaluation.py: CSV test-split evaluation and threshold/class metric artifacts.src/inference/val_train_set_eval.py: train/validation evaluation for a supplied best checkpoint, with aggregate CSV metrics and split-specific overlays.src/inference/qualitative_evaluation.py: checkpoint comparison on selected labeled crops.src/visualize_fives_patches.py: one-image diagnostic for optional FIVES center-patch geometry.
Core packages
src/inference/: shared image loading, patch prediction, stitching, output conversion, and inference/evaluation entrypoints.src/data/: discovery, source-level split logic, lazy datasets, transforms, and patch diagnostics.src/patching/:OriginalImageRecord,PatchRecord, deterministic edge-covering grids, training randomization, scaled context, resampling, and foreground filtering.src/models/: model factory, SegFormer full-resolution refinement, output normalization, and decoder normalization helpers.src/losses/: binary and multiclass loss implementations plus the loss factory.src/metrics/: segmentation metrics and loss-component diagnostics.src/engine/: training/validation loop, single-pass stitched full-image validation with patch loss, checkpointing, metric export, and TensorBoard logging.src/optim/andsrc/schedulers/: configurable optimizer and scheduler factories.src/utils/: config merging/compatibility, checkpoint I/O, serialization, logging, and reproducibility helpers.
Keep responsibilities within these boundaries. Add behavior to the appropriate package and expose it through an entrypoint only when it is an actual user workflow. Avoid putting model-specific logic in the trainer, split logic in datasets, or hard-coded paths in reusable modules.
Development invariants
- Configuration is the source of truth. Add new user-tunable behavior to YAML and
src/utils/config.pydefaults rather than hard-coding it in an entrypoint. - Preserve source-image grouping. Any new sampler, patch transform, or validation path must retain source IDs and prevent data leakage.
- Keep binary and multiclass semantics explicit. Binary models use one sigmoid output and thresholding; multiclass models use three class logits, softmax, and argmax. Do not silently apply binary threshold logic to multiclass outputs.
- Preserve deterministic geometry. Stitched full-image validation, test evaluation, and inference must cover edges and average overlapping predictions consistently.
- Use the existing factories for models, losses, optimizers, and schedulers. When adding a supported option, update the relevant factory, configuration example, tests, and docs together.
- Treat each checked-in experiment YAML as an independent source of truth. Tests may enforce shared pipeline semantics such as multiclass class IDs, output shape, and monitor availability, but must not require tunable patching, augmentation, loss, optimizer, scheduler, or training values to match another experiment. Architecture guides document option behavior; exact experiment values belong in the active YAML.
- Keep masks and predictions shape-safe. Check image/mask dimensions at discovery or evaluation boundaries and preserve class IDs or binary encoding when saving outputs.
- Prefer small, composable functions with type hints and
pathlib.Path. Keep entrypoints thin and make reusable behavior testable without requiring a full training run. - Avoid unnecessary dependencies. If a dependency is required at runtime, add it to
requirements.txtand document why. - Do not change user data, runs, outputs, checkpoints, or environment files as part of a code change unless that mutation is explicitly requested.
Standard workflow for agents
Before editing:
- Read this file and the relevant section of
README.md,DESCRIPTION.md, orPATCHING_DESCRIPTION.md. - Inspect the active configuration and the implementation that owns the behavior.
- Search for callers, tests, output names, and documentation references before renaming or removing anything.
- Check the working tree and preserve unrelated user changes.
While editing:
- Make the smallest coherent change that satisfies the task.
- Reuse existing helpers and conventions before adding parallel implementations.
- Update tests for changed behavior, especially for split logic, patch geometry, output encoding, configuration compatibility, and multiclass behavior.
- Keep generated files out of the patch.
After editing:
venv/bin/python -m unittest discover -s tests -p 'test_*.py'
Also run focused tests or lightweight module checks relevant to the change. Do not launch a full training run unless requested or necessary for verification. Review the final diff for stale names, hard-coded run timestamps, undocumented files, and accidental generated artifacts.
Documentation synchronization policy
Documentation is part of the implementation contract. Every code, config, data-layout, CLI, output, or repository-structure change must include the corresponding documentation update in the same change.
Use these ownership rules:
README.md: user-facing commands, supported workflows, data setup, configuration behavior, model/loss choices, and output usage.DESCRIPTION.md: architecture, module responsibilities, data flow, ownership boundaries, and run-artifact structure.PATCHING_DESCRIPTION.md: patch size/stride/overlap, edge coverage, offsets, scaled context, resampling, foreground filtering, phase behavior, and patch diagnostics.FIVES_REMOVAL.md: complete removal checklist for optional FIVES support; update it when that support's integration points change.AGENTS.md: repository tree, data organization, development invariants, workflow, and documentation-maintenance rules.
Mandatory synchronization checklist:
- If a file, directory, module, entrypoint, config, or output location is added, removed, renamed, or repurposed, update the repository tree and relevant descriptions in
AGENTS.mdandDESCRIPTION.md. - If a CLI flag, config key, model, loss, split mode, output artifact, or data requirement changes, update
README.mdand the owning architecture/patching guide. - If patch construction or filtering changes, update
PATCHING_DESCRIPTION.mdand its references inREADME.md/DESCRIPTION.md. - Remove obsolete commands, filenames, hard-coded run examples, and claims about behavior that no longer exists.
- Keep links and command examples pointing to files that actually exist. The canonical patching filename is
PATCHING_DESCRIPTION.md. - Do not mirror tunable YAML values in architecture guides unless an example is explicitly illustrative; changing only an experiment parameter does not require a documentation edit.
- Do not finish a structural change while
AGENTS.mdstill describes the old repository layout. The structure section must be updated in the same change.
At the end of every task, search the documentation for the old name or behavior and verify that the documented tree, commands, and outputs match the current repository.
Handoff expectations
Final reports should state:
- what changed and which files were touched;
- what verification was run and its result;
- any known limitations or intentionally unchanged compatibility paths; and
- any user action still required.