AGCRN论文解读
一、创新点
传统GCN只能基于静态预定义图建模全局共享模式,而AGCRN通过两种GCN的增强模块(NAPL、DAGG)实现了更精细的节点特性学习和图结构生成。

1 节点自适应参数学习模块(NAPL)
传统GCN通过共享参数(权重和偏置)在所有节点上执行图卷积操作,这样只能考虑到邻近节点间的空间相关性。然而在交通序列中,还因时间序列的动态特性和节点的多种影响因素(例如兴趣点、天气)而表现出多样性模式。
因此,传统的图卷积公式必须作出如下变换。将权重 Θ 分解为两个更小的权重矩阵。其中EG代表节点嵌入矩阵,它为每个节点提供了一个区分性的表示,使得模型能够识别节点间的差异。WG是一个共享的权重池,包含了所有节点共享的候选特征模板,由节点嵌入EG确定哪些模板最适合每个节点。

这么讲非常抽象晦涩!!!作者据说受到了矩阵分解的启发,也许可以从这方面入手理解。Θ 是三维矩阵(节点N,输入特征C,输出特征F),这时一个节点对应死了一个权重值。如果把第0维和第1维中间拦腰斩断,插入一个索引维度d,那么就分解出了EG(节点N,索引d)和WG(索引d,输入特征C,输出特征F)。因此,每个节点 Ni 就能通过索引 di 在权重池子里找到适合自己的那个权重。这种生成方式允许节点共享一个全局权重池,同时保留节点特定性。代码如下:
self.node_embeddings = nn.Parameter(torch.randn(self.num_node, args.embed_dim), requires_grad=True)self.weights_pool = nn.Parameter(torch.FloatTensor(embed_dim, cheb_k, dim_in, dim_out))
self.bias_pool = nn.Parameter(torch.FloatTensor(embed_dim, dim_out))weights = torch.einsum('nd,dkio->nkio', node_embeddings, self.weights_pool) #N, cheb_k, dim_in, dim_out
bias = torch.matmul(node_embeddings, self.bias_pool)
那么到底改进了什么?
- 在GCN中,一个权重矩阵 Θ 就能处理所有节点的特征,不管每个节点今天刮风下雨还是有车祸。而在NAPL中,每个节点都有选择自己权重矩阵的权力。这样模型针对不同的节点才会预测得更加精准。
- 如果每个节点都有多个不同的权重矩阵,而不是共享一个权重池。那样会导致模型过于复杂,徒增计算资源。
因此NAPL是一个很折中的办法!
2 数据自适应图生成(DAGG)
在传统的基于GCN的交通预测模型中需要预定义的邻接矩阵 A 以进行图卷积操作。而预定义的图无法包含完整的空间依赖信息,也无法直接与预测任务相关联。
有两点原因:首先,两条物理上相邻的道路可能由于单行道或隔离带而没有直接的交通交互。某条道路因为施工或重大活动会突然变得与其他道路关联更强。其次,构建预定义图通常需要依赖领域专家的知识,而且需要大量人力来设计和验证图的质量。
因此,作者提出了数据自适应图生成(DAGG)模块。这个模块首先基于输入数据(如交通流量或速度)为所有节点随机初始化一个可学习的节点嵌入字典 EA ,是一个二维矩阵(节点数量N,嵌入维度d)。通过 EA 和其转置矩阵相乘即可得到节点之间的内积相似度矩阵,即新的邻接矩阵。这是为什么?

首先,内积的本质就是用来衡量两个向量的相似性。两个向量方向相同,且相似性越大,内积就会越大。当两个向量垂直时,内积为0;方向相反,内积为负。而EA 的第 i 行和其转置矩阵的第 i 列是同一向量,那么 EA 的 i 行与其转置矩阵的 i+1 列相乘得到的结果就代表,第 i 个节点和 第 i+1 个节点的相似度。因此,逐行逐列相乘后就可以得到一个 N 行 N 列的邻接矩阵。
下面是作者的实现代码,node_embeddings 就是上图的 EA 矩阵。
# AGCRN.py 中的代码
self.node_embeddings = nn.Parameter(torch.randn(self.num_node, args.embed_dim), requires_grad=True)# AGCN.py 中的代码
supports = F.softmax(F.relu(torch.mm(node_embeddings, node_embeddings.transpose(0, 1))), dim=1)
不过,自适应图生成的生成并不是作者的首创,早在2019年的 Graph WaveNet 论文(Graph WaveNet for Deep Spatial-Temporal Graph Modeling)中就提出过类似的方法,叫做自适应邻接矩阵。本篇论文是 2020 年的,不管是查看论文还是代码,可以发现就是说的一个东西。。。
二、自适应图卷积递归网络(AGCRN)
作者讲上述两个模块与 GRU 结合起来可以得到:

