deepSTRF.metrics package
Submodules
deepSTRF.metrics.losses module
Loss functions for deepSTRF: gradient-bearing, NaN-aware, reduction over neurons.
See docs/_source/md/metrics_paradigm.md for shape conventions, NaN handling,
and reduction semantics.
- deepSTRF.metrics.losses.mse_loss(pred: Tensor, gt: Tensor, mask: Tensor | None = None, reduction: str = 'mean') Tensor[source]
Boolean-masked mean squared error, reduced over the neuron axis.
- Parameters:
pred (
torch.Tensor) – Prediction tensor of shape(B, N, 1, T).gt (
torch.Tensor) – Ground-truth tensor of shape(B, N, 1, T)(PSTH or single-trial target) or(B, N, R, T)withR > 1(raw responses), in which case it is collapsed to PSTH viananmean(dim=2, keepdim=True)before the loss is computed.gtmay contain NaN; positions where the resulting PSTH is NaN are dropped from the per-neuron mean.mask (
torch.Tensor, optional) – Bool tensor broadcastable to the post-collapsegtshape(B, N, 1, T). If None, defaults to~gt.isnan(). If provided, REPLACES (does not augment) the NaN-derived mask.reduction (
{'none', 'mean', 'sum'}, default'mean') – Reduction over the neuron axis.'none'returns the per-neuron vector;'mean'/'sum'reduce it via nanmean / nansum.
- Returns:
Shape
(N,)ifreduction='none', otherwise a scalar.- Return type:
torch.Tensor
- deepSTRF.metrics.losses.poisson_loss(pred: Tensor, gt: Tensor, mask: Tensor | None = None, reduction: str = 'mean', log_input: bool = False, validate_input: bool = False, eps: float = 1e-08) Tensor[source]
Negative Poisson log-likelihood (without the
log(gt!)constant).- Parameters:
pred (
torch.Tensor) – Prediction of shape(B, N, 1, T). Interpreted as the rateλwhenlog_input=Falseand as the log-rateη = log(λ)whenlog_input=True(see Notes).gt (
torch.Tensor) – Ground-truth target. A pre-computed PSTH(B, N, 1, T)or a raw responses tensor(B, N, R, T)withR > 1; in the latter case it is collapsed to PSTH viananmean(dim=2, keepdim=True)first. May contain NaN.mask (
torch.Tensor, optional) – Bool tensor broadcastable to(B, N, 1, T). If None, defaults to~gt.isnan(). If provided, REPLACES (does not augment) the NaN-derived mask.reduction (
{'none', 'mean', 'sum'}, default'mean') – Reduction over the neuron axis ('none'keeps the(N,)vector).log_input (
bool, defaultFalse) – Selects the prediction parameterisation (see Notes).validate_input (
bool, defaultFalse) – Whenlog_input=False, raise on negativepredat masked-in positions instead of silently clamping inside the log. Costs a per-step CPU sync.eps (
float, default1e-8) – Floor applied topredinside the log whenlog_input=False.
- Returns:
Shape
(N,)ifreduction='none', otherwise a scalar.- Return type:
torch.Tensor
Notes
Two parameterisations of the prediction are supported, matching the canonical-link logic of generalised linear models:
log_input=False(default): the loss ispred − gt · log(pred + eps)per element.predmust be non-negative for the log to be meaningful; the implementation silently clampspredto≥ epsinside thelogto avoid NaN propagation (the linear term keeps its sign). Passvalidate_input=Truefor a loud failure on negative predictions.log_input=True: the loss becomesexp(pred) − gt · pred, which is well-defined for any real-valuedpred. This is the standard trick for pairing a Poisson NLL with an unbounded readout (Linear, sign-permitting ParametricSigmoid, etc.). Seemetrics_paradigm.md§6.2 for the GLM-canonical-link derivation.
The
log(gt!)Stirling term is not added — for non-integergt(e.g. trial-averaged PSTH binned counts) it is meaningless, and for integergtit is constant inpredso it does not affect optimisation. Users who want the full likelihood for AIC/BIC can add it themselves.
deepSTRF.metrics.performance module
Performance metrics for deepSTRF: NaN-aware, eval-only, reduction over neurons.
See docs/_source/md/metrics_paradigm.md for the design rationale, shape
conventions, NaN handling, and per-metric formulas.
- deepSTRF.metrics.performance.coherence(pred: Tensor, gt: Tensor, dt_ms: float, reduction: str = 'mean') Tensor[source]
Magnitude-squared coherence per neuron (mean over frequency bins).
Eval-only: uses
scipy.signal.coherence, no gradient.- Parameters:
pred (
torch.Tensor) – Prediction of shape(B, N, 1, T).gt (
torch.Tensor) – Ground-truth PSTH of shape(B, N, 1, T).dt_ms (
float) – Time-bin width in milliseconds; sets the sampling ratefs = 1 / (dt_ms · 1e-3)passed toscipy.signal.coherence.reduction (
{'none', 'mean', 'sum'}, default'mean') – Reduction over the neuron axis.
- Returns:
Shape
(N,)ifreduction='none', otherwise a scalar.- Return type:
torch.Tensor- Raises:
ValueError – If any element of
predorgtis NaN (this metric does not tolerate NaN; pre-flatten to a NaN-free subset first).
- deepSTRF.metrics.performance.compute_CCmax(responses: Tensor, max_iters: int = 126) Tensor[source]
CCmax (Hsu / Spearman-Brown) per
(B,)cell.Internal helper kept importable for the audio loaders (legacy CCmax / TTRC pipeline). Prefer
compute_neuron_quality()on the dataset itself.- Parameters:
responses (
torch.Tensor) – Responses of shape(B, R, T). NaN marks invalid repeats / time bins (dropped per(b,)).max_iters (
int, default126) – Cap on random half-splits per cell.
- Returns:
Shape
(B,).1.0for cells withR = 1; NaN for cells withρ_half ≤ 0.- Return type:
torch.Tensor
- deepSTRF.metrics.performance.compute_TTRC(responses: Tensor) Tensor[source]
Trial-to-trial response correlation per
(B,)cell.Internal helper kept importable for the audio loaders (legacy CCmax / TTRC pipeline). Prefer
compute_neuron_quality()on the dataset itself.- Parameters:
responses (
torch.Tensor) – Responses of shape(B, R, T). NaN-aware.- Returns:
Shape
(B,).1.0for cells withR = 1; NaN for cells with no valid trial pair.- Return type:
torch.Tensor
- deepSTRF.metrics.performance.corrcoef(pred: Tensor, gt: Tensor, mask: Tensor | None = None, reduction: str = 'mean') Tensor[source]
Pearson correlation per neuron over flattened valid (B, T) positions.
See
metrics_paradigm.md§6.3.- Parameters:
pred (
torch.Tensor) – Prediction of shape(B, N, 1, T).gt (
torch.Tensor) – Pre-computed PSTH(B, N, 1, T)or raw responses(B, N, R, T)withR > 1(collapsed to PSTH viananmean(dim=2, keepdim=True)first). May contain NaN.mask (
torch.Tensor, optional) – Bool tensor broadcastable to(B, N, 1, T). If None, defaults to~gt.isnan(); if provided, REPLACES the NaN-derived mask.reduction (
{'none', 'mean', 'sum'}, default'mean') – Reduction over the neuron axis.
- Returns:
Shape
(N,)ifreduction='none', otherwise a scalar. Neurons with fewer than 2 valid positions or zero variance yield NaN.- Return type:
torch.Tensor
- deepSTRF.metrics.performance.fve(pred: Tensor, gt: Tensor, mask: Tensor | None = None, reduction: str = 'mean') Tensor[source]
Fraction of variance explained (R²) per neuron, over flattened valid positions.
FVE_n = 1 - SS_res / SS_totwhereSS_totis the variance ofgtonly. Negative when the prediction is worse than predicting the mean.- Parameters:
pred (
torch.Tensor) – Prediction of shape(B, N, 1, T).gt (
torch.Tensor) – Pre-computed PSTH(B, N, 1, T)or raw responses(B, N, R, T)withR > 1(collapsed to PSTH viananmean(dim=2, keepdim=True)first). May contain NaN.mask (
torch.Tensor, optional) – Bool tensor broadcastable to(B, N, 1, T). If None, defaults to~gt.isnan(); if provided, REPLACES the NaN-derived mask.reduction (
{'none', 'mean', 'sum'}, default'mean') – Reduction over the neuron axis.
- Returns:
Shape
(N,)ifreduction='none', otherwise a scalar. Neurons with fewer than 2 valid positions or zero target variance yield NaN.- Return type:
torch.Tensor
- deepSTRF.metrics.performance.noise_power(responses: Tensor, mask: Tensor | None = None, reduction: str = 'mean') Tensor[source]
Sahani-Linden noise power per neuron (
NP = TP - SP).- Parameters:
responses (
torch.Tensor) – Raw responses of shape(B, N, R, T). NaN marks missing repeats / time bins.mask (
torch.Tensor, optional) – Bool tensor broadcastable toresponses. If None, defaults to~responses.isnan(); if provided, REPLACES the NaN-derived mask.reduction (
{'none', 'mean', 'sum'}, default'mean') – Reduction over the neuron axis.
- Returns:
Shape
(N,)ifreduction='none', otherwise a scalar.- Return type:
torch.Tensor
- deepSTRF.metrics.performance.normalized_corrcoef(pred: Tensor, responses: Tensor, method: str = 'schoppe', mask: Tensor | None = None, reduction: str = 'mean', ccmax_iters: int = 126) Tensor[source]
Noise-corrected correlation coefficient per neuron.
See
metrics_paradigm.md§6.4.- Parameters:
pred (
torch.Tensor) – Prediction of shape(B, N, 1, T)(the model-output convention; the R-axis must be 1).responses (
torch.Tensor) – Raw responses(B, N, R, T). The PSTH is formed internally viananmean(dim=2, keepdim=True); the noise ceiling uses the full repeat axis. May contain NaN.method (
{'schoppe', 'hsu'}, default'schoppe') –'schoppe'divides bysqrt(var(pred) · SP)(Schoppe et al. 2016);'hsu'divides the raw Pearson byCCmax(Hsu/Spearman-Brown).mask (
torch.Tensor, optional) – Bool tensor broadcastable to the PSTH(B, N, 1, T). If None, defaults to~psth.isnan(); if provided, REPLACES the NaN-derived mask.reduction (
{'none', 'mean', 'sum'}, default'mean') – Reduction over the neuron axis.ccmax_iters (
int, default126) – Cap on random half-splits per(stim, neuron)for the'hsu'CCmax estimate.
- Returns:
Shape
(N,)ifreduction='none', otherwise a scalar. In the single-trial degenerate case (R = 1everywhere) the noise correction is undefined and the rawcorrcoef(pred, psth)is returned.- Return type:
torch.Tensor- Raises:
ValueError – If
methodis not'schoppe'or'hsu', or if the input shapes are inconsistent.
- deepSTRF.metrics.performance.signal_power(responses: Tensor, mask: Tensor | None = None, reduction: str = 'mean') Tensor[source]
Sahani-Linden signal power per neuron.
Computed per-stimulus (with the per-stim valid repeat count) then length-weighted across stimuli. Cells without any qualifying stim — needs ≥ 2 valid repeats and ≥ 2 valid time bins — return NaN.
- Parameters:
responses (
torch.Tensor) – Raw responses of shape(B, N, R, T). NaN marks missing repeats / time bins.mask (
torch.Tensor, optional) – Bool tensor broadcastable toresponses. If None, defaults to~responses.isnan(); if provided, REPLACES the NaN-derived mask.reduction (
{'none', 'mean', 'sum'}, default'mean') – Reduction over the neuron axis.
- Returns:
Shape
(N,)ifreduction='none', otherwise a scalar.- Return type:
torch.Tensor
- deepSTRF.metrics.performance.snr(responses: Tensor, mask: Tensor | None = None, reduction: str = 'mean') Tensor[source]
Signal-to-noise ratio per neuron (
SNR = SP / NP).- Parameters:
responses (
torch.Tensor) – Raw responses of shape(B, N, R, T). NaN marks missing repeats / time bins.mask (
torch.Tensor, optional) – Bool tensor broadcastable toresponses. If None, defaults to~responses.isnan(); if provided, REPLACES the NaN-derived mask.reduction (
{'none', 'mean', 'sum'}, default'mean') – Reduction over the neuron axis.
- Returns:
Shape
(N,)ifreduction='none', otherwise a scalar. Noiseless cells (NP ≈ 0) yield+inf; the caller decides whether to filter.- Return type:
torch.Tensor
Module contents
- deepSTRF.metrics.coherence(pred: Tensor, gt: Tensor, dt_ms: float, reduction: str = 'mean') Tensor[source]
Magnitude-squared coherence per neuron (mean over frequency bins).
Eval-only: uses
scipy.signal.coherence, no gradient.- Parameters:
pred (
torch.Tensor) – Prediction of shape(B, N, 1, T).gt (
torch.Tensor) – Ground-truth PSTH of shape(B, N, 1, T).dt_ms (
float) – Time-bin width in milliseconds; sets the sampling ratefs = 1 / (dt_ms · 1e-3)passed toscipy.signal.coherence.reduction (
{'none', 'mean', 'sum'}, default'mean') – Reduction over the neuron axis.
- Returns:
Shape
(N,)ifreduction='none', otherwise a scalar.- Return type:
torch.Tensor- Raises:
ValueError – If any element of
predorgtis NaN (this metric does not tolerate NaN; pre-flatten to a NaN-free subset first).
- deepSTRF.metrics.corrcoef(pred: Tensor, gt: Tensor, mask: Tensor | None = None, reduction: str = 'mean') Tensor[source]
Pearson correlation per neuron over flattened valid (B, T) positions.
See
metrics_paradigm.md§6.3.- Parameters:
pred (
torch.Tensor) – Prediction of shape(B, N, 1, T).gt (
torch.Tensor) – Pre-computed PSTH(B, N, 1, T)or raw responses(B, N, R, T)withR > 1(collapsed to PSTH viananmean(dim=2, keepdim=True)first). May contain NaN.mask (
torch.Tensor, optional) – Bool tensor broadcastable to(B, N, 1, T). If None, defaults to~gt.isnan(); if provided, REPLACES the NaN-derived mask.reduction (
{'none', 'mean', 'sum'}, default'mean') – Reduction over the neuron axis.
- Returns:
Shape
(N,)ifreduction='none', otherwise a scalar. Neurons with fewer than 2 valid positions or zero variance yield NaN.- Return type:
torch.Tensor
- deepSTRF.metrics.fve(pred: Tensor, gt: Tensor, mask: Tensor | None = None, reduction: str = 'mean') Tensor[source]
Fraction of variance explained (R²) per neuron, over flattened valid positions.
FVE_n = 1 - SS_res / SS_totwhereSS_totis the variance ofgtonly. Negative when the prediction is worse than predicting the mean.- Parameters:
pred (
torch.Tensor) – Prediction of shape(B, N, 1, T).gt (
torch.Tensor) – Pre-computed PSTH(B, N, 1, T)or raw responses(B, N, R, T)withR > 1(collapsed to PSTH viananmean(dim=2, keepdim=True)first). May contain NaN.mask (
torch.Tensor, optional) – Bool tensor broadcastable to(B, N, 1, T). If None, defaults to~gt.isnan(); if provided, REPLACES the NaN-derived mask.reduction (
{'none', 'mean', 'sum'}, default'mean') – Reduction over the neuron axis.
- Returns:
Shape
(N,)ifreduction='none', otherwise a scalar. Neurons with fewer than 2 valid positions or zero target variance yield NaN.- Return type:
torch.Tensor
- deepSTRF.metrics.mse_loss(pred: Tensor, gt: Tensor, mask: Tensor | None = None, reduction: str = 'mean') Tensor[source]
Boolean-masked mean squared error, reduced over the neuron axis.
- Parameters:
pred (
torch.Tensor) – Prediction tensor of shape(B, N, 1, T).gt (
torch.Tensor) – Ground-truth tensor of shape(B, N, 1, T)(PSTH or single-trial target) or(B, N, R, T)withR > 1(raw responses), in which case it is collapsed to PSTH viananmean(dim=2, keepdim=True)before the loss is computed.gtmay contain NaN; positions where the resulting PSTH is NaN are dropped from the per-neuron mean.mask (
torch.Tensor, optional) – Bool tensor broadcastable to the post-collapsegtshape(B, N, 1, T). If None, defaults to~gt.isnan(). If provided, REPLACES (does not augment) the NaN-derived mask.reduction (
{'none', 'mean', 'sum'}, default'mean') – Reduction over the neuron axis.'none'returns the per-neuron vector;'mean'/'sum'reduce it via nanmean / nansum.
- Returns:
Shape
(N,)ifreduction='none', otherwise a scalar.- Return type:
torch.Tensor
- deepSTRF.metrics.noise_power(responses: Tensor, mask: Tensor | None = None, reduction: str = 'mean') Tensor[source]
Sahani-Linden noise power per neuron (
NP = TP - SP).- Parameters:
responses (
torch.Tensor) – Raw responses of shape(B, N, R, T). NaN marks missing repeats / time bins.mask (
torch.Tensor, optional) – Bool tensor broadcastable toresponses. If None, defaults to~responses.isnan(); if provided, REPLACES the NaN-derived mask.reduction (
{'none', 'mean', 'sum'}, default'mean') – Reduction over the neuron axis.
- Returns:
Shape
(N,)ifreduction='none', otherwise a scalar.- Return type:
torch.Tensor
- deepSTRF.metrics.normalized_corrcoef(pred: Tensor, responses: Tensor, method: str = 'schoppe', mask: Tensor | None = None, reduction: str = 'mean', ccmax_iters: int = 126) Tensor[source]
Noise-corrected correlation coefficient per neuron.
See
metrics_paradigm.md§6.4.- Parameters:
pred (
torch.Tensor) – Prediction of shape(B, N, 1, T)(the model-output convention; the R-axis must be 1).responses (
torch.Tensor) – Raw responses(B, N, R, T). The PSTH is formed internally viananmean(dim=2, keepdim=True); the noise ceiling uses the full repeat axis. May contain NaN.method (
{'schoppe', 'hsu'}, default'schoppe') –'schoppe'divides bysqrt(var(pred) · SP)(Schoppe et al. 2016);'hsu'divides the raw Pearson byCCmax(Hsu/Spearman-Brown).mask (
torch.Tensor, optional) – Bool tensor broadcastable to the PSTH(B, N, 1, T). If None, defaults to~psth.isnan(); if provided, REPLACES the NaN-derived mask.reduction (
{'none', 'mean', 'sum'}, default'mean') – Reduction over the neuron axis.ccmax_iters (
int, default126) – Cap on random half-splits per(stim, neuron)for the'hsu'CCmax estimate.
- Returns:
Shape
(N,)ifreduction='none', otherwise a scalar. In the single-trial degenerate case (R = 1everywhere) the noise correction is undefined and the rawcorrcoef(pred, psth)is returned.- Return type:
torch.Tensor- Raises:
ValueError – If
methodis not'schoppe'or'hsu', or if the input shapes are inconsistent.
- deepSTRF.metrics.poisson_loss(pred: Tensor, gt: Tensor, mask: Tensor | None = None, reduction: str = 'mean', log_input: bool = False, validate_input: bool = False, eps: float = 1e-08) Tensor[source]
Negative Poisson log-likelihood (without the
log(gt!)constant).- Parameters:
pred (
torch.Tensor) – Prediction of shape(B, N, 1, T). Interpreted as the rateλwhenlog_input=Falseand as the log-rateη = log(λ)whenlog_input=True(see Notes).gt (
torch.Tensor) – Ground-truth target. A pre-computed PSTH(B, N, 1, T)or a raw responses tensor(B, N, R, T)withR > 1; in the latter case it is collapsed to PSTH viananmean(dim=2, keepdim=True)first. May contain NaN.mask (
torch.Tensor, optional) – Bool tensor broadcastable to(B, N, 1, T). If None, defaults to~gt.isnan(). If provided, REPLACES (does not augment) the NaN-derived mask.reduction (
{'none', 'mean', 'sum'}, default'mean') – Reduction over the neuron axis ('none'keeps the(N,)vector).log_input (
bool, defaultFalse) – Selects the prediction parameterisation (see Notes).validate_input (
bool, defaultFalse) – Whenlog_input=False, raise on negativepredat masked-in positions instead of silently clamping inside the log. Costs a per-step CPU sync.eps (
float, default1e-8) – Floor applied topredinside the log whenlog_input=False.
- Returns:
Shape
(N,)ifreduction='none', otherwise a scalar.- Return type:
torch.Tensor
Notes
Two parameterisations of the prediction are supported, matching the canonical-link logic of generalised linear models:
log_input=False(default): the loss ispred − gt · log(pred + eps)per element.predmust be non-negative for the log to be meaningful; the implementation silently clampspredto≥ epsinside thelogto avoid NaN propagation (the linear term keeps its sign). Passvalidate_input=Truefor a loud failure on negative predictions.log_input=True: the loss becomesexp(pred) − gt · pred, which is well-defined for any real-valuedpred. This is the standard trick for pairing a Poisson NLL with an unbounded readout (Linear, sign-permitting ParametricSigmoid, etc.). Seemetrics_paradigm.md§6.2 for the GLM-canonical-link derivation.
The
log(gt!)Stirling term is not added — for non-integergt(e.g. trial-averaged PSTH binned counts) it is meaningless, and for integergtit is constant inpredso it does not affect optimisation. Users who want the full likelihood for AIC/BIC can add it themselves.
- deepSTRF.metrics.signal_power(responses: Tensor, mask: Tensor | None = None, reduction: str = 'mean') Tensor[source]
Sahani-Linden signal power per neuron.
Computed per-stimulus (with the per-stim valid repeat count) then length-weighted across stimuli. Cells without any qualifying stim — needs ≥ 2 valid repeats and ≥ 2 valid time bins — return NaN.
- Parameters:
responses (
torch.Tensor) – Raw responses of shape(B, N, R, T). NaN marks missing repeats / time bins.mask (
torch.Tensor, optional) – Bool tensor broadcastable toresponses. If None, defaults to~responses.isnan(); if provided, REPLACES the NaN-derived mask.reduction (
{'none', 'mean', 'sum'}, default'mean') – Reduction over the neuron axis.
- Returns:
Shape
(N,)ifreduction='none', otherwise a scalar.- Return type:
torch.Tensor
- deepSTRF.metrics.snr(responses: Tensor, mask: Tensor | None = None, reduction: str = 'mean') Tensor[source]
Signal-to-noise ratio per neuron (
SNR = SP / NP).- Parameters:
responses (
torch.Tensor) – Raw responses of shape(B, N, R, T). NaN marks missing repeats / time bins.mask (
torch.Tensor, optional) – Bool tensor broadcastable toresponses. If None, defaults to~responses.isnan(); if provided, REPLACES the NaN-derived mask.reduction (
{'none', 'mean', 'sum'}, default'mean') – Reduction over the neuron axis.
- Returns:
Shape
(N,)ifreduction='none', otherwise a scalar. Noiseless cells (NP ≈ 0) yield+inf; the caller decides whether to filter.- Return type:
torch.Tensor