CycleNet源码解析:可学习周期分解的时间序列预测
CycleNet是NeurIPS 2024收录的轻量级时序预测模型,其核心创新在于通过显式建模数据的周期性成分来简化预测任务。本文将深入剖析其PyTorch实现,重点关注周期分解机制与残差预测的具体代码逻辑。
核心架构:周期-残差双分支设计
模型的基本假设是时间序列可分解为周期性成分与残差成分。前者通过可学习参数显式建模,后者则由轻量网络预测。这种解耦策略显著降低了学习难度,尤其适合具有稳定周期特征的数据。
def forward(self, inputs, start_idx):
# inputs: [B, L, C] 批次、历史长度、通道数
# start_idx: [B] 各样本在周期中的起始偏移
# 实例归一化
if self.use_revin:
mu = inputs.mean(dim=1, keepdim=True)
sigma = torch.sqrt(inputs.var(dim=1, keepdim=True) + 1e-5)
inputs = (inputs - mu) / sigma
# 剥离历史周期成分
periodic_hist = self.period_bank(start_idx, self.hist_len)
residual = inputs - periodic_hist
# 通道独立预测残差
residual_pred = self.predictor(
residual.transpose(1, 2)
).transpose(1, 2) # [B, pred_len, C]
# 叠加未来周期成分
future_idx = (start_idx + self.hist_len) % self.period_size
periodic_future = self.period_bank(future_idx, self.pred_len)
outputs = residual_pred + periodic_future
# 反归一化
if self.use_revin:
outputs = outputs * sigma + mu
return outputs
周期记忆模块:高效索引实现
period_bank是模型的关键组件,以可学习参数存储一个完整周期的模式:
class PeriodicMemory(nn.Module):
def __init__(self, period_len, channels):
super().__init__()
self.period_len = period_len
self.channels = channels
# 可学习的周期模板 [period_len, channels]
self.template = nn.Parameter(
torch.zeros(period_len, channels)
)
def forward(self, offsets, span):
# offsets: [B] 各样本的起始位置
# span: 需要连续取样的长度
# 构建全局索引: [B, span]
# 行方向: 各样本的起始偏移
# 列方向: 0到span-1的连续位置
positions = offsets.unsqueeze(1) + torch.arange(
span, device=offsets.device
).unsqueeze(0)
# 周期循环取模
cyclic_idx = positions % self.period_len
# 向量化索引提取 [B, span, channels]
return self.template[cyclic_idx]
该实现摒弃了循环遍历,通过张量广播与模运算实现一次性索引,速度提升约2-3倍。
残差预测网络:极简MLP设计
剥离周期后的残差序列交由轻量网络处理,作者提供两种配置:
- Linear:单层全连接,参数量最低
- MLP:双层结构带激活,实际效果更优
class ResidualForecaster(nn.Module):
def __init__(self, hist_len, pred_len, channels, hidden=None):
super().__init__()
self.channels = channels
if hidden is None: # Linear模式
self.layers = nn.Linear(hist_len, pred_len)
else: # MLP模式
self.layers = nn.Sequential(
nn.Linear(hist_len, hidden),
nn.ReLU(),
nn.Linear(hidden, pred_len)
)
def forward(self, x):
# x: [B, channels, hist_len]
# 通道独立:各通道共享相同映射权重
return self.layers(x) # [B, channels, pred_len]
实现要点与局限
周期设定的敏感性:模型性能高度依赖period_len的选取。以Weather数据集为例,144步长表现最优,偏离此值则显著下降,暗示需针对数据集调参或引入自适应周期学习。
场景适配边界:在交通流等时空耦合复杂数据中,单层MLP难以捕捉通道间交互与时滞依赖,表现不及iTransformer等架构。此外,数据中的突变异常会破坏周期假设,导致预测失效。
计算效率优势:得益于周期分解与极简预测器,CycleNet参数量远低于PatchTST等模型,训练推理速度具有明显优势,在周期特征明确的场景下性价比突出。