在前文中,可以得到图卷积 Z,再将 Z 提取为更新门 z 和重置门 r,那么我们就可以计算出候选状态以及最终输出 h。代码如下:
state = state.to(x.device) # 确保 state 与输入 x 在相同设备(如 GPU)上
input_and_state = torch.cat((x, state), dim=-1) # 将当前输入 x 和隐藏状态 state 沿特征维度拼接
z_r = torch.sigmoid(self.gate(input_and_state, node_embeddings))
z, r = torch.split(z_r, self.hidden_dim, dim=-1)
candidate = torch.cat((x, z*state), dim=-1)
hc = torch.tanh(self.update(candidate, node_embeddings))
h = r*state + (1-r)*hc
return h
三、实验
作者使用了 PeMSD4 和 PeMSD8 数据集,其中训练集、验证集和测试集的划分比例为 6:2:2。将 12 步的历史数据作为输入,接下来的 12 步数据作为输出。
3.1 消融实验
同时,作者为了更好地评估 NAPL 和 DAGG 的性能,还进行了全面的消融实验。分别对比了如下几组实验:
- GCGRU:传统的 GCN ;
- NAPL-GCGRU:将传统的 GCN 替换为我们提出的 NAPL-GCN;
- DAGG-GCGRU:将预定义图替换为 DAGG 模块;
- AGCRN-I:不统一节点嵌入,而是在不同的 NAPL-GCN 层和 DAGG 中使用独立的节点嵌入矩阵。
- AGCRN:作者的模型。
其中作者提到了节点嵌入,是指在模型中使用统一的节点嵌入向量来表示不同模块或层之间的节点特性。这意味着,在 AGCRN 中,节点的嵌入向量在整个模型中是共享的,而不是为每个模块分别学习不同的嵌入。 查看代码,也可以发现整个项目只有一个 node_embeddings。
下图为作者的测试结果。可以发现NAPL在短期预测时表现不佳。这是因为短期预测(例如 5 分钟或 15 分钟的预测)通常能从已有的历史数据中获得足够的信息,所以不太依赖于节点特定的嵌入(即 NAPL 学到的每个节点的特性)。换句话说,短期预测可以依赖于前几个时间步的交通数据,而不需要太多的额外个性化特征。然而长期预测(例如 30 分钟或 60 分钟的预测)则面临更大的不确定性,因为历史数据可能无法充分预测未来的变化。这时,NAPL 所学习的节点特定嵌入变得尤为重要,因为它能帮助模型更好地捕捉每个节点的独特模式(例如道路的特殊流量模式、影响因素等),从而提高对长期预测的准确性。

3.2 图生成过程分析
在上述的图卷积的公式中,还有一个单位矩阵 I。它的作用是保持每个节点的自信息,即让节点的当前特征在计算中不被忽视。这就类似于一个节点在做预测时不考虑自己的历史数据,只依赖邻居节点的状态,可能导致信息丢失或不准确。因此,作者对自适应图生成(DAGG)做了两个变种,即不使用单位矩阵的 DAGG-r 和 不使用生成的图拉普拉斯矩阵的 DAGG-2。
由下表可以看出,如果不使用单位矩阵,那么效果会大打折扣。但是不使用图生成的拉普拉斯矩阵(预定义图),效果并没有很大差距。

最后,作者还考虑了嵌入维度对实验的影响。发现嵌入维度为10时效果最好。


