时间序列预测论文讲解-[AAAI 2024] HDMixer: Hierarchical Dependency with Extendable Patch for Multivariate Time

[AAAI 2024] HDMixer: Hierarchical Dependency with Extendable Patch for Multivariate Time Series Forecasting

研究背景与动机

文章介绍了多变量时间序列预测的研究背景,指出了现有方法在处理此类问题时存在的局限性。多变量时间序列预测在多个领域如金融、气象、医疗等都有重要应用。传统的预测方法往往忽略了时间序列之间的相互依赖性,且难以处理长序列数据。

文章还提到了Length-fixed patch方法的局限性,即其无法适应不同时间序列的特点,导致模型性能受限。这为研究提供了动机,即需要一种新的方法来更好地捕捉多变量时间序列之间的复杂依赖关系。

模型和方法

作者认为,通过Length-Extendable Patcher (LEP) 可以自适应地扩展时间序列的长度,并结合Hierarchical Dependency Explorer (HDE) 来捕捉不同层次的时间依赖性,从而提高预测的准确性。
在这里插入图片描述

Length-Extendable Patcher (LEP)

LEP 的设计目的是为了克服传统固定长度 patch 方法在处理时间序列数据时的局限性。固定长度的 patches 可能会丢失重要的边界信息,如完整的峰值或周期。因此,LEP 的设计理念是自适应地调整 patch 长度,以保留更多的语义信息。

LEP的大概思路如下:

  • 这一部分的目的是将原始时间序列分割成具有可变长度的 patches,以更好地捕捉时间序列中的局部特征。
  • 与传统的固定长度 patch 方法不同,LEP 通过学习得到的偏移量和扩展长度来动态调整 patch 的大小。
  • 通过 bi-linear 插值方法来处理非整数索引的采样问题,保证了模型的可微性。

为了确保 LEP 生成的 patches 能够提供有用的信息,文章引入了 Patch Entropy Loss。这个损失函数基于近似熵来衡量不同 patch 方法的复杂性差异。

LEP 的主要优势在于其能够自适应地生成 patches,从而保留了时间序列中的边界信息,减少了信息丢失,并提高了模型的预测性能。

通过这种方式,LEP 为多变量时间序列预测提供了一种更加灵活和有效的数据预处理方法。
在这里插入图片描述

Hierarchical Dependency Explorer (HDE)

HDE 的设计理念是利用纯多层感知机 (MLP) 结构来有效捕捉时间序列数据中的长期依赖、短期依赖以及变量间的交互。它的目的是为了提高模型在多变量时间序列预测中的表现。

HDE的大概思路如下:

  • HDE 是模型的核心部分,用于探索和捕捉时间序列中的多尺度依赖关系。
  • 它由多个 HDMixer 块组成,每个块通过多层感知机 (MLP) 来分别处理短期依赖、长期依赖和变量间的交互。
  • HDMixer 块的设计允许模型在不同的时间尺度上捕捉依赖关系,同时保持参数数量的可控性。

HDE 的主要优势包括:捕捉多尺度依赖:通过不同的 MLP 层,HDE 能够捕捉到时间序列数据中的多尺度依赖关系。参数效率:由于参数共享和层归一化,HDE 在保持模型复杂性的同时,提高了参数的效率。泛化能力:HDE 的设计使得模型具有良好的泛化能力,能够适应不同的时间序列数据。
在这里插入图片描述

代码

HDMixer



# Cell
from typing import Callable, Optional
import torch
from torch import nn
from torch import Tensor
import torch.nn.functional as F
import numpy as np

from layers.PatchTST_layers import *
from layers.RevIN import RevIN
from layers.box_coder1D import *
import math

def generate_pairs(n):
    pairs = []
    
    for i in range(n):
        for j in range(n):
            if i != j:
                pairs.append([i, j])
    
    return np.array(pairs)


def cal_PSI(x, r):
    #[bs x nvars x patch_len x patch_num]
    x = x.permute(0,1,3,2)
    batch, n_vars, patch_num, patch_len = x.shape
    x = x.reshape(batch*n_vars, patch_num, patch_len)
    # Generate all possible pairs of patch_num indices within each batch
    pairs = generate_pairs(patch_num)
    # Calculate absolute differences between pairs of sequences
    abs_diffs = torch.abs(x[:, pairs[:, 0], :] - x[:, pairs[:, 1], :])
    # Find the maximum absolute difference for each pair of sequences
    max_abs_diffs = torch.max(abs_diffs, dim=-1).values 
    max_abs_diffs = max_abs_diffs.reshape(-1,patch_num,patch_num-1)
    # Count the number of pairs with max absolute difference less than r
    c = torch.log(1+torch.mean((max_abs_diffs < r).float(),dim=-1))
    psi = torch.mean(c,dim=-1)
    return psi

def cal_PaEn(lfp,lep,r,lambda_):
    psi_lfp = cal_PSI(lfp,r)
    psi_lep = cal_PSI(lep,r)
    psi_diff = psi_lfp - psi_lep
    lep = lep.permute(0,1,3,2)
    batch, n_vars, patch_num, patch_len = lep.shape    
    lep = lep.reshape(batch*n_vars, patch_num, patch_len)
    sum_x = torch.sum(lep, dim=[-2,-1])
    PaEN_loss = torch.mean(sum_x*psi_diff)*lambda_ # update parameters with REINFORCE
    return PaEN_loss

class Model(nn.Module):
    def __init__(self, configs, max_seq_len:Optional[int]=1024, d_k:Optional[int]=None, d_v:Optional[int]=None, norm:str='BatchNorm', attn_dropout:float=0., 
                 act:str="gelu", key_padding_mask:bool='auto',padding_var:Optional[int]=None, attn_mask:Optional[Tensor]=None, res_attention:bool=False, 
                 pre_norm:bool=False, store_attn:bool=False, pe:str='zeros', learn_pe:bool=True, pretrain_head:bool=False, head_type = 'flatten', verbose:bool=False, **kwargs):
        
        super().__init__()
        
        # load parameters
        c_in = configs.enc_in
        self.seq_len=context_window = configs.seq_len
        target_window = configs.pred_len
        
        n_layers = configs.e_layers
        n_heads = configs.n_heads
        d_model = configs.d_model
        d_ff = configs.d_ff
        dropout = configs.dropout
        fc_dropout = configs.fc_dropout
        head_dropout = configs.head_dropout
        
        individual = configs.individual
    
        patch_len = configs.patch_len
        stride = configs.stride
        padding_patch = configs.padding_patch
        
        revin = configs.revin
        affine = configs.affine
        subtract_last = configs.subtract_last
        
        decomposition = configs.decomposition
        kernel_size = configs.kernel_size
        
        
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值