pyFDN.MatchCumulativeEnergy#
- class pyFDN.MatchCumulativeEnergy(target, *, window=1024, hop=None, power=0.5, floor_db=-100.0, frequency='descending')[source]#
Doubly-cumulated energy against a reference – decay and colour, no bands.
Takes the short-time power spectrum of both signals and integrates it twice, backwards in time and downwards in frequency:
\[E[f, t] = \sum_{t' \ge t} \; \sum_{f' \ge f} \big| S[f', t'] \big|^2\]so \(E[f, t]\) is the energy still to come after time \(t\) in the band above \(f\), and \(E[0, 0]\) is the total energy. The loss is the RMS difference of the two surfaces after a compressive power.
Cumulating twice carries both things a fit needs: read down the \(t = 0\) edge and you have the integrated spectrum (the colour), read across the \(f = 0\) edge and you have the full-band decay, and the interior ties them together band by band – without the arbitrary quantization of octave bands. The compressive
power(rather than a logarithm) keeps the surface’s six-orders-of-magnitude dynamic range visible to the loss while staying bounded. See the design note for the reasoning behind the defaults.- Parameters:
target (
Any) – Reference IR, shape(n_samples,),(n_samples, n_out)or(n_samples, n_out, n_in). Zero-padded or truncated to the model’snfft.window (
int) – STFT window and hop in samples. UnlikeMatchEnergyDecaythis loss needs no window long enough to resolve an octave – it never splits into octaves – so the default is short.hop (
int|None) – STFT window and hop in samples. UnlikeMatchEnergyDecaythis loss needs no window long enough to resolve an octave – it never splits into octaves – so the default is short.power (
float) – The compression exponent \(p \in (0, 1]\) applied to the normalized surface. 1 is no compression (raw energies), 0.5 the default, 0.25 stronger.floor_db (
float) – Hard floor on the normalized surface, in energy dB below the reference’s total energy. It bounds the gradient of the compression near zero and keeps the fit off the numerical floor of the render;clampmeans no gradient flows from anything below it.frequency (
str) – Which way the frequency cumulation runs, and with it the loss’s balance between the ends of the spectrum. The default"descending"(the plain reading of “energy above this frequency”) gives a low band little gradient;"both"scores both directions and averages, and is what to reach for when the fit has to find a decay it was not given. See the design note for the comparison.
Notes
The surface is normalized by the reference’s total energy, one constant – not each surface by its own – so a level error is a genuine error of the loss rather than something it is blind to. Fitting shape only, with the level left to another term, is the one thing this loss deliberately does not do.
- __init__(target, *, window=1024, hop=None, power=0.5, floor_db=-100.0, frequency='descending')[source]#
Methods
__init__(target, *[, window, hop, power, ...])check(model)Preflight against the model it will train, before the first step.
terms()Flatten into
(weight, loss)leaves.Attributes
nameShort label, used as the key in
pyFDN.TrainLog.loss_log.