Audio Classification
PyTorch
LiteRT
LiteRT
kernel-insect-cnn
insect
bioacoustics
experimental
local-inference
Instructions to use ganesh333/kernel-insect-classifier with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- LiteRT
How to use ganesh333/kernel-insect-classifier with LiteRT:
# No code snippets available yet for this library. # To use this model, check the repository files and the library's documentation. # Want to help? PRs adding snippets are welcome at: # https://github.com/huggingface/huggingface.js
- Notebooks
- Google Colab
- Kaggle
File size: 3,768 Bytes
575e16b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | """Load and run the packaged model locally. No network calls are made."""
import json, h5py, numpy as np, torch
from pathlib import Path
from .model import InsectCNN
from .audio import logmel, audio_quality, resample, crop_offsets, read_audio, SR
# Labels are 'GenusSpecies' with no separator; longest prefix first so Pseudochorthippus != Chorthippus.
ORTHOPTERA=['Pseudochorthippus','Chorthippus','Gryllus','Nemobius','Oecanthus','Pholidoptera','Roeseliana','Tettigonia']
CICADIDAE=['Azanicada','Brevisiana','Kikihia','Myopsalta','Platypleura','Pycna']
# Chosen on the validation split for full_model (species ~77%, genus ~90%, group ~98% correct above it).
DEFAULT_THRESHOLD=0.6
def genus_of(species):
return next((g for g in ORTHOPTERA+CICADIDAE if species.startswith(g)),species)
def group_of(species):
return 'Orthoptera (crickets/grasshoppers)' if genus_of(species) in ORTHOPTERA else 'Cicadidae (cicadas)'
def _summed(probs, labels, keyf):
out={}
for i,p in enumerate(probs): k=keyf(labels[str(i)]); out[k]=out.get(k,0.)+float(p)
return sorted(out.items(),key=lambda kv:-kv[1])
def identify(probs, labels, threshold=DEFAULT_THRESHOLD):
"""Most specific taxonomic level whose summed probability reaches the threshold, else 'unknown'."""
top=int(np.argmax(probs))
levels=[('species',[(labels[str(top)],float(probs[top]))]),
('genus',_summed(probs,labels,genus_of)),('group',_summed(probs,labels,group_of))]
for level,ranked in levels:
if ranked[0][1]>=threshold: return {'level':level,'name':ranked[0][0],'confidence':ranked[0][1]}
return {'level':'unknown','name':'Uncertain - possibly a species outside the 32 trained classes','confidence':levels[-1][1][0][1]}
def load_model(model_dir, device='cpu'):
model_dir=Path(model_dir)
cfg=json.loads((model_dir/'config.json').read_text())
labels=json.loads((model_dir/'labels.json').read_text())
net=InsectCNN(cfg['num_classes'])
h5_path=model_dir/'model.h5'
with h5py.File(h5_path,'r') as h:
state={}
for key in h['state_dict']:
arr=np.asarray(h['state_dict'][key])
state[key]=torch.from_numpy(arr.copy())
net.load_state_dict(state)
net.to(device).eval()
return net, labels, cfg
def predict_wav(path, model_dir, device='cpu'):
net,labels,cfg=load_model(model_dir,device)
# Integer PCM is scaled to [-1,1] before mixing to mono so the quality check sees true levels.
sr,y=read_audio(path)
ok,reasons=audio_quality(y)
# eval_crops>1 averages over evenly spaced 2 s windows; older bundles use the center crop.
y16=resample(y,sr)
offs=crop_offsets(len(y16),int(cfg.get('eval_crops',1)))
x=torch.from_numpy(np.stack([logmel(y16,SR,o) for o in offs])).to(device)
with torch.no_grad():
probs=torch.softmax(net(x),dim=1).mean(dim=0).cpu().numpy()
order=np.argsort(probs)[::-1][:5]
thr=float(cfg.get('confidence_threshold',DEFAULT_THRESHOLD))
return {'identification':identify(probs,labels,thr),
'genus_scores':[{'genus':g,'score':v} for g,v in _summed(probs,labels,genus_of)[:3]],
'group_scores':[{'group':g,'score':v} for g,v in _summed(probs,labels,group_of)],
'predicted_species':labels[str(int(order[0]))],
'confidence':float(probs[order[0]]),
'top_k':[{'species':labels[str(int(i))],'score':float(probs[i])} for i in order],
'quality_pass':bool(ok),'quality_reasons':reasons,
'model_version':cfg['model_version'],
'experimental':True,
'warning':'Research insect-species classifier only. Not trained for grain-pest detection or grain safety.'}
|