Teaching Machines to Understand Movement: Dog Behavior Classification with IMU Data
Introduction
Dogs communicate constantly, just not in words. A head tilt, a neck shake, a scratch, a drink of water, a sudden sprint toward the door, these often carry more information about health and behavior than a bark does. At Hoomanely, we've long believed the next real step forward in pet health comes from reading these small patterns at scale. That's the thinking behind our neck-band IMU behavior classification system, which reads motion signals and labels what a dog is doing in real time.
This post walks through how we process high-frequency accelerometer and gyroscope data, break it into sliding windows, run it through a CNN plus BiGRU model, and get strong validation accuracy on behaviors like shaking, drinking, walking, running, and scratching. Dogs move unpredictably, which makes this a genuinely hard problem, but solving it opens the door to smarter health monitoring, earlier illness detection, and a better read on everyday routines.
Why dog behavior classification is uniquely hard
Human activity recognition is a mature field. Step tracking, fall detection, cycling classification, sleep estimation, all of that has existed for years. Dogs break most of the assumptions those models rely on.
- Dogs don't move like people. Human movement is structured and periodic. Dog movement is closer to chaos: violent shakes, short sprint bursts, asymmetric scratching, and long stretches of stillness.
- The device orientation keeps changing. A neck-band rotates freely as a dog plays, jumps, or rolls, so the IMU axes rarely stay aligned the same way for more than a few seconds.
- Many behaviors look alike in raw data. Drinking versus licking, scratching versus shaking, walking versus a playful hop; even a person would struggle to tell some of these apart without watching the dog.
- The signals are short and fast. A neck shake lasts 250 to 700 milliseconds, and drinking happens in quick rhythmic bursts, so capturing these micro-behaviors needs a high sample rate.

Data pipeline: from raw IMU streams to training windows
We collect from a nine-axis sensor (accelerometer, gyroscope, magnetometer), though our first version uses six channels (ax, ay, az, gx, gy, gz) sampled at 100 to 120 Hz on the neck-band.
Preprocessing: resample to a consistent rate around 100 Hz, apply a low-pass Butterworth filter with a 20-25 Hz cutoff to strip high-frequency noise, and normalize each axis.
x_norm = (x - mean) / stdSliding window segmentation: 1.5-second windows with a 0.5-second step, giving 66% overlap, so each window becomes a 100 Hz by 150 sample by 6 channel tensor.
Labeling is the slowest part by far. We sync IMU logs with video using timestamp alignment and motion-peak syncing, and annotators tag segments in playback. That gives us labeled data across walking, running, shaking, scratching, drinking, lying down, and eating.

Model architecture: CNN for local patterns, BiGRU for temporal understanding
The idea is straightforward: CNNs pull out short-range motion patterns, and GRU layers learn how those patterns unfold over time.
Architecture: input is 150 samples across 6 channels; 1D CNN layers with kernel sizes of 3 to 5 and increasing filter counts (32, 64, 128) catch local patterns like a scratching spike or a drinking rhythm; a BiGRU layer with 128 units reads both past and future context, which helps separate similar behaviors and catch transitions; dropout at 0.3; then a dense layer with softmax.
IMU Window (150 × 6)
↓
Conv1D → ReLU
↓
Conv1D → ReLU
↓
BiGRU
↓
Dense Layer
↓
Softmax OutputThis combination beat a pure CNN, a pure GRU or LSTM, statistical features paired with XGBoost, and handcrafted frequency features, in that order.

Why CNN plus BiGRU beats the alternatives
Dog motion is messy and operates at several different scales, so a single approach, either pure CNN or pure RNN, misses part of the picture. Combining them gave us our best results.
Why CNNs help: they're good at catching local motion signatures. Scratching produces sharp, high-frequency spikes; drinking produces rhythmic, low-amplitude oscillations; shaking produces dense, explosive bursts of energy. A 1D CNN with small kernels acts like a sliding feature detector, picking up sudden jerks, periodic bursts, frequency shifts, and asymmetry between axes that classical statistical features or an RNN alone would miss.
Why BiGRU adds value on top: once the CNN has extracted local features, the model still needs to understand the full 1.5-second window as a sequence. BiGRU reads forward and backward, which helps it understand transitions like walk to run or sit to lie down, and it smooths out noisy CNN detections by looking at the broader structure. A dog just starting to run can look a lot like a fast walk cycle for a moment, and BiGRU uses the surrounding frames to sort that out.
Why pure CNN falls short: it treats every segment on its own, has no sense of pacing or duration, and gets confused by windows that mix two behaviors.
Why pure GRU or LSTM falls short: without a strong local pattern detector, raw IMU data is too noisy on its own, and these models tend to smooth away short events like a scratch or a shake that only last a fraction of a second.
Why the hybrid fits dog movement specifically: dog behavior plays out at multiple time scales, from 20-80ms micro-patterns like a scratch burst, to 200-800ms meso-patterns like a drinking cycle, to full 1-2 second macro-patterns like a walk or run gait. CNN captures the micro and meso patterns, and BiGRU stitches them into a coherent read on the macro behavior.
How the model performs across behaviors
Exact numbers matter less here than how the model behaves across different dog actions. Overall, the CNN plus BiGRU architecture holds up well across a wide range of dogs, neck-band orientations, and activity intensities.
Some behaviors come through very clearly: shaking has an extremely distinctive, high-energy pattern, scratching produces clear asymmetric bursts, and running has a stable, rhythmic stride. These produce motion signatures the CNN extracts easily and the BiGRU contextualizes well.
Others need more context to get right: walking versus a slow run share similar stride frequencies, eating versus drinking differ only in subtle low-amplitude ways, and posture transitions like sitting into lying down are gradual and less structured. The model handles these reasonably, but the overlap in motion characteristics makes them inherently harder.
Overall, the system gives dependable behavior classification for real-world use, and it works best as one part of a multi-sensor pipeline. Adding audio, proximity, and weight data in future iterations should push accuracy further.
Lessons learned
- IMU orientation drift is a real headache. Axis rotation breaks assumptions built around a fixed axis. Augmentation and normalization help, but a future version may need attitude estimation, a quaternion-based representation, or gravity-compensated signals.
- Some behaviors need more than IMU. Telling eating apart from drinking often needs bowl-level audio, proximity data, or a weight change, since IMU alone can't always make the call.
- Window size matters. One to two seconds works best. Shorter loses context, longer starts mixing behaviors together.
- Behavior boundaries are fuzzy. Dogs don't switch into walking the way a person starts a stopwatch; the transition is gradual, and that naturally makes labels noisier.
- The model benefits from per-dog tuning. Just as human gait varies with height and build, dog motion varies with breed, age, neck girth, coat, and temperament. A lightweight on-device personalization layer is next on our list.