【源码复现】《Towards Deeper Graph Neural Networks》

目录

  • 1、论文简介
  • 2、论文核心介绍
    • 2.1、基本概述
    • 2.2、模型介绍
  • 3、源码复现
    • 3.1、torch复现
    • 3.2、DGL复现

1、论文简介

  • 论文题目——《Towards Deeper Graph Neural Networks》
  • 论文作者——Meng Liu, Hongyang Gao & Shuiwang Ji
  • 论文地址——Towards Deeper Graph Neural Networks
  • 源码——源码链接

2、论文核心介绍

2.1、基本概述

 GCN模型和GAT模型仅仅是减缓了过平滑问题,网络层数并没有达到深层。SGC采用图卷积矩阵的k次幂在单层的神经网络中试图去捕获高阶的邻域信息。PPNP和APPNP用个性化页面排名矩阵取图卷积矩阵克服了过平滑问题。然而这些方法在每一层线性聚合邻域表征,失去了深度非线性架构强大的表达能力,这意味着他们仍然是浅层的网络。那图神经网络真的可以达到深层吗?答案是肯定的!
 本文介绍的DAGNN模型就是解决过平滑问题并使网络加深的一个模型。DAGNN将变换和传播分离,传播k次后,局部邻域和大的邻域信息可以被学习到,通过一个自适应调节机制,平衡局部邻域信息和全局邻域信息。

2.2、模型介绍

 大多数图卷积操作通过邻域信息传播聚合邻域表征,之后实施一个变换操作。普通图卷积的第 l l l层操作可以描述为:
h i ( l ) = PROPAGATION ( l ) ( { x i ( l − 1 ) , { x j l − 1 ∣ j ∈ N i } } ) h_i^{(l)} = \text{PROPAGATION}^{(l)}(\{x_i^{(l-1)},\{x_j^{l-1}|j \in \mathcal{N}_i\}\}) hi(l)=PROPAGATION(l)({xi(l1),{xjl1jNi}})
x i ( l ) = TRANSFORMATION ( l ) ( a i ( l ) )              x_i^{(l)}=\text{TRANSFORMATION}^{(l)}(a_i^{(l)})\;\;\;\;\;\; xi(l)=TRANSFORMATION(l)(ai(l))
 基于上述操作,那存在的问题是什么呢?首先,直觉上,表征变换和表征传播交织在一起,即变换操作中的参数和传播中的感受域交织。一跳邻域需要一个变换函数,那么当考虑到更大的邻域时会需要更多的参数,进而导致很难训练一个具有大量参数的深层图神经网络。其次,再结点分类任务中,一个具有两层的多层感知机不考虑图结构,仅仅使用初始特征 X X X作为输入,也可以达到不错的性能。基于图结构的信息传播则是帮助减轻分类任务,使同一个类的结点表征更相似。因此,从特征和图结构的角度来看,表征变换和表征传播发挥着不同的作用。DAGNN模型则是采用传播和变换分离的策略,得到如下的模型:

Z = MLP ( X )              Z = \text{MLP}(X)\;\;\;\;\;\; Z=MLP(X)
X o u t = softmax ( A ^ k Z )              X_{out} = \text{softmax}(\hat{A}^kZ)\;\;\;\;\;\; Xout=softmax(A^kZ)

 然而,不考虑中间表征,仅仅使用传播k次之后的表征很难获得充分关键的邻域信息,同时也会带来更多的全局信息而稀释了局部的信息,为此,在传播之后,DAGCN采用自适应调节机制来平衡局部邻域信息和全局邻域信息,来决定不同传播层获得的邻域信息有多少应该被保留来生成每个结点的最终表示。DAGNN模型公式描述如下,模型框架如下图所示。
Z = MLP ( X ) Z = \text{MLP}(X) Z=MLP(X)
H l = A ^ Z , l = 1 , 2 , . . . , k H_l= \hat{A}Z,l=1,2,...,k Hl=A^Z,l=1,2,...,k
H = stack ( Z , H 1 , . . . , H k ) H = \text{stack}(Z,H_1,...,H_k) H=stack(Z,H1,...,Hk)
S = σ ( H s ) S = \sigma(Hs) S=σ(Hs)
S ~ = reshape ( S ) \tilde{S} =\text{reshape}(S) S~=reshape(S)
X o u t = softmax ( sqeeze ( S ~ H ) ) X_{out} = \text{softmax}(\text{sqeeze}(\tilde{S}H)) Xout=softmax(sqeeze(S~H))
在这里插入图片描述

