ganesh333's picture
Upload folder using huggingface_hub
001425d verified
|
Raw History Blame Contribute Delete
7.29 kB
---
license: cc-by-4.0
library_name: pytorch
pipeline_tag: audio-classification
datasets:
- InsectSet32
metrics:
- accuracy
- f1
tags:
- audio-classification
- insect
- bioacoustics
- experimental
- local-inference
- litert
- tflite
---
# Kernel Insect Sound Classifier (InsectCNN `full_model`, experimental 0.1.0)
A compact CNN (159k parameters) that classifies **32 sound-producing insect species** (9 Orthoptera, 23 Cicadidae) from audio. It was trained on [InsectSet32](https://zenodo.org/records/7072196).
> **This is not a grain-pest detector.** Do not use it to certify grain as clean or safe, to accept or reject lots, or to trigger treatment. It is a research baseline trained on a small dataset.
## Model details
| | |
|---|---|
| Architecture | `InsectCNN`: 3 conv blocks (16/32/64 ch, BatchNorm, ReLU) + dense head (128) with dropout 0.25 (`src/model.py`) |
| Input | Mono audio → resampled to 16 kHz → 2 s windows, peak-normalised → 64-bin log-mel (n_fft 512, hop 160), per-record standardised (`src/audio.py`) |
| Inference | Softmax averaged over 5 evenly spaced 2 s windows (`eval_crops: 5` in `config.json`) |
| Output | 32 species scores, plus a hierarchical species → genus → group answer |
| Base model | None. Trained from scratch (no pretrained weights, not a fine-tune) |
| Framework | PyTorch & Google LiteRT / TFLite |
### Files
- `model.tflite`: Google LiteRT / TensorFlow Lite on-device model for Android / edge mobile deployment.
- `model.pt`: PyTorch state dict weights. Load it with `torch.load(..., weights_only=True)`.
- `model.h5`: PyTorch state dict in a project-specific HDF5 layout (`kernel-pytorch-state-dict-hdf5-v1`). **It is not a Keras model.** `src.inference.load_model` reads it.
- `config.json`, `labels.json`: architecture, preprocessing settings and class-index → species mapping.
- `metrics.json`, `history.json`: test metrics (with per-class report) and the training curve.
- `src/`, `predict.py`, `export_litert.py`, `test_inference.py`: model definition, audio frontend, exporter and testing scripts.
- `train.py`, `evaluate.py`, `data/*.csv`: reproduction scripts and the official split annotations (the audio itself is not included).
## Usage
This is a custom PyTorch model. It does **not** load with `transformers`, and the hosted inference widget and Inference API don't support it. Run it locally:
```bash
pip install huggingface_hub
python -c "from huggingface_hub import snapshot_download; print(snapshot_download('ganesh333/kernel-insect-classifier', local_dir='kernel-insect-classifier'))"
cd kernel-insect-classifier
pip install -r requirements.txt
python predict.py path/to/recording.wav
```
WAV works out of the box. FLAC, OGG and MP3 need `soundfile`, which `requirements.txt` includes. Inference is fully local; no audio is sent anywhere.
Python API:
```python
from src.inference import predict_wav
r = predict_wav("recording.wav", model_dir=".")
print(r["identification"]) # {'level': 'species'|'genus'|'group'|'unknown', 'name': ..., 'confidence': ...}
print(r["predicted_species"], r["confidence"]) # raw top-1
print(r["top_k"], r["quality_pass"], r["quality_reasons"])
```
**Hierarchical identification.** The model reports the most specific level whose summed probability is at least 0.6: species, then genus, then group (cicadas vs crickets/grasshoppers). Otherwise it reports `unknown`. The threshold was chosen on the validation split.
## Training
Data: InsectSet32. Using the dataset's official `train`/`validation`/`test` partitions, 331 recordings were loaded (206 / 51 / 74).
```bash
# place Cicadidae.csv, Orthoptera.csv, Cicadidae.zip, Orthoptera.zip in data/
python train.py --epochs 60 --random-crop --eval-crops 5 --output .
```
- AdamW (lr 1e-3, weight decay 1e-4), batch size 16, class-weighted cross entropy (weights from train only), seed 42.
- Each epoch trains on a fresh random 2 s window per file.
- The checkpoint is chosen by best validation macro-F1 (0.548). The test split was scored once, after selection.
- About 4 minutes on a CPU.
## Evaluation
Official test split (n = 74 recordings). 95% CIs from a file-level bootstrap:
| Metric | Value |
|---|---|
| Accuracy | 0.486 [0.38, 0.59] |
| Macro-F1 | 0.400 [0.29, 0.47] |
| Weighted-F1 | 0.474 |
| Session-clean accuracy / macro-F1 (n = 48) | 0.458 / 0.343 |
"Session-clean" counts only test files whose source recording session never appears in train or validation. See *Data leakage* below.
Accuracy among test files whose score at that level is at least 0.6:
| Level | Share of test files ≥ 0.6 | Accuracy on those (val / test) |
|---|---|---|
| Species | 43% | 77% / 72% |
| Genus | 77% | 90% / 95% |
| Group | 96% | 98% / 99% |
For comparison, the earlier center-crop baseline of the same architecture scored 0.392 accuracy and 0.329 macro-F1 on the same split. The CIs overlap, so with only 74 test files these differences are not conclusive.
## Limitations
- **Small, imbalanced data.** Species have 4–22 recordings each, and `Roeselianaroeselii` has no test files. All scores are uncertain.
- **Data leakage.** The official split groups by file, not by source recording: 26 of the 74 test files share a source session with train or validation. Official-split scores are therefore optimistic; the session-clean numbers are the more honest estimate.
- **Label noise.** Five `MHV 318 P.capensis` source files are labelled `Platypleuracfcatenata`. They were kept as published.
- **Closed set.** Every input is mapped onto the 32 trained species. Silence, pure tones and white noise can receive high-confidence species predictions. Use `quality_reasons` and treat `genus`/`unknown` answers as exactly that.
- **Noise sensitivity.** Added background noise (SNR 0–20 dB) often changes the prediction.
- **Not calibrated.** The scores are not probabilities of grain infestation. Recording conditions differ from grain sacks and warehouses.
- **Not mobile-ready.** This is not a validated Android LiteRT/TFLite model. See `docs/deployment.md` before any on-device port.
- `model.pt` is a pickle-based file and may be flagged by the Hub's pickle scanner. It contains only tensors. Prefer `model.h5`, or load with `weights_only=True`.
## Dataset attribution and citation
Trained on **InsectSet32** by Marius Faiß, Baudewijn Odé and Ed Baker (CC BY 4.0, [Zenodo 7072196](https://zenodo.org/records/7072196)). Orthoptera recordings: Baudewijn Odé. Cicadidae recordings: the Global Cicada Sound Collection on Bioacoustica ([doi.org/10.1093/database/bav054](https://doi.org/10.1093/database/bav054)). Copyright in individual recordings belongs to the recordists. See `data/README.txt`.
For academic use, please cite the dataset paper: Faiß, M. & Stowell, D. *Adaptive representations of sound for automatic insect recognition*, PLOS Computational Biology (2023), [doi.org/10.1371/journal.pcbi.1011541](https://doi.org/10.1371/journal.pcbi.1011541).
## License
- Model weights and this card: **CC BY 4.0**, matching the training data's license. Keep the attribution above when you redistribute.
- Code (`src/`, `*.py`): **MIT**. See `LICENSE`.