本论文的PeMSD4数据集运行结果如下:
2024-12-07 06:19: Total training time: 25.8792min, best loss: 19.460032
2024-12-07 06:19: Horizon 01, MAE: 18.68, RMSE: 30.26, MAPE: 12.5175%
2024-12-07 06:19: Horizon 02, MAE: 18.78, RMSE: 30.61, MAPE: 12.5259%
2024-12-07 06:19: Horizon 03, MAE: 18.98, RMSE: 31.03, MAPE: 12.6548%
2024-12-07 06:19: Horizon 04, MAE: 19.22, RMSE: 31.49, MAPE: 12.8187%
2024-12-07 06:19: Horizon 05, MAE: 19.50, RMSE: 31.96, MAPE: 13.0233%
2024-12-07 06:19: Horizon 06, MAE: 19.77, RMSE: 32.41, MAPE: 13.2145%
2024-12-07 06:19: Horizon 07, MAE: 20.01, RMSE: 32.82, MAPE: 13.3573%
2024-12-07 06:19: Horizon 08, MAE: 20.20, RMSE: 33.19, MAPE: 13.4612%
2024-12-07 06:19: Horizon 09, MAE: 20.38, RMSE: 33.54, MAPE: 13.5726%
2024-12-07 06:19: Horizon 10, MAE: 20.59, RMSE: 33.93, MAPE: 13.7235%
2024-12-07 06:19: Horizon 11, MAE: 20.93, RMSE: 34.43, MAPE: 13.9569%
2024-12-07 06:19: Horizon 12, MAE: 21.45, RMSE: 35.11, MAPE: 14.3262%
2024-12-07 06:19: Average Horizon, MAE: 19.87, RMSE: 32.60, MAPE: 13.2627%

