Rat detection system for NYC apartments. Uses a MobileNetV2 binary classifier trained with PyTorch and deployed on Raspberry Pi via ONNX Runtime. When a rat is detected on camera, sends a push notification via ntfy.sh.
- Download rat images and background images from iNaturalist
- Train a MobileNetV2 model with two-phase transfer learning (frozen backbone → full fine-tuning)
- Export to ONNX with INT8 quantization for efficient inference
- Deploy on a Raspberry Pi running a camera loop as a systemd service
Requires Python 3.10+ and uv.
# For training (GPU/desktop)
uv sync --extra train
# For Raspberry Pi deployment
uv sync --extra piuv run python scripts/download_data.pyFetches rat images (Rattus norvegicus) and background images from iNaturalist, organized into data/train/ and data/val/ with rat/ and no_rat/ subdirectories.
uv run rat-train --data-dir data --epochs 30Training uses a two-phase schedule:
- Phase 1 (epochs 0–4): backbone frozen, only the classifier head trains
- Phase 2 (epochs 5+): full model fine-tuning with differential learning rates
The best checkpoint is saved to models/best_model.pt with metadata.
uv run rat-export --checkpoint models/best_model.pt --output models/Exports the model to ONNX format and applies dynamic INT8 quantization, producing rat_detector_int8.onnx for Pi deployment.
# With display (desktop)
uv run rat-infer --model models/rat_detector_int8.onnx --camera 0
# Headless (Pi)
uv run rat-infer --model models/rat_detector_int8.onnx --no-display --save-detections --threshold 0.7# On the Pi
bash scripts/deploy.shInstalls dependencies, sets up a systemd service that auto-starts the camera loop on boot, and restarts on failure.
Pass --notify-topic <your-topic> to rat-infer to receive push notifications via ntfy.sh when a rat is detected. Notifications are throttled to one per minute by default.
uv run --extra train pytest tests/src/rat_vision/
├── config.py # TrainConfig / InferenceConfig dataclasses
├── model.py # MobileNetV2 with custom classifier head
├── dataset.py # Transforms and DataLoader creation
├── train.py # Two-phase training loop with early stopping
├── export.py # ONNX export + INT8 quantization
├── inference.py # Real-time ONNX camera inference
└── notify.py # ntfy.sh push notifications
scripts/
├── download_data.py # Fetch images from iNaturalist
├── train.sh # Train + export wrapper
├── deploy.sh # Pi setup script
└── rat-vision.service # systemd unit file