Skip to content

feat(behavior): image-embedding lane for the behaviour classifier - #245

Open
gbradham wants to merge 1 commit into
mainfrom
claude/image-embedding-classifier-680163
Open

gbradham wants to merge 1 commit into
mainfrom
claude/image-embedding-classifier-680163

Conversation

@gbradham

@gbradham gbradham commented Nov 5, 2026

Copy link
Copy Markdown
Member

What

An optional image lane for the behaviour classifier, beside the keypoint features. Keypoints can't tell a rear from a hunched sit, and grooming forepaws aren't tracked, so the lane adds what the camera sees around the animal.

Per frame:

  1. Crop: a causal square around the body centre, scaled to body length.
  2. Mask: YOLO segmentation (mouse_seg.pt).
  3. Encode: 19 mask-shape descriptors, masked DINOv2 ViT-S/14 (CLS + mean patch token) and the mmv2.pt layer-19 neck pooled in the mask.
  4. Reduce and window: PCA fitted on training sessions only (stored in the model bundle), then a past-only window (value, mean, std, diff).

Steps 1–3 are cached per session, like the motion lane. One window function serves training, offline scoring and live, so they can't drift apart.

Changes

  • New analysis/behavior/image_lane.py and tests/unit/analysis/behavior/test_image_lane.py.
  • Wired into training, CV, batch scoring and the live pipeline (image_lane=True). img_* columns are NaN-tolerant: a missed mask still leaves the keypoint features.
  • Live display draws its overlay on a copy of the frame; before, downstream stages reading pixels saw the overlay.

Results (reproducing the research pipeline)

  • PyMouse leave-one-mouse-out: 0.776 centred / 0.768 live (research 0.778 / 0.768).
  • Blast leave-one-session-out: 0.834 → 0.842 with the lane (research 0.829 → 0.847).

Limits

  • Live use needs a CUDA GPU (47–76 ms/frame on CPU).
  • Models are looked up in ~/.glider/models/image_lane or $GLIDER_IMAGE_LANE_MODELS; they aren't bundled.
  • A live lane model must be keypoints (+freq) + lane; motion/trajectory features can't run live.

Testing

ruff, black --check clean; pytest tests/unit/analysis/behavior tests/unit/gui/behavior: 1879 passed, 2 skipped (Python 3.12, local). Not yet run in the GUI against live video.

Adds an optional image lane beside the keypoint features: a causal crop
around the animal, a YOLO segmentation mask, mask-shape descriptors, masked
DINOv2 ViT-S/14 and the mmv2 pose-model neck, reduced by a PCA fitted on the
training sessions only and windowed past-only (value, mean, std, diff).

- image_lane.py: config, crop tracker, encoder, per-session raw cache,
  PCA artifact stored in the model bundle, one window function shared by
  training, offline scoring and the live stream.
- Wired into training, cross-validation, batch scoring and the live
  pipeline (image_lane=True); lane columns are NaN-tolerant, so a missed
  mask leaves the keypoint features usable.
- Live display now draws its overlay on a copy of the frame, so stages
  that read pixels downstream no longer see it.

Reproduces the research pipeline: PyMouse leave-one-mouse-out 0.776
centred / 0.768 live (research 0.778 / 0.768); Blast leave-one-session-out
0.834 -> 0.842 with the lane.

This branch has not been deployed

No deployments
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.

1 participant