NanoDetector

A YOLOv5m animal detector and 25-class species classifier for North American camera-trap imagery, built to run on a Jetson Nano in a battery-powered field enclosure.

NanoDetector is one half of a system for monitoring wildlife where there is no power and no network. The other half is a device: an Arduino-scheduled, satellite-connected trail-camera unit that wakes on a timer, classifies imagery on-device, and transmits the conclusions over Iridium instead of the photographs. A season of imagery collapses from tens of gigabytes to a stream of small structured messages.

πŸ”§ Code, device, docs github.com/sheneman/NanoDetector
🌐 Project site nanodetector.ai
🦌 Parent project WHISL β€” Wildlife & Humans in Shared Landscapes
πŸ’΅ Funding NSF Award #2317537

Quick start

NanoDetector is a standard YOLOv5 checkpoint trained on stock, unmodified Ultralytics YOLOv5 β€” no fork or patch is needed.

import torch
from huggingface_hub import hf_hub_download

weights = hf_hub_download("sheneman/NanoDetector", "NanoDetector_YOLOv5m_v1.pt")
model = torch.hub.load("ultralytics/yolov5", "custom", path=weights)
model.conf = 0.75   # threshold used in field deployment

results = model("camera_trap_image.jpg")
results.print()
print(results.pandas().xyxy[0])   # xmin ymin xmax ymax confidence class name

Or with the YOLOv5 CLI:

git clone https://github.com/ultralytics/yolov5.git && cd yolov5
pip install -r requirements.txt
python detect.py --weights NanoDetector_YOLOv5m_v1.pt --source ./images --conf-thres 0.75

Field deployments use --conf-thres 0.75, far above YOLOv5's 0.25 default: species labels feed a satellite summary, so precision matters more than recall. MegaDetector, not this model, is responsible for not missing animals.


Model details

File NanoDetector_YOLOv5m_v1.pt (169 MB)
sha256 397cd7d62fb38116cea7575bed3a7270b6c8301e434834f792e0bb7eb4081d4c
Architecture YOLOv5m β€” 290 layers, 20,949,918 parameters
Input RGB, 640 Γ— 640
Classes 25
Framework PyTorch / Ultralytics YOLOv5 @ c23a441
Version v1 β€” best.pt snapshot at epoch 438 of a 500-epoch run
Developed by Luke Sheneman, Research Computing and Data Services, University of Idaho
License MIT

Training data

1,391,742 labelled images merged from five public camera-trap corpora distributed by LILA BC β€” IDFG, IDFG2, North American Camera Trap Images, WCS, and Caltech Camera Traps β€” harmonised into a single 25-class taxonomy (mapping table).

Split Images
train 1,177,647
val 67,449
test 146,646

The corpus is heavily imbalanced β€” cattle, elk and deer dominate, while badger has 29 instances in the entire test split.

Training: 500 epochs at 640Γ—640, batch 200, SGD, hyp.scratch-low, 2 GPUs via DDP on the University of Idaho RCDS cluster. Full recipe, exact command, and archived opt.yaml/hyp.yaml: docs/training.md.

Classes

idx class idx class idx class
0 human 9 lagomorph 18 badger
1 coyote 10 bobcat 19 unknown cervid ⚠️
2 fox 11 pronghorn ⚠️ 20 rabbit
3 mountain lion 12 bighorn sheep ⚠️ 21 horse
4 elk 13 unknown ungulate ⚠️ 22 unknown cat
5 deer 14 vehicle 23 turkey
6 unknown canid ⚠️ 15 wolf 24 domestic sheep
7 domestic dog 16 moose
8 bear 17 cattle

⚠️ unvalidated β€” no instances (or a single instance) in the held-out splits. Predictions for these classes are unsupported by evidence.

Evaluation

Stock YOLOv5 val.py at 640Γ—640 against this checkpoint.

Split Images Labels P R mAP@0.5 mAP@0.5:0.95
val 67,449 89,912 0.947 0.930 0.968 0.902
test 146,646 193,326 0.849 0.835 0.872 0.809

Read the test number carefully. YOLOv5's all row is an unweighted mean over classes. The test split contains exactly one instance each of unknown canid and unknown cervid; both score 0, and two zeros in a 22-class mean cost ~9 points of mAP by themselves. Excluding those two degenerate classes, test mAP@0.5 is 0.959 β€” consistent with validation. The model does not degrade on test.

Selected per-class test results (full tables: docs/evaluation.md):

