fix(behavior): stop refusing a cohort over frame-rate jitter - #102
Merged
Conversation
`resolve_sessions_fps` grouped recorded rates by rounding to three decimal places and refused to train if more than one group survived. Container timestamps do not cooperate with that: thirty sidecars written off one camera in one session read 29.979620, 30.000000 and 30.000727. That is a 0.07% spread -- 0.19 ms across an eight-frame window -- and it made a perfectly uniform cohort untrainable. The guard is worth keeping; it exists so one rolling window cannot mean two durations in the same model. But the differences it is for are 25 vs 30 and 30 vs 60, which are 20% and 100% apart. Group rates within 2% instead, so encoder wobble and the 29.97/30.0 naming convention collapse to one rate while a genuine mismatch still fails loudly. The resolved rate is the mean of the group, within tolerance of every member by construction. The error also advised passing `fps=` to force a rate, which the Train tab had no way to do -- `_shared_options` never sent one and no widget offered it. Add a frame-rate spin box defaulting to "auto (from pose CSVs)", so the advice names something reachable and a genuinely mixed cohort can still be trained deliberately. Found on a 34-session cohort that trained fine from a folder with no sidecars and failed the moment it moved to one that had them.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
resolve_sessions_fpsgrouped recorded frame rates by rounding to threedecimal places, then refused to train if more than one group survived.
Container timestamps don't cooperate with that. Thirty sidecars written off one
camera in a single session read:
Over an 8-frame window that is 0.19 ms. It made a perfectly uniform cohort
untrainable, with an error listing 30 files as though they'd been recorded
differently.
The guard itself is worth keeping — it exists so one rolling window cannot mean
two durations inside a model. But the differences it's for are 25 vs 30 (20%)
and 30 vs 60 (100%). This groups rates within 2%, so encoder wobble and the
29.97/30.0 naming convention collapse into one rate while a genuine mismatch
still fails loudly. The resolved rate is the group mean, within tolerance of
every member by construction.
The advice you couldn't take
The error said to "pass
fps=to force one rate" — but_shared_options()never sent
fpsand no widget offered it, so from the GUI that was a dead end.Adds a Frame rate spin box defaulting to
auto (from pose CSVs), with 0shown as the special "auto" value so a literal 0 fps can't reach the pipeline.
Verified against the real cohort
34 sessions whose sidecars carry the spread above:
ValueError: these sessions were recorded at different frame rates (29.98 fps: …; 30.0 fps: …; 30.001 fps: …)Found because the cohort trained fine from a folder with no sidecars — falling
back to
DEFAULT_FPS— and broke the moment it moved to a folder that hadthem. Recording more metadata made it fail.
Tests
is covered in both directions
fps=None, a set value reaches the pipeline, 0 rendersas "auto", and all three entry points accept
fps2803 passed, 1 skipped; ruff and black clean.