Source code for ts3.models.transductive.ndt_stitch.ndt_stitch_extractor

"""NDT-stitch's unit-embedding extractor.

The embedding is the unit's pair of stitcher columns, ``[in.T, out]`` concatenated to 2D.
Those are per-session parameters, so they exist only for the sessions a
checkpoint was trained on, and the units come from the recording rather than from a lookup:
the stitcher has no vocabulary, only a column order matching ``units.id``.
"""

import numpy as np
import torch

from core.dataset import WholeSessionSpikeDataset
from core.utils.logger import get_cli_logger
from ts3.models.transductive.base import TransductiveExtractor

logger = get_cli_logger()


[docs] class NDTStitchExtractor(TransductiveExtractor):
[docs] def read( self, state_dict: dict, dataset: WholeSessionSpikeDataset, uids: set[str] ) -> tuple[torch.Tensor, np.ndarray]: in_keys = [k for k in state_dict if k.startswith("in_stitcher") and k.endswith("weight")] out_keys = [k for k in state_dict if k.startswith("out_stitcher") and k.endswith("weight")] assert {k.split(".")[1] for k in in_keys} == {k.split(".")[1] for k in out_keys}, ( "In and out stitcher keys must have the same session ids" ) embs, out_uids = [], [] for rec_id in sorted({k.split(".")[1] for k in in_keys}): if rec_id not in dataset.recording_ids: logger.warning(f"Recording {rec_id} not found in dataset") continue in_weight = state_dict[f"in_stitcher.{rec_id}.weight"].T # (v, D) out_weight = state_dict[f"out_stitcher.{rec_id}.weight"] # (v, D) assert in_weight.shape == out_weight.shape, ( f"In and out stitcher weights must have the same shape, got " f"{in_weight.shape} and {out_weight.shape}" ) embs.append(torch.cat([in_weight, out_weight], dim=1)) # (v, 2D) rec_uids = dataset.get_recording(rec_id).units.id.astype(str) # (v,) assert len(rec_uids) == in_weight.shape[0], ( f"Number of units in recording {rec_id} ({len(rec_uids)}) does not match " f"the number of units in the stitcher weights ({in_weight.shape[0]})" ) out_uids.extend(rec_uids) return torch.cat(embs, dim=0), np.array(out_uids)