python基于GCN(图卷积神经网络模型)和LSTM(长短期记忆神经网络模型)开发构建污染物时间序列预测模型

在以往的时间序列预测建模中广泛使用的是回归类算法模型和RNN类的算法模型,相对来说技术栈会更稳定一些,最近有一个实际业务场景的需求,在建模的过程中要综合考虑其余点位的影响依赖,这时候我想到了之前做过的交通流量和速度预测相关的项目,在那里采用的就是图相关的算法模型,所以这里也想对标来开发。

GCN(Graph Convolutional Network)是一种用于处理图结构数据的卷积神经网络模型。它的构建原理是基于图卷积操作,通过在图上进行局部的卷积运算来提取节点的特征表示。

具体来说,GCN通过邻居节点的信息聚合来更新每个节点的表示。GCN的每一层都可以表示为以下的公式:

H^{(l+1)} = σ(D^{-0.5}AD^{-0.5}H^{(l)}W^{(l)})

其中,H^{(l)}表示第l层的节点表示矩阵,A表示节点之间的邻接矩阵,D是度矩阵,W^{(l)}表示第l层的权重矩阵,σ表示激活函数。

GCN的优点主要体现在以下几个方面:

  1. 考虑了节点的邻居信息:GCN通过聚合节点的邻居信息来更新节点的表示,能够捕捉到节点的局部结构信息,适用于处理图结构数据。
  2. 具有共享权重的卷积:GCN通过共享权重矩阵来进行卷积操作,减少了需要学习的参数数量,降低了模型的复杂度。
  3. 良好的泛化能力:GCN能够将节点的特征向量传递给邻居节点,从而在整个图上进行信息传播,有助于节点的特征表示学习。

然而,GCN也存在一些缺点:

  1. 无法处理动态图:GCN对于静态图结构的处理效果较好,但对于动态图的处理存在一定的困难,因为动态图的结构会随着时间的推移而变化。
  2. 局部邻居信息的限制:GCN只考虑节点的一阶邻居信息,对于高阶邻居信息的利用能力有限。
  3. 对大规模图的计算开销较大:GCN的计算复杂度与图的规模相关,对于大规模图的处理需要较高的计算资源。

GCN作为一种处理图结构数据的卷积神经网络模型,具有考虑邻居信息、共享权重、泛化能力强等优点,但对动态图的处理存在限制,并且对大规模图的计算开销较大。

LSTM(Long Short-Term Memory)是一种用于处理序列数据的循环神经网络模型。它的构建原理是通过引入门控机制来解决传统RNN存在的梯度消失和梯度爆炸问题,从而能够更好地捕捉长期依赖关系。

具体来说,LSTM通过三个门控单元(输入门、遗忘门和输出门)来控制信息的流动和记忆的更新。它的计算过程可以表示为以下公式:

输入门:i_t = σ(W_{xi}x_t + W_{hi}h_{t-1} + b_i)
遗忘门:f_t = σ(W_{xf}x_t + W_{hf}h_{t-1} + b_f)
输出门:o_t = σ(W_{xo}x_t + W_{ho}h_{t-1} + b_o)
新的记忆:\tilde{c}t = tanh(W{xc}x_t + W_{hc}h_{t-1} + b_c)
细胞状态更新:c_t = f_t \odot c_{t-1} + i_t \odot \tilde{c}_t
隐藏状态更新:h_t = o_t \odot tanh(c_t)

其中,i_t、f_t和o_t分别表示输入门、遗忘门和输出门的输出,\tilde{c}_t表示新的记忆,c_t表示细胞状态,h_t表示隐藏状态,x_t表示当前时刻的输入。

LSTM的优点主要体现在以下几个方面:

  1. 解决了梯度消失和梯度爆炸问题:通过门控机制,LSTM能够有效地捕捉长期依赖关系,解决了传统RNN在处理长序列时产生的梯度问题。
  2. 长期记忆能力强:LSTM能够在细胞状态中长期存储信息,有助于模型记住对当前任务有用的信息。
  3. 能够处理不定长的序列:LSTM可以处理不定长的序列数据,适用于多种应用场景,如自然语言处理、语音识别等。