3、源码复现

 本节介绍了DAGNN的源码复现,主要将模型的代码放在了下面,如果需要详细的源码,请参看百度云链接。

链接:https://pan.baidu.com/s/1DofAHZbSp5Zf4uKMlriaBA
提取码:6666

3.1、torch复现

import torch
from torch.nn import Module
import torch.nn as nn
from torch.nn.parameter import Parameter
from torch.nn import functional as F

class DAGNN(nn.Module):
    def __init__(self,input_dim,hid_dim,output_dim,model,k,dropout):
        super(DAGNN,self).__init__()

        self.input_dim = input_dim
        self.hid_dim = hid_dim
        self.output_dim = output_dim
        self.model = model
        self.k = k
        self.dropout = dropout
        #法一
        #self.s = Parameter(torch.empty(size=(output_dim,1)))
        #nn.init.xavier_uniform_(self.s.data,gain=1.414)
        #法二
        self.project = nn.Linear(output_dim,1)
        self.init_param()
    def init_param(self):
        #kaiming 初始化
        self.project.reset_parameters()
    def forward(self,feature,adj):
        Z = self.model(feature)

        prop_matrix = [Z]
        for _ in range(self.k):
            Z = torch.mm(adj,Z)
            prop_matrix.append(Z)
        H = torch.stack(prop_matrix,dim=1)
        #S = F.sigmoid(torch.matmul(H,self.s))
        S = F.sigmoid(self.project(H))
        
        #转置
        S = S.transpose(2,1)
        out = torch.squeeze(torch.matmul(S,H))
        return F.log_softmax(out,dim=1)

class MLP(Module):
    def __init__(self,input_dim,hid_dim,output_dim,dropout):
        super(MLP,self).__init__()
        self.input_dim = input_dim
        self.hid_dim = hid_dim
        self.output_dim = output_dim
        self.dropout = dropout
        self.layer1 = nn.Linear(input_dim,hid_dim)
        self.layer2 = nn.Linear(hid_dim,output_dim)
        self.init_param()
    def init_param(self):
        self.layer1.reset_parameters()
        self.layer2.reset_parameters()

    def forward(self,X):
        X = F.dropout(X,self.dropout,training=self.training)
        X = self.layer1(X)
        X = F.relu(X)
        X = F.dropout(X,self.dropout,training=self.training)
        X = self.layer2(X)
        return X
    def __repr__(self) -> str:
        return self.__class__.__name__

3.2、DGL复现

import os
os.environ["DGLBACKEND"] = "pytorch"
import dgl
import dgl.function as fn
import torch 
import torch.nn as nn
import torch.nn.functional as F
from dgl.nn.pytorch.conv import GATConv


class DAGNNLayer(nn.Module):
    def __init__(self,infeat,k) -> None:
        super(DAGNNLayer,self).__init__()
        self.k = k
        self.s = nn.Linear(infeat,1,bias=False)
        self.s.reset_parameters()
    def forward(self,feat,g):
        with g.local_scope():
            results = [feat]

            g = dgl.add_self_loop(g)
            #计算正则
            degs = g.in_degrees().to(feat).clamp(min=1)
            norm = torch.pow(degs,-0.5)
            norm = norm.to(feat.device).unsqueeze(1)
            
            for _ in range(self.k):
                feat = feat * norm
                g.ndata['h'] = feat
                g.update_all(fn.copy_u('h','m'),fn.sum('m','h'))
                feat = g.ndata['h'].to(feat)
                feat = feat * norm
                results.append(feat)

            H = torch.stack(results,dim=1)
            S = F.sigmoid(self.s(H))
            S  = S.permute(0,2,1)
            out = torch.matmul(S,H).squeeze()
            return out

class DAGNN(nn.Module):
    def __init__(self,infeat,hidfeat,outfeat ,dropout,k) -> None:
        super(DAGNN,self).__init__()
        self.dropout = dropout

        self.layer1 = nn.Linear(infeat,hidfeat,bias=False)
        self.layer2 = nn.Linear(hidfeat,outfeat,bias=False)
        self.DAGNNLayer = DAGNNLayer(outfeat,k)
        self.init_param()
    def init_param(self):
        self.layer1.reset_parameters()
        self.layer2.reset_parameters()
    def forward(self,x,g):
        x = F.dropout(x,self.dropout,training=self.training)
        x = F.relu(self.layer1(x))
        x = F.dropout(x,self.dropout,training=self.training)
        x = self.layer2(x)
        x = self.DAGNNLayer(x,g)

        return F.log_softmax(x,dim=1)
    

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

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

