phase_conditioning¶
Which frames the bar-position terms are supervised on.
Both frame-wise position losses here — beat_phase_loss()
and beat_position_loss() — average their
position term over a weighted subset of frames rather than all of them. This
module holds that weight, so the two losses share one definition and one
explanation of why the choice matters.
Functions
|
Per-frame weight for a bar-position loss term. |
- phase_weight(beat_y, mask, phase_conditioning, tolerance_frames=0)[source]¶
Per-frame weight for a bar-position loss term.
\[\begin{split}w_{i,t} = \begin{cases} m_{i,t} & \text{phase\_conditioning} = \text{"mask"} \\ m_{i,t} \, \max_{|s| \le r} b_{i,t+s} & \text{phase\_conditioning} = \text{"beat"} \end{cases}\end{split}\]The
maskfactor is always present: not every dataset carries position annotations (seemusicality.loaders.beat_dataset.BeatDataset), so unannotated clips must contribute nothing."mask"optimises the position heads on a distribution they are never read at —musicality.postprocess.label_bar_position()samples them only at detected beat times, so ~96% of the gradient goes into re-learning “is this a beat at all”, which the beat head already does at 0.92 F."beat"restricts the term to the frames the decoder actually reads, turning 1-vs-3 from a rare-event detection problem (~1 positive frame in 23) into a balanced classification problem (~1 beat in 4). Seedocs/beat_phase_improvement_review.mdstep 2.Note
A hand-set
pos_weighton the position heads must be retuned alongside this — the imbalance it compensates for largely disappears. Measured neg:pos mass on ballroom is ~20:1 under"mask"but ~4.7:1 under"beat"(not 3:1 — the positive mass is a product of the smeared beat weight and the smeared position target, so it decays faster than the weight alone). The beat-phase task was calibrated at18and4respectively.tolerance_framespushes back the other way: widening the window raises the positive mass again.- Parameters:
beat_y (Tensor) – Beat target channel, shape
(B, T). Under the defaultsigma_frames: 1.5it is Gaussian-smeared (peak 1.0 at a beat, exactly 0 more than 4 frames away —gaussian_smeartruncates its kernel atround(3 * sigma)), so it doubles as a soft “near a beat” weight with no threshold or window size to invent. Under sharp targets it is a single frame per beat, andtolerance_framessupplies the window the smear used to.mask (Tensor) – Target’s mask channel, shape
(B, T)— 1 where the clip carries bar-position annotations, 0 where it does not.phase_conditioning (str) –
"mask"or"beat".tolerance_frames (int) –
Half-width, in frames, of the window the
"beat"gate is widened over — seesliding_windowed_max().0(the default) leaves the gate exactly as the target came.This exists because the decoder does not read the position head at the annotated frame; it reads it at the frame the beat head’s peak rounded to, which shift tolerance explicitly allows to sit up to
rframes away (musicality.postprocess.label_bar_position_global()). The head therefore has to be right across that whole window, so the term is supervised across it.Warning
Whatever widens this must widen the position target too.
BeatDatasetgives frames away from a beat a uniform row, meaning “no information here”, so widening the gate alone would train the head towards maximum uncertainty at precisely the frames the decoder reads.beat_position_loss()does both together; nothing else should call this with a non-zero radius.
- Returns:
Weight tensor, shape
(B, T).- Raises:
ValueError – If
phase_conditioningis not a known mode.- Return type:
Tensor