然而,LSTM也存在一些缺点:

  1. 计算复杂度较高:LSTM中引入了多个门控单元和记忆单元,导致模型的计算复杂度较高,对计算资源要求较大。
  2. 可能存在过拟合:LSTM的参数数量较多,模型容易过拟合,需要采取一些正则化方法来缓解这个问题。
  3. 难以并行化:LSTM的计算过程涉及到门控单元的计算,导致模型难以进行有效的并行化,限制了其在大规模数据上的应用。

LSTM作为一种用于处理序列数据的循环神经网络模型,具有解决梯度问题、长期记忆能力强等优点,但计算复杂度较高、难以并行化等缺点。

这里本文的核心思想是想要基于GCN+LSTM来实现图网络和时序网络的融合,开发构建更加适合业务需求的时间序列预测模型。

首先是数据集加载,如下所示:

with open("distance.json") as f:
    route_distances = json.load(f)
with open("nodedata.json") as f:
    speeds_array = json.load(f)
route_distances = np.array(route_distances)
speeds_array = np.array(speeds_array)
print(f"route_distances shape={route_distances.shape}")
print(f"speeds_array shape={speeds_array.shape}")

结果输出如下所示:

route_distances shape=(23, 23)
speeds_array shape=(1056, 23)

共包含了23个节点。

之后是创建邻接矩阵,如下:

num_routes = route_distances.shape[0]
route_distances = route_distances / 10000
w2, w_mask = (
    route_distances * route_distances,
    np.ones([num_routes, num_routes]) - np.identity(num_routes),
)
adjacency_matrix = (np.exp(-w2 / sigma2) >= epsilon) * w_mask

结果输出如下所示:

一个简单的GCN+LSTM实现如下所示:

def gcn_layer(adj_matrix, input_features, output_dim):
    # GCN层的实现
    adj_normalized = normalize_adj(adj_matrix) # 对邻接矩阵进行归一化处理
    output = Dense(output_dim)(adj_normalized @ input_features) # GCN的公式实现
    output = Activation('relu')(output)
    return output

# 构建GCN+LSTM模型
def build_gcn_lstm_model(adj_matrix, input_dim, hidden_dim, output_dim):
    # 输入层
    inputs = Input(shape=(None, input_dim))
    
    # GCN层
    gcn_output = gcn_layer(adj_matrix, inputs, hidden_dim)
    
    # LSTM层
    lstm_output = LSTM(hidden_dim)(gcn_output)
    
    # 输出层
    outputs = Dense(output_dim, activation='softmax')(lstm_output)
    
    model = Model(inputs=inputs, outputs=outputs)
    model.compile(optimizer=Adam(lr=0.001), loss='categorical_crossentropy', metrics=['accuracy'])
    
    return model

也可以自己定义新的layer都是可以的,如下:

class GCNLSTM(layers.Layer):

    def __init__(**kwargs):
        super().__init__(**kwargs)
        self.graph_conv = gcnLayer(in_feat, out_feat, graph_info, **graph_conv_params)
        self.lstm = layers.LSTM(lstm_units, activation="relu")
        self.dense = layers.Dense(output_seq_len)
        self.input_seq_len, self.output_seq_len = input_seq_len, output_seq_len

    def get_config(self):
        config = super().get_config().copy()
        return config

    def call(self, inputs):
        inputs = tf.transpose(inputs, [2, 0, 1, 3])
        gcn_out = self.graph_conv(inputs) 
        shape = tf.shape(gcn_out)
        gcn_out = tf.reshape(gcn_out, (batch_size * num_nodes, input_seq_len, out_feat))
        lstm_out = self.lstm(gcn_out) 
        dense_output = self.dense(lstm_out) 
        output = tf.reshape(dense_output, (num_nodes, batch_size, self.output_seq_len))
        return tf.transpose(output, [1, 2, 0]) 

