机器学习周记(第三十三周:文献阅读-时空双通路框架)2024.3.25~2024.3.31

目录

摘要

ABSTRACT

1 论文信息

1.1 论文标题

1.2 论文摘要 

1.3 论文模型

1.3.1 Spatial Encoder(空间编码器)

1.3.2 Temporal Encoder(时间编码器)

2 相关代码


摘要

  本周阅读了一篇运用GNN进行时间序列预测的论文。论文主要提出了一种分离空间和时间编码器的双通路框架,用于通过有效的时空表示学习准确预测水温,特别是极端的高水温。框架主要使用Transformer的自注意机制构造空间和时间编码器执行任务,同时采用了各种补丁嵌入方法和空间特征位置嵌入方法的组合。此外,本周还运用GAT模型进行了一个时间序列预测的实验。

ABSTRACT

This week, We read a paper on time series prediction using GNNs. The paper proposes a dual-pathway framework that separates spatial and temporal encoders for accurate prediction of water temperature, particularly extreme high water temperature, through effective spatiotemporal representation learning. The framework primarily utilizes Transformer's self-attention mechanism to construct spatial and temporal encoders for the task, along with various combinations of patch embedding methods and spatial feature positional embedding methods. Additionally, this week, an experiment on time series prediction was conducted using the GAT model.

1 论文信息

1.1 论文标题

Two-pathway spatiotemporal representation learning for extreme water temperature prediction

1.2 论文摘要 

  准确预测极端水温对于了解海洋环境的变化以及减少全球变暖导致的海洋灾害至关重要。在本研究中,提出了一个分离空间和时间编码器的双通路框架,用于通过有效的时空表示学习准确预测水温,特别是极端高水温。基于Transformer自注意机制构造空间和时间编码器网络执行任务,预测朝鲜半岛周围16个沿海位置未来连续七天的水温时间序列,同时采用了各种组合的补丁嵌入方法空间特征的位置嵌入。最后还进行了与传统深度卷积和递归网络的比较实验,通过比较和评估这些结果,所提出的双路径框架能够通过更好地捕获来自开放海洋和区域海域的时空相互关系和长期特征关系,改善对极端沿海水温的可预测性,并进一步确定基于自注意力的空间和时间编码器的最佳架构细节。此外,为了检查所提出的模型的可解释性及其与领域知识的一致性,进行了模型可视化并分析了空间和时间注意力图,展示了与未来预测更相关的时空输入序列的权重。

1.3 论文模型

  双通路框架主要包括空间编码器(Spatial Encoder)时间编码器(Temporal Encoder),如Fig.(a)所示。这两个编码器主要用来学习多尺度时空相互关系特征表示,将时空数据V(t,h,w)的特征表示通过SpatialEncoderTemporalEncoder分为两个空间组件,维度分别为hw,以及一个时间组件,维度为t。第一条路径中,SpatialEncoder捕获给定输入数据的一个连续片段的空间依赖关系。第二条路径中,TemporalEncoder捕获从SpatialEncoder中以时间顺序提供的连续序列空间特征向量之间的时间依赖关系,与时间特征融合。Fig.1(a)中的二维嵌入包含一个将输入数据映射到特征空间的操作,然后将其输出结果送到连续的空间编码器中。对于CNN,它通过3 \times 3卷积核卷积操作执行,而对于基于自注意力的网络,则是将每个数据分成补丁。嵌入特征被馈送到SpatialEncoder,并构建为Feature Vector以学习时空特征表示。Feature Vector的大小是固定的,并且为了比较各种实验模型组合的性能,确定了实现它所需的编码器数量。通过空间编码器压缩的Feature Vector以时间顺序被接收到TemporalEncoder中,以构建集成的时空特征向量。

