Source code for ts2.models.single_session.stat_baseline.co_smoothing.readout_rrr

"""Reduced-rank regression, the standard NLB baseline.

A rank-k ridge readout from the observed units to the held-out units at each timestep.
Unlike ``PopCoupling``'s rank-1 coupling this captures unit-specific, multi-dimensional
structure.
"""

import logging

import torch

from ._readout_base import RRRReadoutBase

log = logging.getLogger(__name__)


[docs] class RRRReadout(RRRReadoutBase): """Reduced-rank readout over binned counts. Args: rank: reduced rank k. ``None`` selects on val. ridge_lambda: ridge strength. ``None`` selects on val. """ NAME = "readout_rrr" STANDARDIZE = False
[docs] def fit(self, train_dataset, val_dataset): def features(dataset, obs_t, held_t): # cached per split, so both partitions share one walk counts = torch.from_numpy(self._windows(dataset).reshape(-1, self.N)) return counts.index_select(1, obs_t), counts.index_select(1, held_t) score, obs_t, held_t = self._fit_two_stage(train_dataset, val_dataset, features) log.info( f"{self.NAME}: fit reduced-rank W ({obs_t.numel()} obs -> " f"{held_t.numel()} held-out), rank={self.rank}, " f"lambda={self.ridge_lambda:.3g}, val poisson_d2={score:.4f}" )
[docs] def predict(self, spikes: torch.Tensor, **_) -> torch.Tensor: obs = self.rr_obs_idx.to(spikes.device) return self._scatter(spikes, spikes.index_select(-1, obs)) # (B, T, |O|)