之后就可以进行模型的训练了如下:

history=model.fit(X_train,y_train,validation_data=(X_test,y_test),epochs=200)
model.save("model.h5")
plotLoss(history.history["loss"],history.history["val_loss"],"loss.png")

loss可视化如下所示:

这里我们随机选取了几个node对其数据进行可视化,如下所示:

node之间的热力图如下所示:

对测试集进行测试评估,对比曲线可视化结果如下所示:

这里对不同node未来时刻进行持续预测,分别展示,如下所示:

这是一种比较新的建模方式,在实际应用中可以更多捕捉到不同节点的依赖性,这个是比较有用的一点,后续会在实际应用过程中继续挖掘。

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

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

相关文章

全国第一届学生(青年)运动会女子拳击比赛60公斤冠军载誉归来

11月16日,参加全国第一届学生(青年)运动会女子拳击比赛60公斤冠军阿依古再丽麦合苏提抵达和田。 中华人民共和国第一届学生(青年)运动会拳击比赛11月12日在广西贺州市钟山县体育馆落下帷幕,本届比赛新疆拳击…

60V降压恒流芯片 高调光比LED驱动器 SL6015B替代PT4115 电路简单

在LED照明领域,降压恒流芯片是一种非常重要的芯片,它可以将输入的电压降低并输出稳定的电流,从而为LED灯提供合适的驱动电源。其中,SL6015B是一款非常优秀的降压恒流芯片,它具有高调光比、简单的电路设计、低成本的优点…

服务案例|故障频发的一周,居然睡得更香!

医院运维有多忙? 医院运维,听起来平平无奇毫不惊艳,但其中的含金量,可不是“维持系统正常运行”就能总结的。毕竟医院对业务连续性的超高要求,让运维面对的问题都是暂时的,下一秒可能就有新问题需要发现解…

一般人用 Linux 算是找虐吗?

一般人用 Linux 算是找虐吗? 主要得看用什么Linux,毕竟Android也算是Linux,满大街一般人整天在用,也没什么人觉得自己在找虐。 最近很多小伙伴找我,说想要一些Linux的资料,然后我根据自己从业十年经验&…

【Linux】:进程间通信和日志模拟

进程间通信 一.基本概念二.简单的通信-管道(匿名管道)1.建立通信信道2.通信接口 三.命名管道三.模拟命名管道通信(加上日志)1.完整代码2.基本使用 一.基本概念 是什么 两个或多个进程实现数据层面的交互。 因为进程独立性的存在,导致进程间…

spark shuffle 剖析

ShuffleExchangeExec private lazy val writeMetrics SQLShuffleWriteMetricsReporter.createShuffleWriteMetrics(sparkContext)private[sql] lazy val readMetrics SQLShuffleReadMetricsReporter.createShuffleReadMetrics(sparkContext)用在了两个地方,承接的是…

禁止安装新软件怎么设置(超详细图文介绍)

很多公司的网管向我们反应,总是有员工随意下载软件,并且不去正规网站、正规官网下载,导致公司的电脑总是又卡又慢,网管的工作很难开展。 此时就需要对公司安装软件的情况,进行统一管控了。 方法一:适合个人…

Git - 版本控制系统

目录 一、概述 配置用户信息 二、Git仓库 创建 本地仓库 git的三个区域 示例 Git文件状态 举例 三、区域使用 暂存区使用 版本库使用 文件忽略 四、分支 步骤 合并与删除 步骤 合并与提交 合并冲突 五、常用指令 六、Git远程仓库 使用步骤 克隆 同步 …

一键合并多个TXT文本,将保存在TXT的快递单号进行一键合并

如果你需要处理大量的TXT文本文件,那么你可能会遇到需要将这些文件合并为一个文件的情况。这不仅涉及到文件的组织和管理,还可能涉及到文件内容的连贯性和完整性。现在,我们有一个强大的工具,可以帮助你轻松实现一键文件整理&…

身份证号码校验

