fc_rmse

Contents

fc_rmse#

class braintools.fit.losses.fc_rmse(prediction, target)#

Compute the RMSE between the upper triangles of two functional-connectivity matrices.

\[L = \sqrt{\frac{2}{n(n-1)} \sum_{i<j} (\hat C_{ij} - C_{ij})^2},\]

where \(\hat C\) and \(C\) are the Pearson functional-connectivity matrices (functional_connectivity()) of n regions.

Parameters:
  • prediction (Any) – Model output of shape (n_time, n_regions), n_regions >= 2.

  • target (Any) – Data of shape (n_time', n_regions). FC is scale-invariant, so units are not compared.

Returns:

Scalar loss in [0, 2].

Return type:

Array

Raises:

ValueError – If an input is not 2-D, has fewer than 2 regions, or the region counts differ.

Notes

Only the n(n-1)/2 off-diagonal pairs enter the mean, as the 0.6 specification requires. This differs from brainmass.objectives.fc_rmse, which averages over the full n x n matrix, including the diagonal (always equal, so it adds zeros to the mean). The two are related by

\[L_{\mathrm{brainmass}} = L \sqrt{\frac{n - 1}{n}}, \qquad L = L_{\mathrm{brainmass}} \sqrt{\frac{n}{n - 1}},\]

so brainmass values are smaller by the factor \(\sqrt{(n-1)/n}\) (0.926 for \(n = 7\), e.g. 0.0869 versus 0.0939). Code ported from brainmass must rescale thresholds or weights by that factor. Works under jax.jit and jax.vmap and is differentiable (gradient 0 at a perfect fit).

Examples

>>> import jax.numpy as jnp
>>> from braintools.fit import losses
>>> t = jnp.linspace(0., 10., 200)
>>> a = jnp.stack([jnp.sin(t), jnp.sin(t), jnp.cos(t)], axis=1)
>>> b = jnp.stack([jnp.sin(t), -jnp.sin(t), jnp.cos(t)], axis=1)
>>> round(float(losses.fc_rmse(a, b)), 4)
1.1563