相关文章:
AGCRN论文解读
一、创新点 传统GCN只能基于静态预定义图建模全局共享模式,而AGCRN通过两种GCN的增强模块(NAPL、DAGG)实现了更精细的节点特性学习和图结构生成。 1 节点自适应参数学习模块(NAPL) 传统GCN通过共享参数(权重…...
Python机器学习笔记(五、决策树集成)
集成(ensemble)是合并多个机器学习模型来构建更强大模型的方法。这里主要学习两种集成模型:一是随机森林(random forest);二是梯度提升决策树(gradient boosted decision tree)。 1…...
Kafka单机及集群部署及基础命令
目录 一、 Kafka介绍1、kafka定义2、传统消息队列应用场景3、kafka特点和优势4、kafka角色介绍5、分区和副本的优势6、kafka 写入消息的流程 二、Kafka单机部署1、基础环境2、iptables -L -n配置3、下载并解压kafka部署包至/usr/local/目录4、修改server.properties5、修改/etc…...
如何使用 Python 实现链表的反转?
在Python中实现链表的反转可以通过几种不同的方法。这里,我将向你展示如何使用迭代和递归两种方式来反转链表。 1. 迭代方法 迭代方法是通过遍历链表,逐个节点地改变其指向来实现反转的。 class ListNode: def __init__(self, val0, nextNone): …...
react跳转传参的方法
传参 首先下载命令行 npm react-router-dom 然后引入此代码 前面跳转的是页面 后面传的是你需要传的参数接参 引入此方法 useLocation():这是 react-router-dom 提供的一个钩子,用于获取当前路由的位置对象location.state:这是从其他页面传…...
Scala:正则表达式
object test03 {//正则表达式def main(args: Array[String]): Unit {//定义一个正则表达式//1.[ab]:表示匹配一个字符,或者是a,或者是b//2.[a-z]:表示从a到z的26个字母中的任意一个//3.[A-Z]:表示从A到Z的26个字母中的任意一个//4.[0-9]:表示从0到9的10…...
【数电】常见时序逻辑电路设计和分析
本文目的:一是对真题常考题型总结,二是对常见时序电路设计方法进行归纳,给后面看这个文档的人留有一点有价值的东西。 1.不同模计数器设计 2.序列信号产生和检测电路 2.1序列信号产生电路 2.1.1设计思路 主要设计思路有三种 1)…...
Spring IOCAOP
Spring介绍 个人博客原地址 Spring是一个IOC(DI)和AOP框架 Sprng的优良特性 非侵入式:基于Spring开发的应用中的对象可以不依赖于Spring的API 依赖注入:DI是控制反转(IOC)最经典的实现 面向切面编程&am…...
Scala中的隐式转换
package qiqiobject qqqqq {//给参数设置一个默认值:如果用户不传入,就使用这个值def sayName(implicit name:String"小花"):Unit{println(s"我叫:$name")}//需求:能够自己设置函数的参数默认值,而不是在代码…...
GESP 2024年12月认证 真题 及答案
CCF GESP第八次认证将于2024年12月7日上午9:30正式开考,1-4级认证时间为上午9:30-11:30,5-8级认证时间为下午13:30-16:30。认证语言包括:C、 Python和图形化编程三种语言,其中C和Python编程为1-8级,图形化编程为1-4级。…...
C++多态性
概念 C中的多态性是面向对象编程的一个重要特征,它允许我们通过一个基类的指针或引用来操作不同派生类的对象。多态性增强了代码的灵活性和可扩展性。主要分为两种类型:编译时多态(静态多态)和运行时多态(动态多态&am…...
PyODBC: Python 与数据库连接的桥梁
PyODBC: Python 与数据库连接的桥梁 介绍 在现代的开发环境中,数据是核心要素之一。几乎所有的应用程序都需要与数据库进行交互。在 Python 中,pyodbc 是一个非常常用的库,它提供了一种简便的方法,通过 ODBC(开放数据…...
专题二十五_动态规划_两个数组的 dp (含字符串数组)_算法专题详细总结
目录 动态规划_两个数组的 dp (含字符串数组) 1. 最⻓公共⼦序列(medium) 解析: 1. 状态表⽰: 2. 状态转移⽅程: 3. 初始化:编辑 4. 填表顺序:编辑 5. 返回值…...
PHP语法学习(第七天)-循环语句,魔术常量
老套路了,朋友们,先回忆昨天讲的内容PHP语法学习(第六天)主要讲了PHP中的if…else语句、关联数组以及数组排序。 想要学习更多PHP语法相关内容点击“PHP专栏!” 下列代码都是在PHP在线测试运行环境中得到的!! 还记得电…...
数据库授权讲解一下
这条 SQL 命令是 MySQL 数据库中用于权限管理的 GRANT 语句。它用于授予用户特定的权限。下面是命令的详细解释: GRANT ALL PRIVILEGES ON *.* TO root% IDENTIFIED BY Zz!12345678 WITH GRANT OPTION;GRANT: 这是一个关键字,用于…...
组件开发的环境准备: nodejs安装,npm镜像源的修改,pnpm包管理器的安装(全局安装),基于pnpm创建脚手架项目
Node.js 是一个开源的、跨平台的 JavaScript 运行环境(本质是Chrome引擎的封装),允许开发者使用 JavaScript 来编写服务器端代码 npm(Node Package Manager)是 Node.js 包管理器, 用来安装各种库、框架和工具 【Node.js官网】 https://nodejs.org 【n…...
学生成绩统计系统
实验内容 问题描述: 输入n个学生的考试成绩,每个学生信息由姓名与分数组成;试设计一种算法: (1)按分数高低次序,打印出每个学生的名次,分数相同的为同一名次; (2)按名次输出每个学生的姓名与分数。 基本要求: (1)学生的考试成绩必须通过…...
【Spring项目】图书管理系统
阿华代码,不是逆风,就是我疯 你们的点赞收藏是我前进最大的动力!! 希望本文内容能够帮助到你!! 目录 一:项目实现准备 1:需求 (1)登录 2:准备…...
Vivado ILA数据导出MATLAB分析
目录 ILA数据导出 分析方式一 分析方式二 有时候在系统调试时,数据在VIVADO窗口获取的信息有限,可结合MATLAB对已捕获的数据进行分析处理 ILA数据导出 选择信号,单击右键后,会有export ILA DATA选项,将其保存成CS…...
【开源免费】基于SpringBoot+Vue.JS高校学科竞赛平台(JAVA毕业设计)
博主说明:本文项目编号 T 075 ,文末自助获取源码 \color{red}{T075,文末自助获取源码} T075,文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...
uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...
毫米波雷达基础理论(3D+4D)
3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文: 一文入门汽车毫米波雷达基本原理 :https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...
Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成
一个面向 Java 开发者的 Sring-Ai 示例工程项目,该项目是一个 Spring AI 快速入门的样例工程项目,旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计,每个模块都专注于特定的功能领域,便于学习和…...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...