根据《新版外国人永久居留身份证适配性改造要点》,公司需要把代码中对身份证的校验进行优化 就文档内容可以看到需要优化的要点是: 新版永居证号码以 9 开头 受理地区代码出生日期顺序码校验码;(共18位) eg&#xff…

2023年约特干故城夜间演艺《万方乐奏有于阗》完美谢幕

11月19日,记者走进约特干故城看到演员在欢乐地跳着刀郎舞和古典舞,庆祝今年以来夜间演艺《万方乐奏有于阗》演出200场完美谢幕。 11月19日在约特干故城,演员正在表演迎宾乐舞。阿卜力克木依卜拉依木摄 当天晚上,城楼上旌旗猎猎&am…

Transmit v5.10.3(FTP客户端)

Transmit 5是一款由Panic开发的功能强大的FTP(文件传输协议)客户端软件,专为 macOS 平台设计。它提供了简单、直观的界面和丰富的功能,使用户能够轻松地管理和传输文件。 在文件传输和同步方面,Transmit 5提供了强大的文件同步功能&#xff…

18张值得收藏的高清卫星影像

这里分享的18张高清卫星影像,由吉林一号卫星拍摄。 原图来自长光卫星嘉宾在直播中分享的PPT演示文档。 18张高清卫星影像 吉林一号高分04A星,于2022年05月21日拍摄的北京紫禁城高清卫星影像。 北京紫禁城 云南昆明滇池国际会展中心高清卫星影像&…

【STM32外设系列】JW01三合一空气质量检测模块

🎀 文章作者:二土电子 🌸 关注公众号获取更多资料! 🐸 期待大家一起学习交流! 文章目录 一、JW01模块简介二、数据格式介绍三、程序设计3.1 串口初始化3.2 串口接收中断服务函数3.3 数据解析函数 四、其他…

思福迪 运维安全管理系统 test_qrcode_b 远程命令执行漏洞

思福迪 运维安全管理系统 test_qrcode_b 远程命令执行漏洞 一、漏洞描述二、漏洞影响三、网络测绘四、漏洞复现1.手动复现2.自动化复现3.python源代码 免责声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任…

OOM问题排查+Jvm优化

OOM问题排查: 1、top命令:查看cpu和内存的使用情况。 2、jstat命令:查看YGC和FGC情况,一般都是老年代不够用。导致OOM 3、jmap命令: 查看哪个类的实例过多,以每个类占用多少了内存。4、jstack 查看线程与线程之间的阻…

【广州华锐互动】昆虫3D虚拟动态展示:探索神奇的微观世界

在这个充满科技魅力的时代,我们可以通过各种方式去了解和探索自然界的奥秘。而昆虫作为地球上最为丰富多样的生物群体之一,其独特的生活习性和形态特征一直吸引着人们的目光。 由广州华锐互动开发的昆虫3D虚拟动态展示系统,成为了一种全新的科…

原始类型 vs. 对象(基本类型 vs. 引用类型)

原始类型 首先我们先看一段代码: let age 30; let oldAge age; age 31; console.log(age); console.log(oldAge);在 JavaScript 中,原始类型的赋值是通过值复制的方式进行的,而不会相互影响。只有对象类型的值才是通过引用复制的方式进行…

【数据结构(三)】双向链表(2)

文章目录 1. 基本概念2. 管理双向链表的思路3. 代码实现 1. 基本概念 管理单向链表的缺点分析: ①单向链表,查找的方向只能是一个方向,而双向链表可以向前或者向后查找。     ②单向链表不能自我删除,需要靠辅助节点 ,而双向…

基于springboot实现在线外卖平台系统项目【项目源码】

基于springboot实现在线外卖平台管理系统演示 Java技术 Java是由SUN公司推出,该公司于2010年被oracle公司收购。Java本是印度尼西亚的一个叫做爪洼岛的英文名称,也因此得来java是一杯正冒着热气咖啡的标识。Java语言在移动互联网的大背景下具备了显著的…