Skip to content

Add MobileNet ONNX species classification and modernize BatBot - #44

Merged
bluemellophone merged 14 commits into
mainfrom
jrp/ml-model
Oct 15, 2026
Merged

bluemellophone merged 14 commits into
mainfrom
jrp/ml-model

Conversation

@bluemellophone

@bluemellophone bluemellophone commented Aug 17, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

This PR prepares BatBot 0.2.0 by adding end-to-end bat-species classification with a bundled 35-label MobileNet ONNX model. Users can classify existing spectrograms, generate and classify spectrograms from WAV recordings, or process directory trees with fault-tolerant summaries and ordered multi-worker inference.

The PR also restructures the package so importing batbot is lightweight, consolidates project configuration in pyproject.toml, raises the minimum Python version to 3.11, modernizes testing and publishing workflows, and expands branch coverage to 82.7%.

High-level changes

Area Change impact
Classification Added a Scoutbot-inspired pre / predict / post ONNX inference pipeline and reusable Classifier Spectrograms can be classified directly into species codes and confidence scores
Model delivery Bundled the MobileNet model with SHA-256 verification and a pooch download mirror Installed packages work offline when the bundled model is present and can recover from the mirror
WAV and bulk processing Added WAV-to-spectrogram classification, recursive discovery, weighted aggregation, partial-failure handling, and summary statistics Large labeled or unlabeled datasets can be processed in one command
Concurrency Added bounded multi-worker ONNX inference sharing one validated session Users can increase throughput with --num-workers without loading one model per worker
CLI Added classify, classify-wav, and classify-bulk; completed fetch and the legacy batch path Classification is available without writing Python
Evaluation Added a performance plotting example for labeled WAV/JPG/JPEG datasets Users can generate confusion matrices, top-k metrics, MCC, and NOISE diagnostics
Package structure Moved high-level functions into batbot.api and added lazy submodule loading import batbot no longer initializes scientific/ONNX stacks or creates a log file
Packaging Consolidated metadata, dependencies, extras, and tool settings in pyproject.toml One authoritative configuration replaces duplicated setup and requirements files
CI/CD Updated the Python matrix, distribution validation, wheel smoke tests, and PyPI OIDC publishing Releases are tested from built artifacts and no longer require a long-lived PyPI token
Quality Added classifier, API, CLI, utility, cache, concurrency, and performance-example tests 79 tests pass, with one xdoctest skipped and 82.7% branch coverage

Classification and batch processing

  • Add batbot.classifier alongside the existing spectrogram component, following Scoutbot WIC’s pre → predict → post pattern.
  • Bundle the ONNX model and support SHA-256-verified downloads from the Kitware Data mirror through Pooch.
  • Classify existing spectrograms or generate spectrograms directly from WAV recordings.
  • Integrate parallel WAV preprocessing with bounded batch inference.
  • Reuse ONNX sessions across concurrent inference workers while preserving result order.
  • Report per-file predictions, class scores, failures, and aggregate species counts.
  • Display preprocessing and classification progress on stderr, keeping JSON output separate.

WAV classification uses full, uncompressed spectrogram chunks from fast_mode=False. Compressed, masked, and debug images remain available for inspection.

Platform, runtime, and Docker support

  • Support native paths, Unicode filenames, case-insensitive extension discovery, and configurable caches on macOS, Linux, and Windows.
  • Separate CPU and NVIDIA runtime installation through batbot[cpu] and batbot[gpu].
  • Add explicit CPU, CUDA, and Apple CoreML provider selection.
  • Preload matching CUDA/cuDNN libraries and provide actionable initialization/fallback diagnostics.
  • Validate ONNX Runtime session options in normal and reduced-thread modes.
  • Modernize Docker with multi-stage builds, non-root execution, and separate CPU and GPU targets:
    • CPU: Linux amd64 and arm64.
    • NVIDIA GPU: Linux amd64.

Evaluation, notebooks, and collaboration

  • Add a performance plotting example accepting labeled WAV/JPG/JPEG datasets.
  • Preserve genus-level plot ordering across labels, confidence columns, targets, and predictions so shaded regions remain aligned. Inference class ordering is unchanged.
  • Add two notebooks for Codespaces, Google Colab, and local Jupyter:
    • 01_classify_your_files.ipynb: bring-your-own-file classification, charts, and exports.
    • 02_spectrogram_walkthrough.ipynb: waveform/STFT processing, debugging images, model windows, and final predictions.
  • Add a development container and comprehensive contributor, architecture, notebook, and testing guides.
  • Encourage code contributions to BatBot and Kitware BatAI.
  • Direct monitoring data contributions to the USGS NABat program, following its upload guidance. Notebook exports are not NABat submission templates.

