SPB Git

spb/wp41_uqo

Public
3.3 KB · 70 lines python
1"""Simple neural baselines on the 1-minute branch only: MLP on the origin features and a small TCN over the last 3902one-minute bars, both with the same Student-t head and loss as MRPT (matched information set, matched tuning budget).3PatchTST-style 1m-only = MRPT(branches=['A']) (see configs/ablations.yaml); iTransformer/Chronos/TimesFM: see4docs/MODEL_CARD.md §baselines-not-run for the licensing/compatibility audit."""5from __future__ import annotations67import torch8import torch.nn as nn9import torch.nn.functional as F1011from ..data.windows import F_BAR, F_GLOBAL12from ..models.student_t import StudentTHead131415class MLPBaseline(nn.Module):16    """Flattened last 60 one-minute bars + global features -> MLP -> per-minute Student-t."""1718    def __init__(self, horizon: int = 60, n_last: int = 60, d_hidden: int = 256, dropout: float = 0.1):19        super().__init__()20        self.n_last, self.H = n_last, horizon21        self.net = nn.Sequential(nn.Linear(n_last * F_BAR + F_GLOBAL + 4, d_hidden), nn.GELU(), nn.Dropout(dropout),22                                 nn.Linear(d_hidden, d_hidden), nn.GELU(), nn.Dropout(dropout))23        self.fut = nn.Linear(4, d_hidden)24        self.head = StudentTHead(d_hidden)25        self.cfg = type("C", (), {"head": "student_t", "quantiles": [], "__dict__": {}})()2627    def n_params(self):28        return sum(p.numel() for p in self.parameters())2930    def forward(self, b):31        x = b["xA"][:, -self.n_last:].reshape(b["xA"].shape[0], -1)32        g = torch.cat([x, b["glob"], b["fut_cal"][:, 0]], -1)33        h = self.net(g).unsqueeze(1) + self.fut(b["fut_cal"].float())34        out = self.head(F.gelu(h), b["sigma"]); out["hidden"] = h35        return out363738class TCNBaseline(nn.Module):39    """Dilated causal 1-D convolutions over the 390 one-minute bars; last state + future calendar -> Student-t."""4041    def __init__(self, horizon: int = 60, channels: int = 96, n_blocks: int = 6, kernel: int = 3, dropout: float = 0.1):42        super().__init__()43        self.inp = nn.Conv1d(F_BAR + 1, channels, 1)44        self.blocks = nn.ModuleList()45        for i in range(n_blocks):46            d = 2 ** i47            self.blocks.append(nn.Sequential(nn.Conv1d(channels, channels, kernel, dilation=d, padding=(kernel - 1) * d),48                                             nn.GELU(), nn.Dropout(dropout), nn.Conv1d(channels, channels, 1)))49        self.pad = [(kernel - 1) * 2 ** i for i in range(n_blocks)]50        self.glob = nn.Linear(F_GLOBAL, channels)51        self.fut = nn.Linear(4, channels)52        self.pos = nn.Embedding(horizon, channels)53        self.head = StudentTHead(channels)54        self.cfg = type("C", (), {"head": "student_t", "quantiles": [], "__dict__": {}})()5556    def n_params(self):57        return sum(p.numel() for p in self.parameters())5859    def forward(self, b):60        x = torch.cat([b["xA"], b["mA"].unsqueeze(-1).float()], -1).transpose(1, 2)61        h = self.inp(x)62        for blk, p in zip(self.blocks, self.pad):63            y = blk(h)[:, :, :-p] if p > 0 else blk(h)64            h = h + y65        last = h[:, :, -1] + self.glob(b["glob"].float())66        H = b["fut_cal"].shape[1]67        q = last.unsqueeze(1) + self.fut(b["fut_cal"].float()) + self.pos.weight[:H].unsqueeze(0)68        out = self.head(F.gelu(q), b["sigma"]); out["hidden"] = q69        return out70
Files · main
Menu

Theme