Source code for ibl_bwb_eval.tasks.types

"""Enums shared by more than one suite's readouts.

Each suite's own tasks and readout specs live in its module next to this one.
"""

from enum import Enum
from typing import Protocol


[docs] class TargetResolution(Enum): """How many targets a task has along the input's time axis: one, or one per timestep. This is the output's shape and not the kind of value in it (:class:`DataType`). What entity a target belongs to (a trial window in TS1, a unit in TS3) is an orthogonal axis carried by the task id, so it is deliberately not encoded here. Attributes: SEQUENCE: one target for the whole window (e.g. the choice made in 1s). TIMESTEP: one target per timestep (e.g. wheel speed @50Hz). """ SEQUENCE = 0 TIMESTEP = 1
[docs] class DataType(Enum): """What kind of value each target is, independent of :class:`TargetResolution`. A task can be classification and per-timestep at once, so size a readout head from TargetResolution and pick a loss from this. Attributes: CONTINUOUS: For continuous-valued variables BINARY: For binary variables MULTINOMIAL: For multi-class variables EVENT_RATE: For variables representing event rates """ CONTINUOUS = 0 BINARY = 1 MULTINOMIAL = 2 EVENT_RATE = 3
[docs] class ReadoutSpec(Protocol): """What a model needs to size a readout head, and nothing more. The intersection of the suites' specs, not a base class, so they stay independent. ``dim`` and ``num_timesteps`` are properties so a spec deriving them (TS3) and one storing them (TS1) both qualify. ``num_timesteps`` is the length of the axis :class:`TargetResolution` names, 1 for a sequence-level task and the target's sample count for a timestep-level one, so a model sizes its head without branching on it. """ id: str target_resolution: TargetResolution @property def dim(self) -> int: ... @property def num_timesteps(self) -> int: ...