在时序预测领域,如何有效地利用外部变量(exogenous variables)来提升内部变量(endogenous variables)的预测性能一直是一个挑战。
在上一篇文章中,我结合论文为大家解读了TimeXer框架,今天,我将对TimeXer代码进行解析。
论文精度链接: TimeXer:融合外部变量与内部变量,提升时序预测性能
TimeXer算法框架中包括模块有:Endogenous Embedding,Exogenous Embedding,Endogenous Self-Attention,Exogenous-to-Endogenous Cross-Attention。
1. Endogenous Embedding
Endogenous Embedding 通过Patch级表示精细捕捉内生变量时间变化,针对内生、外生变量嵌入粒度不同产生的信息对齐问题,引入可学习的全局令牌促进外生因果信息向内生时间Patch传递,助力预测。
class EnEmbedding(nn.Module):def __init__(self, n_vars, d_model, patch_len, dropout):super(EnEmbedding, self).__init__()# patch_len: 每个补丁的长度# d_model: 嵌入维度self.patch_len = patch_len# 将 patch_len 维投影到 d_model 维,生成时间 tokenself.value_embedding = nn.Linear(patch_len, d_model, bias=False)# 全局可学习 token,初始化为 [1, n_vars, 1, d_model] 的随机值self.glb_token = nn.Parameter(torch.randn(1, n_vars, 1, d_model))# 位置嵌入,用于补充位置信息self.position_embedding = PositionalEmbedding(d_model)# Dropout 正则化self.dropout = nn.Dropout(dropout)def forward(self, x):# 输入维度 [B, V, L]n_vars = x.shape[1]# 全局令牌复制到每个 batchglb = self.glb_token.repeat((x.shape[0], 1, 1, 1))# 将时间序列划分为不重叠补丁 [B, V, N, patch_len]x = x.unfold(dimension=-1, size=self.patch_len, step=self.patch_len)# 展平为 [B*V, N, patch_len]x = torch.reshape(x, (x.shape[0] * x.shape[1], x.shape[2], x.shape[3]))# 通过线性投影生成时间 token [B*V, N, d_model]x = self.value_embedding(x) + self.position_embedding(x)# 恢复为 [B, V, N, d_model]x = torch.reshape(x, (-1, n_vars, x.shape[-2], x.shape[-1]))# 拼接全局令牌 [B, V, N+1, d_model]x = torch.cat([x, glb], dim=2)# 展平为 [B*V, N+1, d_model]x = torch.reshape(x, (x.shape[0] * x.shape[1], x.shape[2], x.shape[3]))# 应用 dropoutreturn self.dropout(x), n_vars
完整文章链接: 时序预测算法TimeXer代码解析