Packaging and CI

  • Require Python 3.11+, with CI grids covering Python 3.11–3.14.
  • Consolidate package metadata, dependencies, and tool configuration into pyproject.toml.
  • Add source and wheel installation checks across macOS, Linux, and Windows.
  • Add notebook execution, warning-as-error documentation builds, Docker checks, and an opt-in trusted CUDA hardware job.
  • Configure tagged-release publishing through PyPI Trusted Publishing/OIDC.
  • Retain Black, isort, and Flake8; do not introduce Ruff or mandatory type-checking gates.

Model and inference behavior

  • The package includes batbot.mobilenet.9dc57ea3.onnx through Git LFS and package data.
  • The bundled model and mirrored download are checked against the expected SHA-256 hash.
  • Model downloads use a BatBot-versioned pooch cache.
  • Image preprocessing retains the model's training-time BGR layout and produces overlapping 224 × 224 × 3 windows.
  • Scores from multiple windows and multiple WAV spectrograms are aggregated using window counts as weights.
  • num_workers > 1 runs per-spectrogram ONNX calls concurrently, preserves input order, bounds in-flight work, and reuses one session.
  • Generated WAV spectrograms are temporary by default and can be retained with spectrogram_output or --spectrogram-dir.
  • Bulk processing records failures per input instead of discarding successful results.

CLI and API changes

CLI

Command Input Behavior
batbot classify Existing spectrogram images Classification only
batbot classify-wav WAV files or folders Spectrogram generation followed by classification
batbot classify-bulk Mixed image/WAV inputs Recursive discovery, fault isolation, and summaries
batbot batch WAV files or folders Legacy interface using the integrated classification pipeline
batbot fetch Model configuration Resolve or download the verified ONNX model

Relevant controls include --batch-size, --num-workers, --preprocess-workers, --provider, --no-progress, and --spectrogram-dir, where applicable.

batbot classify spectrogram.jpg --provider cpu
batbot classify-wav recording.wav --output recording.json
batbot classify-bulk ./recordings --input-type wav \
  --preprocess-workers 4 --num-workers 2 --output results.json

Python API

  • Add reusable classifier.Classifier and convenience functions classify, classify_wav, and classify_bulk.
  • Expose lower-level pre, predict, and post functions.
  • Successful results include path, label, confidence, window_count, top, and scores.
  • Bulk responses contain results and summary; failed inputs retain their path and error.
  • species_counts excludes NOISE and counts classified files—not calls or individual bats.
  • Generated spectrograms are temporary by default; callers can explicitly retain them.
  • Preserve top-level spectrogram APIs, including batbot.pipeline.
  • Keep package imports lightweight through lazy loading of computational components.

Performance plotting

examples/plot_classifier_performance.py now accepts a folder hierarchy containing WAV, JPG, or JPEG inputs, including mixed datasets. The immediate parent directory remains the ground-truth label:

validation/
├── EPFU/
│   ├── recording-01.wav
│   └── call-02.jpg
├── MYLU/
│   └── call-03.jpeg
└── NOISE/
    └── background-01.wav

The example supports reusable prediction caches and multi-worker inference. It produces count, true-normalized, and prediction-normalized confusion matrices; top-1/2/3/5 accuracy; Matthews correlation; and NOISE precision-recall, ROC, and operating-point diagnostics when applicable. Species are reordered by genus before plotting so the shaded error regions remain contiguous.

Compatibility notes

  • Python versions below 3.11 are no longer supported.
  • Classification requires a CPU or GPU runtime extra; install only one ONNX Runtime distribution per environment.
  • Docker now starts the BatBot CLI rather than the previous Gradio application.
  • Model scores are not calibrated probabilities or independently verified species observations.

Testing and validation

Audit and strengthen tests around functional behavior, adding 34 new test cases covering numerical transforms, real processing artifacts, all classification CLI routes, corrupt-file isolation, aggregation, and genus-order visualization.

Local validation Python 3.11 Python 3.14
Tests passed 182 182
Existing doctest skipped 1 1
Combined statement/branch coverage 97.2% 97.1%

Coverage increased from 84.0%, without reducing the measured package scope or adding exclusions. The full suite now enforces a 90% minimum.

Formatting, lint, and documentation checks pass. Targeted fault-injection probes confirm that tests detect incorrect batch averaging, BGR/RGB reversal, and omitted genus swaps.