Fig.1

  输入的网格化时空数据序列记作VV \in \mathbb{R}^{T \times H \times W}。其中,HWT分别代表网格化时空数据的高度、宽度和多个连续时间序列。V被映射为来自时间、高度和宽度维度的补丁嵌入的一系列标记\widetilde{Z}\widetilde{Z} \in \mathbb{R}^{n_{t} \times n_{h} \times n_{w} \times d}。如果使用位置嵌入,\widetilde{Z}将被重塑为\mathbb{R}^{N \times d}d是标记维度,N表示非重叠图像补丁。从每个数据序列中提取n_{h} \times n_{w}个非重叠图像补丁,然后将具有位置嵌入的总共n_{t} \times n_{h} \times n_{w}个标记传到Transformer的核心共同块SpatialEncoder中的多头自注意力(MSA)。从SpatialEncoder中获得的输出F是从输入的网格化时空数据序列V中获得的新表示,具有4 \times 4 \times 512的隐藏特征向量。SpatialEncoder的输出F被馈送到TemporalEncoder的输入中,以学习空间特征的时间依赖性。基于TemporalEncoderTransformer架构,通过缩放点积注意力计算输入F的单个自注意力,如Eq.(1)所述。缩放点积注意力的输入包括维度为d_{k}queries(Qkeys(K,以及维度为d_{v}的值(V)。计算queries与所有keys的点积,每个除以\sqrt{d_{k}},并应用softmax函数来获得值的权重。与具有Fkeysqueries和值的单个注意力函数相比,通过MSA,将querieskeys和值线性投影h次,分别到d_{k}d_{k}d_{v}维度,然后在这些投影版本的querieskeys和值上并行执行注意力函数,产生d_{v}维输出值,更利于结果。这些输出被串联并再次投影,得到最终值。多头注意力使模型能够同时关注不同位置的不同表示子空间的信息。使用单个注意力头,平均会抑制这一特性。通过MSA模块,表示具有时间特征的512维向量,这些向量被转换为连续时空序列的16个目标。

Attention(Q,K,V)=softmax(\frac{QK^{T}}{\sqrt{d_{k}}})V                                                                      (1)

MultiHead(Q,K,V)=Concat(head_{1},...,head_{h})W^{O}                                             (2)

其中\sqrt{d_{k}}是key向量和query向量的维度,head_{i}=Attention(QW_{i}^{Q},KW_{i}^{K},VW_{i}^{V})

  SpatialEncoder应用了ViT(Fig.2(a)和(b))ViT变体Swin Transformer(SwinT,Fig.2(c)和(d))全局上下文ViT(GCViT,Fig.2(c)和(e))多路径ViT(MPViT)(Fig.2(f)和(g)),还包括基本的2D CNN(Fig.1(b))。此外,还将LSTM(Fig.1(c))基于多头自注意力的 Transformer(MAT,Fig.1(d))作为TemporalEncoder应用,通过不同方式的SpatialEncoderTemporalEncoder的组合来检验多尺度自注意力时空特征表示的性能,如Table.1所述。同时还研究了10种单独应用SpatialEncoderTemporalEncoder的实验组合。如Fig.2所示,ViTViT 变体SwinTGCViTMPViT具有共同的基于多头自注意力的Transformer架构。然而,位置和补丁嵌入方法存在差异,如Fig2(a)(c)(f)所示。此外,可以根据投影注意力的方法以及是否将其视为分层结构进行分类,如Table2所示。

Fig.2
Table.1
Table.2

1.3.1 Spatial Encoder(空间编码器)

ViT:一个基于自注意力的空间编码器,通常由两部分组成:补丁构建和Transformer块。如Fig.2(a)所示,对于来自输入的补丁嵌入,2D网格数据的序列被划分为固定大小的补丁,然后进行线性嵌入,并添加一维(1D)位置嵌入以将它们重塑为扁平化的2D补丁序列1D位置嵌入也按照网格顺序添加到补丁嵌入中。结果的补丁嵌入向量序列被输入到SpatialEncoder中,它具有与标准MAT Transformer相同的结构(Fig.2(b))。它由LayerNorm(LN)MSAMLP块组成。在每个MLP块之前和之后分别应用了LN残差连接MLP包含用于非线性的高斯误差线性单元(GeLU)MSA是自注意力的扩展,可以并行执行i个自注意力操作并投影它们的串联输出。

SwinT:为了学习更高分辨率的空间特征,SwinT通过逐渐合并深层中相邻的补丁来构建分层特征图,从较小的补丁开始。分层表示是在一种偏移的窗口方案中计算的,它通过将自注意力计算限制在非重叠的局部窗口中来提高效率,同时允许跨窗口连接。对于补丁嵌入(Fig.2(c)),它首先将输入的网格数据划分为非重叠的补丁。然后在这些补丁标记上应用具有修改后自注意力(即SwinT块)Transformer块,配置如Fig.2(d)所示。SwinT块通过依次连接用于窗口内自注意力操作的Window Multi-head Self-Attention (W-MSA)和用于W-MSA的窗口之间补丁的自注意力操作的Shifted Window Multi-head Self-Attention (SW-MSA),然后在两个MLP层之间插入GeLU来配置。自注意力是在本地窗口内计算的,这些窗口被排列成以非重叠方式均匀划分图像。在每个MSA模块和每个MLP块之前都应用了LN层和残差连接,并在每个模块之后应用了残差连接Transformer块保持了补丁的数量(H/2 \times W/2),并且与线性嵌入一起被划分为第1个Transformer层。为了创建分层表示,随着网络的加深,补丁合并层会减少补丁(标记)的数量。Transformer层共同创建具有相同分辨率的特征图的分层表示。

1.3.2 Temporal Encoder(时间编码器)

  TemporalEncoder使用了两种模型:一种是LSTM,它是一种RNN的变种,另一种是基于自注意力的TE,用于通过SpatialEncoder(Fig.2(c)和(d))捕捉压缩的空间特征向量连续序列之间的时间依赖关系。LSTM接收压缩了空间信息的特征向量作为输入,并将其馈送到LSTM单元中以编码时间信息。TemporalEncoder接收压缩了空间信息的特征向量作为输入,并使用自注意力编码时间信息。与此同时,MLPLinear-GeLU-Linear组成。一系列由先前的SpatialEncoder层压缩的空间特征向量被顺序地馈送到TemporalEncoder。然后通过双通道方法将空间和时间特征分别融合为输出特征图,用于空间-时间特征表示学习。

2 相关代码

实验:PyG搭建图神经网络实现多变量输入多变量输出时间序列预测

参考代码:PyG搭建图神经网络实现多变量输入多变量输出时间序列预测_利用pyg库实现时间序列预测-CSDN博客

step1:首先需要构造图结构,在将多元时间序列数据转化成一个图结构数据之前,需要确定各个节点的空间关系(Node Embedding,一个变量为一个节点)。一个很自然的想法就是计算不同的变量序列间的相关系数,然后使用一个阈值进行判断,如果两个节点(变量)它们的序列间的相关系数大于这个阈值,那么两个变量节点间就存在边。

# num_nodes:节点(变量)数量; data:节点特征数据,data的维度为(x, num_nodes)
def create_graph(num_nodes, data):
    # 将data(feature, num_nodes)序列转换成特征矩阵features(num_nodes, feature)
    features = torch.transpose(torch.tensor(data), 0, 1)
    # 创建一个空的邻接矩阵,用于存储图中的边
    edge_index = [[], []]
    # 遍历所有节点
    for i in range(num_nodes):
        # 遍历当前节点之后的所有节点,以避免重复添加边
        for j in range(i + 1, num_nodes):
            # 从输入的data数据中获取两个节点的特征向量
            x, y = data[:, i], data[:, j]
            # 计算两个节点之间的相关性
            corr = calc_corr(x, y)
            # 如果两个节点之间的相关性大于等于0.4,则将它们之间添加一条边
            if corr >= 0.4:
                edge_index[0].append(i)
                edge_index[1].append(j)

    # 将邻接矩阵转换为PyTorch的长整型张量
    edge_index = torch.LongTensor(edge_index)
    # 创建图对象
    graph = Data(x=features, edge_index=edge_index)
    # 将有向图转换为无向图,以确保每一条有向边都有一个相对应的反向边
    graph.edge_index = to_undirected(graph.edge_index, num_nodes=num_nodes)

    return graph

本次实验的数据集采用伊斯坦布尔股票交易数据集:ISTANBUL STOCK EXCHANGE - UCI Machine Learning Repository

最终构建出的图结构为:

step2:在接下来的训练、验证以及测试过程中保持图的整体结构不变。也就是使用静态图,即图中的关系是通过训练集中的数据确定的。如果想要实现动态图,一个很自然的想法是在构造数据集时,每次都利用一个大小为(num_nodesseq_len)的矩阵计算出图中的各个参数。这样操作后每一个样本都对应一个图,图中的节点数为num_nodes,节点的初始特征都为长度为seq_len的向量,图中的边通过num_nodes个长度为seq_len的向量间的相关系数来确定。

构造数据集:

def nn_seq(num_nodes, seq_len, B, pred_step_size, data):
    # 将数据集划分为训练集(60%)、验证集(20%)和测试集(20%)
    train = data[:int(len(data) * 0.6)]
    # print(train)
    val = data[int(len(data) * 0.6):int(len(data) * 0.8)]
    # print(val)
    test = data[int(len(data) * 0.8):len(data)]
    # print(test)

    # 归一化
    scaler = MinMaxScaler()
    train_normalized = scaler.fit_transform(data[:int(len(data) * 0.8)].values)
    # print(train_normalized)
    val_normalized = scaler.transform(val.values)
    # print(val_normalized)
    test_normalized = scaler.transform(test.values)
    # print(test_normalized)

    # 创建训练集(包含测试集)图
    graph = create_graph(num_nodes, data[:int(len(data) * 0.8)].values)

    # 数据集处理(生成样本和标签)
    # step_size:每一步的步长;shuffle:是否打乱数据
    def process(dataset, batch_size, step_size, shuffle):
        # 将数据集由DataFrame转化为列表
        dataset = dataset.tolist()
        # print(len(dataset), len(dataset[0]))
        # 创建样本序列
        seq = []
        # 遍历训练数据集,直到最后一个滑动窗口和预测步长前
        for i in tqdm(range(0, len(dataset) - seq_len - pred_step_size, step_size)):
            # 创建训练序列
            train_seq = []
            # 遍历每一个滑动窗口
            for j in range(i, i + seq_len):
                # 获取一个滑动窗口的样本
                x = []
                for c in range(len(dataset[0])):
                    x.append(dataset[j][c])
                train_seq.append(x)
                # print(x)
            # 获取一个滑动窗口的标签
            train_labels = []
            for j in range(len(dataset[0])):
                train_label = []
                for k in range(i + seq_len, i + seq_len + pred_step_size):
                    train_label.append(dataset[k][j])
                train_labels.append(train_label)
            # 得到每一个滑动窗口的训练样本与对应的标签,转化为tensor
            train_seq = torch.FloatTensor(train_seq)
            train_labels = torch.FloatTensor(train_labels)
            # print(train_seq.shape, train_labels.shape)
            seq.append((train_seq, train_labels))

        seq = MyDataset(seq)
        seq = DataLoader(dataset=seq, batch_size=batch_size, shuffle=shuffle, num_workers=0, drop_last=False)

        return seq

    # 得到每个数据集的DataLoader
    Dtr = process(train_normalized, B, step_size=1, shuffle=True)
    Val = process(val_normalized, B, step_size=1, shuffle=True)
    Dte = process(test_normalized, B, step_size=pred_step_size, shuffle=False)

    return graph, Dtr, Val, Dte, scaler

运行后得到训练集的图结构,并将其数据与邻接矩阵加入后续的模型训练:

函数最后返回训练集,验证集和测试集的DataLoader(Dtr,Val,Dte)以及得到的归一化参数(scaler),加入后续模型的训练(注意:本次实验进行的是多步预测,预测下一个月的股票交易数据):

step3:定义预测模型。这里使用GAT(图注意力网络),也可以换成GCNGraphSAGE等其他的模型。

class GAT(nn.Module):
    def __init__(self, in_features, h_features, out_features):
        super(GAT, self).__init__()
        self.conv1 = GATConv(in_features, h_features, heads=4, concat=False)
        self.conv2 = GATConv(h_features, out_features, heads=4, concat=False)

    def forward(self, x, edge_index):
        x = F.elu(self.conv1(x, edge_index))
        x = self.conv2(x, edge_index)

        return x

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/504969.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【论文阅读】UniLog: Automatic Logging via LLM and In-Context Learning

注 由于其公司的保密政策,本文没有公开源代码,数据是公开的。 文章目录 摘要一、介绍二、背景和动机2.1、日志语句生成2.2、大语言模型2.3、上下文学习(In-Context Learning,ICL) 三、UNILOG3.1、模型骨干3.2、提示策略3.2.1、提…

大龄程序员的2024年3月总结:鸿蒙,发起GDE申请,金石计划获奖,月榜,技术文章

大家好,我是老A,一名工作十年的安卓开发; 又到了月末写总结的时候了,看过我文章的朋友应该会发现我没有写2月的总结,因为2月有春节假期,2月大部分时间都是在假期中度过的,所以就没有写2月总结&…

瓷砖通铺选择亮面还是哑光?了解这6点不难选。福州中宅装饰,福州装修

选择瓷砖通铺亮面还是哑光,可以从多个角度来考虑: ①空间感觉 亮面瓷砖通常会使空间看起来更加宽敞和明亮,而哑光瓷砖则给人大气、稳重的感觉。如果希望让空间显得更加宽敞,亮面瓷砖是一个不错的选择。 ②清洁与维护 亮面瓷砖更…

KNN算法 | K近邻:KD Tree、球树、KNN数据下采样策略

目录 一. KNN算法实现方式1. 蛮力实现(brute)2. KD树(kd_tree)3. 球树(ball_tree) 二. KD Tree算法1. 构建方式2. KD Tree 查找最近邻 三. 球树(Ball Tree)1. 构建方式 四. KNN评价1. 优点2. 缺点 五. 延申1. KNN数据下采样策略策略1策略2策略3策略4 Condensed Nearest Neighbo…

loadbalancer 引入与使用

在消费中pom中引入 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId> </dependency> 请求调用加 LoadBalanced 注解 进行服务调用 默认负载均衡是轮训模式 想要切换…

OpenStack部署

目录 一、安装环境 1.无网络使用该命令 2.修改主机名 3.配置hosts解析 4.配置本机免密 5.关闭防火墙和SElinux策略 6.关闭NewworkManager 7.修改yum源 7.1下载阿里源 7.2清空并加载缓存yum源 8.安装基本工具 9.系统升级 10.安装OPenStack的yum仓库 11.修改OPenSt…

Verilog语法之assign语句学习

assign语法主要是对组合逻辑的变量进行赋值的&#xff0c;就是把一个变量赋值给另一个变量&#xff0c;被复制的变量必须是wire类型的参数。 从仿真结果可以看出&#xff0c;data_in变量的值赋值给了data_out,assign语法就是赋值没有任何延迟&#xff0c;data_in是什么值&#…

数据结构--单链表(c语言实现)

一.单链表的设计 1.单链表的结构定义: typedef struct Node{int data;//数据域struct Node* next;//后继指针 }Node,*List; 2.单链表的设计示意图: 3.注意,单链表的最后一个节点的next域为NULL; 4.为什么要有一个头节点?(简单方便,不用传二级指针); 二.单链表的实现 //初始化 …

web练习仿小米页面

效果图&#xff1a; HTML代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document…

车载电子电器架构 —— 通信信号数据库开发

车载电子电器架构 —— 信号数据库开发 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自…

rocketmq管理工具rocketmq-console安装

rocketmq-console是一个图形化管理控制台&#xff0c;提供Broker集群状态查看&#xff0c;Topic管理&#xff0c;Producer、Consumer状态展示&#xff0c;消息查询等常用功能&#xff0c;这个功能在安装好RocketMQ后需要额外单独安装、运行。 中文文档地址&#xff1a;https:/…

Java中的多线程和线程安全问题

线程 线程是操作系统进行调度的最小单位。一个进程至少包含一个主线程&#xff0c;而一个线程可以启动多个子线程。线程之间共享进程的资源&#xff0c;但也有自己的局部变量。多线程程序和普通程序的区别&#xff1a;每个线程都是一个独立的执行流&#xff1b;多个线程之间是…

C++模板进阶操作 —— 非类型模板参数、模板的特化以及模板的分离编译

非类型模板参数 模板参数可分为类型形参和非类型形参。类型形参&#xff1a; 出现在模板参数列表中&#xff0c;跟在class或typename关键字之后的参数类型名称。非类型形参&#xff1a; 用一个常量作为类&#xff08;函数&#xff09;模板的一个参数&#xff0c;在类&#xff…

【 书生·浦语大模型实战营】学习笔记(一):全链路开源体系介绍

&#x1f389;AI学习星球推荐&#xff1a; GoAI的学习社区 知识星球是一个致力于提供《机器学习 | 深度学习 | CV | NLP | 大模型 | 多模态 | AIGC 》各个最新AI方向综述、论文等成体系的学习资料&#xff0c;配有全面而有深度的专栏内容&#xff0c;包括不限于 前沿论文解读、…

汇编语言——用INT 21H 的A号功能,输入一个字符串存放在内存,倒序输出

用INT 21H 的A号功能&#xff0c;输入一个字符串“Hello, world!”&#xff0c;存放在内存&#xff0c;然 后倒序输出。 在DOS中断中&#xff0c;INT 21H是一个常用的系统功能调用中断&#xff0c;它提供了多种功能&#xff0c;其中A号功能用于字符串的输入。 在使用这个功能时…

OSCP靶场--Internal

OSCP靶场–Internal 考点(CVE-2009-3103) 1.nmap扫描 ## ┌──(root㉿kali)-[~/Desktop] └─# nmap 192.168.216.40 -sV -sC -Pn --min-rate 2500 -p- Starting Nmap 7.92 ( https://nmap.org ) at 2024-03-31 07:00 EDT Nmap scan report for 192.168.216.40 Host is up…

pymysql进行数据库各项基础操作

目录 1、mysql数据库简介2、基于mysql数据库的准备工作3、通过pymysql进行表的创建4、通过pymysql进行数据插入5、通过pymysql进行数据修改6、通过pymysql进行数据查询7、通过pymysql进行数据删除 本文内容是通过pymysql来进行时数据库的各项基础操作。 1、mysql数据库简介 …

西南交大swjtu算法实验4.2|分治

1. 实验目的 编写一个分治算法来搜索 m*n 矩阵 matrix 中的一个目标值 target&#xff0c;该矩阵 具有以下特性:每行的元素从左到右升序排列。每列的元素从上到下升序排列。 通过该实例熟悉分治算法的分析求解过程&#xff0c;时间复杂度分析方法&#xff0c;以及如何设计 分治…

基于深度学习的图书管理推荐系统(python版)

基于深度学习的图书管理推荐系统 1、效果图 1/1 [] - 0s 270ms/step [13 11 4 19 16 18 8 6 9 0] [0.1780757 0.17474999 0.17390694 0.17207369 0.17157653 0.168248440.1668652 0.16665359 0.16656876 0.16519257] keras_recommended_book_ids深度学习推荐列表 [9137…

ES6 学习(一)-- 基础知识

文章目录 1. 初识 ES62. let 声明变量3. const 声明常量4. 解构赋值 1. 初识 ES6 ECMAScript6.0(以下简称ES6)是JavaScript语言的下一代标准&#xff0c;已经在2015年6月正式发布了。它的目标&#xff0c;是使得」JavaScript语言可以用来编写复杂的大型应用程序&#xff0c;成为…