相关文章

uni-app 一些实用的页面模板

时间倒计时 <!-- 时间倒计时 --> <template><view class"container"><view class"flex-row time-box"><view class"time-item">{{ laveTimeList[0] }}</view><text>天</text><view class&qu…

Kubernetes实战(十四)-k8s集群扩容master节点

1 Master 高可用架构 Kubernetes 作为容器集群系统&#xff0c;通过健康检查 重启策略实现了 Pod 故障自我修复能力&#xff0c;通过调度算法实现将 Pod 分布式部署&#xff0c;并保持预期副本数&#xff0c;根据 Node 失效状态自动在其他 Node 拉起 Pod&#xff0c;实现了应…

【初阶C++】入门(超详解)

C入门 前言1. C关键字(C98)2. 命名空间2.1 命名空间定义2.2 命名空间使用2.3嵌套命名空间 3. C输入&输出4. 缺省参数4.1 缺省参数概念4.2 缺省参数分类 5. 函数重载5.1 函数重载概念5.2 C支持函数重载的原理--名字修饰(name Mangling) 6. 引用6.1 引用概念6.2 引用特性6.3 …

最新版ES8的client API操作 Elasticsearch Java API client 8.0

作者&#xff1a;ChenZhen 本人不常看网站消息&#xff0c;有问题通过下面的方式联系&#xff1a; 邮箱&#xff1a;1583296383qq.comvx: ChenZhen_7 我的个人博客地址&#xff1a;https://www.chenzhen.space/&#x1f310; 版权&#xff1a;本文为博主的原创文章&#xff…

多丽特膳:个性化的调减饮品,让你的蜕变之路更轻松

不同的人有不同的体型和健康状态&#xff0c;在我们的生活中存在九种体质&#xff0c;它们分别是平和质、气虚质、阳虚质、阴虚质、痰湿质、湿热质、血瘀质、气郁质、特禀质。体质是指人类个体在形态结构和生理功能方面的相对稳定的特征&#xff0c;它反映了人类个体之间的差异…

【源码解析】flink sql执行源码概述:flink sql执行过程中有哪些阶段,这些阶段的源码大概位置在哪里

文章目录 一. sql执行流程源码分析1. Sql语句解析成语法树阶段&#xff08;SQL - > SqlNode&#xff09;2. SqlNode 验证&#xff08;SqlNode – >Operation&#xff09;3. 语义分析&#xff08;Operation - > RelNode&#xff09;4. 优化阶段&#xff08;RelNode - &…

【活动回顾】ABeam News | 兰州大学外国语学院回访ABeam 旗下德硕管理咨询(上海),持续推进远景合作

访企拓岗深入调研 持续推进远景合作 继11月上旬ABeam旗下艾宾信息技术开发&#xff08;西安&#xff09;团队一行拜访兰州大学并举行隆重的校企签约仪式后&#xff0c;近日兰州大学一行领导也如约莅临德硕管理咨询&#xff08;上海&#xff09;有限公司开展拓岗调研。 深化…

基于FPGA的视频接口之高速IO(SATA)

简介 本章节是对于高速IO接口应用的一个扩展,目前扩展为SATA(SSD硬盘,机械硬盘不能使用)。通俗易懂的讲,即把SSD硬盘当做大型的Nand Flash来处理,不格式化硬盘,直接以地址和数据的格式,在SATA盘中写入数据,该数据不能被Window和linux直接识别,需单独编写App来查看SSD…

Python 小程序之PDF文档加解密

PDF文档的加密和解密 文章目录 PDF文档的加密和解密前言一、总体构思二、使用到的库三、PDF文档的加密1.用户输入模块2.打开并读取文档数据3.遍历保存数据到新文档4.新文档进行加密5.新文档命名生成路径6.保存新加密的文档 四、PDF文档的解密1.用户输入模块2.前提准备2.文件解密…

【C++11】右值引用与移动语义