Class Labels P R mAP@0.5
deer 29,495 0.968 0.963 0.989
elk 45,625 0.941 0.963 0.987
cattle 85,800 0.916 0.949 0.976
mountain lion 2,465 0.950 0.965 0.989
bear 3,024 0.943 0.935 0.982
wolf 631 0.941 0.946 0.979
coyote 4,175 0.936 0.950 0.962
moose 3,617 0.936 0.770 0.870
turkey 9,025 0.807 0.925 0.948
human 199 0.908 0.693 0.869

Speed: 4.0 ms/image inference, batch 32, datacenter GPU. Jetson Nano is substantially slower.

Intended use

In scope

  • Species-level classification of North American camera-trap imagery
  • Edge/offline inference where uploading imagery is impractical
  • Second-stage classifier behind a class-agnostic detector such as MegaDetector
  • Triage and retrieval across large existing camera-trap archives

Out of scope

  • Person detection β€” see limitations below
  • Regions outside western North America
  • Species not among the 25 classes (they will be forced into the nearest class, not rejected)
  • Individual identification, age, sex, health, or behaviour
  • Legal, enforcement, or regulatory determinations without human review

Limitations

  1. Human recall is poor (0.69 test / 0.72 val). The model misses roughly three people in ten. Only 199 human instances exist across the 193,326-label test split β€” humans are ~0.1% of a corpus drawn from wildlife surveys. Do not use this model to detect people, and do not use it as a privacy filter. The deployed device relies on MegaDetector for the person class precisely for this reason.
  2. Moose are undercounted β€” recall 0.77 at precision 0.94, consistently across both splits.
  3. Four to five classes are unvalidated (⚠️ above): no held-out evidence exists for them.
  4. Turkey over-predicts on test data (precision 0.807 vs 0.954 on validation).
  5. Sparse-class metrics are fragile β€” badger rests on 29 test instances.
  6. Geographic scope β€” trained on western North American imagery; assume poor performance elsewhere.
  7. Split independence is unverified. Camera-trap imagery is highly autocorrelated (bursts, fixed backgrounds). If splits were assigned per-image rather than per-camera-station, these metrics overstate accuracy at a genuinely new site. The split procedure is not recorded in surviving artifacts.
  8. No open-set rejection β€” every detection is assigned one of 25 classes; novel species are misclassified rather than flagged.
  9. Night/IR imagery was not separately evaluated, though it is common in camera-trap data.

Ethical considerations

Human imagery. Camera traps photograph people. This model has a human class, but its human recall is low, so it must not be used to find and redact people β€” roughly three in ten will get through. Use a purpose-built person detector, and handle imagery under an appropriate human-subjects and retention policy.

Sensitive species. Near-real-time, georeferenced locations for wolves, mountain lions and bear can enable poaching or inflame conflict. Treat detection streams with the same care as any sensitive wildlife location data; aggregate or delay before public release.

Management decisions. Errors concentrate in rare classes, which are often the classes of greatest conservation concern. Model counts should inform human judgement, not replace it. Decisions with legal or livelihood consequences need human verification of the underlying imagery.

How it's used in the field

The device runs two models in sequence. MegaDetector v5 finds that something is there (animal/person/vehicle) with high recall; NanoDetector says what it is. Outputs are fused by IoU so MegaDetector stays canonical for localisation and for person/vehicle calls while NanoDetector supplies species identity. Detections within a 30-second burst are then normalised by majority vote β€” never across the human or vehicle classes.

Architecture, firmware, and the fusion pipeline: github.com/sheneman/NanoDetector.

Citation

@software{sheneman_nanodetector,
  author  = {Sheneman, Luke},
  title   = {NanoDetector: An edge AI device and species classifier
             for satellite-connected wildlife monitoring},
  url     = {https://github.com/sheneman/NanoDetector},
  note    = {Model weights: https://huggingface.co/sheneman/NanoDetector},
  institution = {University of Idaho}
}

Acknowledgments

Supported by the National Science Foundation under Award #2317537 and by Research Computing and Data Services at the University of Idaho. Built on Ultralytics YOLOv5 and MegaDetector. Training imagery from LILA BC.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Evaluation results

  • mAP@0.5 (validation) on NanoDetector merged camera-trap corpus (IDFG, NorthAmerica, WCS, Caltech)
    self-reported
    0.968
  • mAP@0.5:0.95 (validation) on NanoDetector merged camera-trap corpus (IDFG, NorthAmerica, WCS, Caltech)
    self-reported
    0.902
  • Precision (validation) on NanoDetector merged camera-trap corpus (IDFG, NorthAmerica, WCS, Caltech)
    self-reported
    0.947
  • Recall (validation) on NanoDetector merged camera-trap corpus (IDFG, NorthAmerica, WCS, Caltech)
    self-reported
    0.930