Architecture and prototyping map
Use this map to locate a change before editing the pipeline. BatBot’s small public API wraps lower-level processing functions; notebook experiments should call those implementations instead of maintaining independent approximations.
Area |
Responsibility |
Typical change and validation |
|---|---|---|
|
Lazy high-level imports; preprocessing and legacy batch adapters |
Preserve signatures, ordering, lightweight import, and per-file failures |
|
Waveforms, STFT, normalization, candidate/contour extraction, images and metadata |
Compare real and synthetic WAVs; inspect debug outputs and timing metadata |
|
Immutable label/model configuration; verified resources and Pooch mirror/cache |
Validate label order, SHA-256, local/mirror parity, offline bundled use |
|
Unicode-safe BGR image loading and uint8 window transforms |
Match training geometry, padding, strides, color ordering, dtype |
|
Provider setup, SessionOptions, reused sessions, ordered threaded inference |
Real model smoke plus provider/fallback/threading regressions |
|
File discovery, bounded WAV worker batches, aggregation, failures, summaries |
Test mixed inputs, worker isolation, cleanup, counts, and duplicate names |
|
Native paths/cache roots; Click commands and JSON/progress boundaries |
Windows drives/UNC, Unicode, environment expansion, JSON stdout |
|
Interactive exploration and labeled evaluation, not a second production API |
Execute clean notebooks; verify exported reports and scientific interpretation |
What a WAV classification actually does
WAV (original file retained)
-> mono waveform -> resample to 250 kHz
-> STFT: 512-point FFT, 256-sample Blackman-Harris window, 16-sample hop
-> select approximately 5–120 kHz; blank nonphysical bands above input Nyquist
-> subtract per-frequency median, apply gain/autogain, clip, quantize, flip
-> compute(fast_mode=False)
|-> full uncompressed JPEG chunks ------------> classifier input
|-> compressed chirp images, masks, metadata -> inspection/prototyping
`-> debug=True: TIFF/PNG diagnostics ---------> inspection only
-> resize each input to height 224, horizontal scale 0.5
-> 224x224 BGR uint8 windows, stride 100; pad narrow images
-> ONNX inference in bounded window batches
-> mean scores per image -> window-count-weighted scores per WAV
-> top label, top-k, all scores, window count -> file-level summary
The default gain is currently 120 dB before optional median-absolute-deviation autogain. Consult the implementation for exact frequency-bin edges and thresholds. The notebooks show actual arrays and output files. Resampling a low-rate recording does not recover absent ultrasonic frequencies.
fast_mode=True is a separate, reduced preprocessing mode: it uses 8-bit
data and different candidate windows and omits full segmentation. It is not
the current WAV classifier default. Do not change training-sensitive transforms
or switch full/compressed images simply because a preview looks clearer.
A full spectrogram’s horizontal axis retains acquisition time; compressed
images concatenate selected ranges and no longer have a continuous time axis.
Classifier windows overlap and are not one-to-one with calls or individual bats.
species_counts counts successful input-file predictions, excluding NOISE;
it is not a population estimate. A score is not a calibrated probability.
Public APIs and error boundaries
from pathlib import Path
from batbot import classifier
runner = classifier.Classifier(providers=["CPUExecutionProvider"], num_workers=1)
images = runner.classify([Path("data/call.jpg")], progress=False)
recording = runner.classify_wav(Path("data/recording.wav"), progress=False)
report = runner.classify_bulk(
[Path("data/input")], input_type="auto",
preprocess_workers=1, progress=True,
spectrogram_output=Path("artifacts/spectrograms"),
)
print(report["summary"])
Successful result dictionaries include path, label, confidence,
window_count, top, and scores. WAV results can include retained
spectrogram_paths. Bulk failures contain path and error. Validate
input discovery and failed-file counts as well as successful predictions.
Runtime/provider initialization errors are meaningful configuration failures;
do not catch them and quietly label all affected files as biological noise.
pre -> predict -> post remains available for lower-level experiments.
Inference workers share one validated session and preserve ordering. WAV
preprocessing uses spawned processes, staged in bounded batches, so native
threads/GPU state are not inherited. Thread count, inference workers,
preprocessing workers, and batch size affect different resources; benchmark
them separately. Never start unbounded processes from notebook cells.
Reproducible model experiments
Record model filename/hash, class order, software versions, active execution providers, parameters, dataset revision and permissions, and manual-label provenance. Split evaluation data at an appropriate recording/site/night or project level to avoid leakage from overlapping calls. Keep the same baseline and summarize failures and class support, not only aggregate accuracy.
The labeled performance script accepts LABEL/*.wav and LABEL/*.jpg
or *.jpeg and applies genus ordering to plot shading. It does not relabel
model outputs. Use held-out, reviewed labels; a folder name alone does not
establish trustworthy ground truth. Discuss research/training extensions in
BatAI, and contribute monitoring data via
the NABat database.