一.左值与右值 左值&#xff1a;可以取地址的表示数据的表达式&#xff0c;左值可以出现在赋值符号左边 右值&#xff1a;不能取地址的表示数据的表达式&#xff0c;右值不能出现在赋值符号左边 int fun() {return 0; } int main() {int a 0;//a->左值const int b 1;//b-&…

粒子群优化算法的实践 - 多个约束条件

粒子群优化算法的实践 - 多个约束条件 flyfish 粒子群优化算法的实践 - 目标函数的可视化 粒子群优化算法的实践 - 向量减法 在粒子群优化算法的代码实践中 代码写法是 #非线性约束 (x[0] - 1) ** 2 (x[1] - 1) ** 2 - 1<0 constraint_ueq (lambda x: (x[0] - 1) ** 2…

【期末考复习向】transformer的运作机制

1.transformer的encoder运作 transformer的encoder部分包括了输入和处理2大部分。首先是输入部分inputs&#xff0c;这里初始的inputs是采用独热向量进行表示的&#xff0c;随后经过word2vec等操作把独热向量&#xff08;采用独热向量的好处就是可向量是正交的&#xff0c;可以…

Centos7部署SVN

文章目录 &#xff08;1&#xff09;SVN概述&#xff08;2&#xff09;SVN与Samba共享&#xff08;3&#xff09;安装SVN&#xff08;4&#xff09;SVN搭建实例&#xff08;5&#xff09;pc连接svn服务器&#xff08;6&#xff09;svn图标所代表含义 &#xff08;1&#xff09;…

【大数据】详解 AVRO 格式

详解 AVRO 格式 1.Avro 介绍2.schema2.1 原始类型2.2 复杂类型2.2.1 Records2.2.2 Enums2.2.3 Arrays2.2.4 Maps2.2.5 Unions2.2.6 Fixed 3.Avro 的文件存储格式3.1 数据编码3.1.1 原始类型3.1.2 复杂类型 3.2 存储格式3.3 存储格式 4.小结 1.Avro 介绍 Apache Avro 是 Hadoop…

【rabbitMQ】声明队列和交换机

上一篇&#xff1a;springboot整合rabbitMQ模拟简单收发消息 https://blog.csdn.net/m0_67930426/article/details/134904766?spm1001.2014.3001.5501 相关配置环境参考上篇 springAMQP提供了几个类用来声明声明队列&#xff0c;交换机及其绑定关系 声明队列&#xff0c;…

经典策略筛选-20231213

策略1&#xff1a; 龙头战法只做最强&#xff1a;国企改革 ----四川金顶 1、十日交易内出现 涨停或 &#xff08;涨幅大于7个点且量比大于3&#xff09; 2、JDK MACD RSI OBV LWR MTM 六指标共振 3、均线多头 4、 筹码峰 &#xff08;锁仓&#xff09; 5、现价> 五日均…

C语言之文件操作(上)

C语言之文件操作&#xff08;上&#xff09; 文章目录 C语言之文件操作&#xff08;上&#xff09;1. 什么是⽂件&#xff1f;1.1 程序⽂件1.2 数据⽂件1.3 ⽂件名 2. ⼆进制⽂件和⽂本⽂件3. ⽂件的打开和关闭3.1 流和标准流3.1.1 流3.1.2 标准流 4. ⽂件指针5. 文件的打开与关…

什么是连接池?如何确认连接池的大小?

对于我们编写的几乎每个网络或移动应用程序来说&#xff0c;其底层的关键组件之一就是数据库。对于编写使用数据库且高性能且资源高效的应用程序&#xff0c;必须处理一项关键资源&#xff0c;但与 CPU、内存等不同&#xff0c;它通常不是很明显。该资源是数据库连接。 什么是…

调用Win10隐藏的语音包

起因 在做一个文本转语音的Demo的时候&#xff0c;遇到了语音包无法正确被Unity识别的问题。明明电脑上安装了语音包但是代码就是识别不出来 原因 具体也不是非常清楚&#xff0c;但是如果语言包是在的话&#xff0c;大概率是Win10系统隐藏了。 确定语言包 首先查看%windi…

VLAN详细学习

文章目录 VLAN概念VLAN种类端口VLAN工作原理以太网的三种链路类型配置 VLAN概念 一种讲局域网设备从逻辑上划分为一个个网段&#xff0c;从而实现虚拟网络的一种技术&#xff0c;这一技术主要应用于交换机中。Vlan技术是技术在以太网帧的基础上增加vlan头&#xff0c;用VLAN I…