Actual accelerator execution, hosted cloud interactions, and scientific model accuracy remain separate validation requirements; hosted GPU-install checks do not establish CUDA kernel execution.

Changelog

Added

  • ONNX classifier, verified model mirror, reusable inference sessions, and structured results.
  • Image-only, WAV-to-classification, and fault-tolerant bulk workflows.
  • Parallel preprocessing/inference controls and progress indicators.
  • Cross-platform runtime support and CPU/NVIDIA Docker targets.
  • Performance evaluation example, Codespaces configuration, and Colab-compatible notebooks.
  • Contributor documentation referencing BatAI and NABat.
  • Functional regressions, test-audit documentation, and a 90% coverage gate.

Removed

  • Legacy setup.py, setup.cfg, and standalone .flake8 configuration.
  • Duplicated dependency lists under requirements/.
  • Import-time logging initialization and eager scientific-stack loading.
  • The previous Docker application entry point.

Updated

  • Minimum Python version to 3.11 and pytest pin to pytest==8.4.2.
  • Package structure, metadata, dependencies, and documentation tooling.
  • Native path handling, cache configuration, and Unicode image I/O.
  • ONNX Runtime provider initialization and session-option validation.
  • Source/wheel/platform CI, container checks, and release publishing.
  • Existing tests to assert numerical results, metadata consistency, artifact contents, ordering, and cleanup.

Reviewer notes

  • The ONNX model is tracked through Git LFS; reviewers and CI need LFS content available for the real-model tests and distribution build.
  • PyPI must have a trusted publisher matching owner Kitware, repository batbot, workflow python-publish.yaml, and environment pypi before the first tagged release.
  • The default inference worker count remains 1; concurrency is opt-in through num_workers or --num-workers.

@codecov

codecov Bot commented Aug 17, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.11098% with 16 lines in your changes missing coverage. Please review.
✅ Project coverage is 96.6%. Comparing base (6820cc8) to head (b0aee90).
⚠️ Report is 10 commits behind head on main.

Files with missing lines Patch % Lines
batbot/_paths.py 92.0% 3 Missing and 3 partials ⚠️
batbot/api.py 95.6% 2 Missing and 2 partials ⚠️
batbot/batbot_cli.py 97.1% 2 Missing and 1 partial ⚠️
batbot/classifier/dataloader.py 95.3% 1 Missing and 2 partials ⚠️
Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff            @@
##            main     #44      +/-   ##
========================================
+ Coverage   59.2%   96.6%   +37.3%     
========================================
  Files          7      15       +8     
  Lines       1383    2065     +682     
  Branches       0     276     +276     
========================================
+ Hits         820    1995    +1175     
+ Misses       563      32     -531     
- Partials       0      38      +38     
Files with missing lines Coverage Δ
batbot/__init__.py 100.0% <100.0%> (+57.5%) ⬆️
batbot/_config.py 100.0% <100.0%> (ø)
batbot/_version.py 100.0% <100.0%> (ø)
batbot/classifier/__init__.py 100.0% <100.0%> (ø)
batbot/classifier/bulk.py 100.0% <100.0%> (ø)
batbot/classifier/config.py 100.0% <100.0%> (ø)
batbot/classifier/inference.py 100.0% <100.0%> (ø)
batbot/classifier/model.py 100.0% <100.0%> (ø)
batbot/classifier/types.py 100.0% <100.0%> (ø)
batbot/spectrogram/__init__.py 95.2% <100.0%> (+24.9%) ⬆️
... and 5 more

... and 2 files with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a3cdeeb...b0aee90. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@bluemellophone bluemellophone changed the title Adding new ML model inference Add MobileNet ONNX species classification and modernize BatBot Aug 18, 2026
Comment thread batbot/classifier/bulk.py Outdated
@stoutta6

Copy link
Copy Markdown
Collaborator

Looks great to me! Only other features I'd like would be 1) integrating the batch spec preprocessing into the batch ML inference, and 2) visual progress indicators in batch inference.

Also, made a fresh install following these instructions but was unable to get it to use my gpu ("Failed to create CUDAExecutionProvider. Require cuDNN 9.* and CUDA 13.* ..."). Was the install expecting separate, manual install of CUDA and cuDNN? It seems like that shouldn't be necessary (link) - it's also possible something in my setup is different from yours.

@stoutta6 stoutta6 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - see comments

@bluemellophone
bluemellophone merged commit 67896a4 into main Oct 15, 2026
43 checks passed
@bluemellophone
bluemellophone deleted the jrp/ml-model branch October 15, 2026 20:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants