最新要闻
- 把魔兽停服当庆典营销 网易《逆水寒》被曝涉嫌抄袭暴雪IP
- 当前热讯:《黑神话:悟空》定档:想玩记得升级电脑
- 快播:2022年预制菜销量大涨!之前有专家还说“我从来不吃”
- 世界报道:高铁站大厅没插座 客服:为了消防安全
- 滚动:你遇到过没?货车安装超亮后射灯:夜晚跟车根本看不清
- 时讯:首发2亿像素HP2!三星Galaxy S23 Ultra万元机皇来了
- 观察:口碑爆棚!剧版《三体》市占率16.51%排行第一
- 年终会员大促:B站/芒果TV/腾讯视频/优酷/百度网盘3.6折起
- 三电机真恐怖!特斯拉Model S Plaid瞬间撕裂马力机张力带
- 焦点热讯:内置LED屏见过没?Naspec推出高端HDMI 2.1数据线
- 焦点要闻:美国一州提案禁售电动汽车 议员:就看不惯“禁售燃油车”的提议
- 环球热门:电动车新国标过渡期陆续到期 雅迪股价半月暴涨3成
- 合作谈崩了 暴雪还想让网易当半年“备胎”?
- 特斯拉Model S之后:一改装公司推出福特电马灵车和礼宾车
- 今日讯!魅族Flyme牵手中国电信天翼终端!软硬件生态全面融合
- 小心吃官司 央视发布声明:2023兔年春晚内容别乱用
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
Pytorch-geometric: Creating Message Passing Networks 构建消息传递网络教程
一、背景
将卷积运算推广到不规则域通常表示为邻局聚合(neighborhood aggregation)或消息传递(neighborhood aggregation)模式。
\(\mathbf{x}^{(k-1)}_i \in \mathbb{R}^{1 \times D}\)表示节点\(i\)在第\((k-1)\)层的节点特征, \(\mathbf{e}_{j,i} \in \mathbb{R}^{1 \times F}\)表示节点\(j\)到节点的\(i\)边特征(可选的),消息传递图神经网络可以描述为:
【资料图】
\[\mathbf{x}_i^{(k)} = \gamma^{(k)} \left( \mathbf{x}_i^{(k-1)}, \square_{j \in \mathcal{N}(i)} \, \phi^{(k)}\left(\mathbf{x}_i^{(k-1)}, \mathbf{x}_j^{(k-1)},\mathbf{e}_{j,i}\right) \right), \]其中, \(\square\)表示可微且置换不变的聚合函数(aggregation function),例如, sum
、mean
或max
,消息函数(message function)\(\phi\) 和更新函数(update function)\(\gamma\)均为可微函数,例如MLP。
\[\mathbf{x}_{\mathcal{N}_{i}}^{(k)}=\text { AGGREGATE }_{(k)}\left(\left\{\mathbf{x}_{j}^{(k-1)}, \forall j \in \mathcal{N}_{i}\right\}\right) \]\[\mathbf{x}_{i}^{(k)}=\sigma\left(\mathbf{W}^{(k)} \cdot\left[\mathbf{x}_{i}^{(k-1)} \| \mathbf{x}_{\mathcal{N}_{i}}^{(k)}\right]\right)\]值得注意的是,一般GNN论文中通常给出的是聚合邻居信息的Aggregator和更新节点表示Updator,其Aggregator对应pytorch-geometric(PyG)中的消息函数和聚合函数。GNN本质上还是在做特征传播。
例如,在GraphSage中,消息函数直接获取邻居节点\(j \in \mathcal{N}_{i}\)在第\(k-1\)层的嵌入,然后使用mean、max或LSTM作为聚合函数,更新函数将邻居中间嵌入和目标节点\(i\)自身嵌入拼接后做线性变化。
\[\alpha_{i j}=\frac{\exp \left(\text { Leaky ReLU }\left(\mathbf{a}^{T}\left[\mathbf{W} \mathbf{x}_{i} \| \mathbf{W} \mathbf{x}_{j}\right]\right)\right)}{\sum_{k \in \mathcal{N}_{i}} \exp \left(\text { Leaky ReLU }\left(\mathbf{a}^{T}\left[\mathbf{W} \mathbf{x}_{i} \| \mathbf{W} \mathbf{x}_{k}\right]\right)\right)}\]\[\mathbf{x}_{i}^{\prime}=\|_{k=1}^{K} \sigma\left(\sum_{j \in \mathcal{N}_{i}} \alpha_{i j}^{k} \mathbf{W}^{k} \mathbf{x}_{j}\right)\]又例如,在GAT中,消息函数根据注意力系数对节点嵌入进行归一化,然后使用"add"
作为聚合函数。
二、MessagePassing基类
PyG的torch_geometric.nn
中提供了MessagePassing
基类,它通过自动处理消息传播来帮助创建此类消息传递图神经网络。用户只需重新定义\(\phi\)message()
和\(\gamma\)update()
及aggregation聚合方式(函数),例如aggr="add"
, aggr="mean"
or aggr="max"
,就可以实现自己GNN模型。
借助以下4个方法可实现上述目的:MessagePassing(aggr="add", flow="source_to_target", node_dim=-2)
:定义要使用的聚合方案("add"
,"mean"
或"max"
)和消息传递的流向("source_to_target"
或"target_to_source"
)。 此外,node_dim
属性指明沿哪个轴传播。
MessagePassing.propagate(edge_index, size=None, **kwargs)
: 开始传播消息的初始调用。它接收边索引edge_index
和构造消息所需的所有其他数据,来更新节点嵌入。propagate()
不仅可以在[N, N]
的方矩中交换消息,还可通过传入size=(N, M)
作为附加参数传递来交换形如[N, M]
的稀疏分配矩阵(例如,推荐系统中的二部图)中的消息。如果size
设为None
,则矩阵为方阵。
MessagePassing.message(...)
:类似\(\phi\),构造每条边到节点\(i\)的消息。若 flow="source_to_target"
则\((j,i) \in \mathcal{E}\)和flow="target_to_source"
则 \((i,j) \in \mathcal{E}\)。它可接受最初传递给propagate()
的任何参数。 此外,传递给propagate()
的tensors可通过添加后缀_i
和_j
到变量名(例如,x_i
和x_j
)映射到对应的节点\(i\)和\(j\)。根据习惯,通常用\(i\)表示聚合信息的中心节点(目标target),并用\(j\)表示邻居节点(源source)。
MessagePassing.update(aggr_out, ...)
:类似\(\gamma\),更新每个节点\(i \in \mathcal{V}\)的嵌入。聚合操作的输出aggr_out
作为其第一个参数,以及最初传递给propagate()
的任何参数。
三、例子
接下来,将通过MessagePassing实现GCN和EdgeConv来作进一步介绍。为便于表示,将节点特征表示为行向量。
3.1 实现GCN层
矩阵形式的GCN层:
\[\mathbf{X}^{(k)} =\sigma\left(\hat{\mathbf{A}} \mathbf{X}^{(k-1)} \mathbf{W}^{(k)} \right)\]其中,\(\hat{\mathbf{A}}=\tilde{\mathbf{D}}^{-\frac{1}{2}} \tilde{\mathbf{A}} \tilde{\mathbf{D}}^{-\frac{1}{2}} \in \mathbb{R}^{N \times N}\)为自环归一化邻接矩阵,\(\tilde{\mathbf{A}}=\mathbf{A}+\mathbf{I}\)在原始邻接矩阵上加自环连接, \(\tilde{\mathbf{D}}=\mathbf{D}+\mathbf{I}\),\(\mathbf{X}^{(k-1)}\in \mathbb{R}^{N \times D}\),\(\mathbf{W}^{(k)}\in \mathbb{R}^{D\times D}\)。
将\(\hat{\mathbf{A}}\)在节点层面展开:
- \(\tilde{\mathbf{A}}\)先左乘\(\tilde{\mathbf{D}}^{-\frac{1}{2}}\)做行变化,即对\(\tilde{\mathbf{A}}\)的每一行\(\tilde{\mathbf{A}}_{i:}\)按节点\(i\)的度\(deg(i)^{-\frac{1}{2}}\)进行归一化(假设\(\tilde{\mathbf{A}}\)为指示矩阵,除自己之外,只有节点\(i\)的一阶邻居\(j \in \mathcal{N}(i)\)的值\(\tilde{\mathbf{A}}_{ij}\)为1)。
- \(\tilde{\mathbf{D}}^{-\frac{1}{2}} \tilde{\mathbf{A}}\)再右乘\(\tilde{\mathbf{D}}^{-\frac{1}{2}}\)做列变化,即对每一列\((\tilde{\mathbf{D}}^{-\frac{1}{2}} \tilde{\mathbf{A}})_{:j}\)按节点\(j\)的度\(deg(j)^{-\frac{1}{2}}\)再做归一化。
此时,\(\hat{\mathbf{A}}_{ij}=\tilde{\mathbf{A}}_{ij} deg(i)^{-\frac{1}{2}} deg(j)^{-\frac{1}{2}}\),即将满足\(\tilde{\mathbf{A}}_{ij} \neq 1\)的边 $ e_{ij}$ 对应的节点对 \(\)的度来进行归一化。
\(\hat{\mathbf{A}}\)的行或列之和并不为一,它不同于可视为概率转移矩阵的简单行归一化\(\tilde{\mathbf{D}}^{-1} \tilde{\mathbf{A}}\)或列归一化$\tilde{\mathbf{A}} \tilde{\mathbf{D}}^{-1} $。
\(\hat{\mathbf{A}}\) 右乘 \(\mathbf{X}^{(k-1)}\),相当于用\(\hat{\mathbf{A}}\)的每一行的系数对节点的行向量矩阵做线性组合。其中,节点\(i\)在第\(k\)层的表示\(\mathbf{x}^{(k)} \in \mathbb{R}^{1 \times D}\)是由 \(\hat{\mathbf{A}}_{i:} \in \mathbb{R}^{1 \times N}\)乘以\(\mathbf{X}^{(k-1)} \in \mathbb{R}^{N \times D}\),等价于直接以加权系数\(\hat{\mathbf{A}}_{i:}\)对节点\(i\)的一阶邻居\(\mathcal{N}(i)\)以及\(i\)自己的节点表示做线性组合(加权求和)。
由此,可得到空域视角的GCN层的定义:
\[\mathbf{x}_i^{(k)} = \sum_{j \in \mathcal{N}(i) \cup \{ i \}} \frac{1}{\sqrt{\deg(i)} \cdot \sqrt{\deg(j)}} \cdot \left( \mathbf{x}_j^{(k-1)} \mathbf{W}^{(k)} \right) + \mathbf{b},\]其中, 邻居节点的特征先经权重矩阵$\mathbf{W}^{(k)} $做变换,再按它们的度做归一化,最后求和。最后,将偏置向量应用于聚合输出。
GCN公式可分为以下步骤:
- 将自环连接加到邻接矩阵上
- 线性变换节点特征矩阵
- 计算归一化系数
- 归一化节点特征(制作message的过程)
- 使用
"add"
方法聚合节点特征(先汇聚邻居节点特征,再和目标节点特征合并) - 加上偏置向量(bias为可选项)。
第1-3步通常在消息传递前计算,4-5步可用MessagePassing
基类轻松实现。完整实现如下所示:
点击查看代码
import torchfrom torch.nn import Linear, Parameterfrom torch_geometric.nn import MessagePassingfrom torch_geometric.utils import add_self_loops, degreeclass GCNConv(MessagePassing): def __init__(self, in_channels, out_channels): # in_channels为输入节点特征维度, out_channels为输出节点特征维度 # 初始化GCN层中的线性变换权重矩阵和bias向量 super().__init__(aggr="add") # "Add" aggregation (Step 5). self.lin = Linear(in_channels, out_channels, bias=False) self.bias = Parameter(torch.Tensor(out_channels)) self.reset_parameters() def reset_parameters(self): # 参数初始化 self.lin.reset_parameters() self.bias.data.zero_() def forward(self, x, edge_index): # 节点特征矩阵x的shape为[N, in_channels] # 边索引edge_index的shape为[2, E] # Step 1: 将自环连接加到邻接矩阵上 edge_index, _ = add_self_loops(edge_index, num_nodes=x.size(0)) # Step 2: 对节点特征矩阵做线性变换 x = self.lin(x) # Step 3: 计算归一化系数 row, col = edge_index # 分别取出边索引的两部分 # 由于GCN一般将图视为无向,row或col中分别包含所有节点的索引,故可根据col统计节点的度 deg = degree(col, x.size(0), dtype=x.dtype) # 度对角矩阵 deg_inv_sqrt = deg.pow(-0.5) # 对角元素开负根号 deg_inv_sqrt[deg_inv_sqrt == float("inf")] = 0 # 归一化系数实际对应每条边,直接用边索引取度相乘即可 # norm的shape为[E, 1], E为边数量 norm = deg_inv_sqrt[row] * deg_inv_sqrt[col] # Step 4-5:开始传播消息 out = self.propagate(edge_index, x=x, norm=norm) # Step 6: 加偏置向量 out += self.bias return out def message(self, x_j, norm): # x_j的shape为[E, out_channels] # Step 4: 归一化节点特征(先将norm系数变为列向量,再和x_j做点乘) return norm.view(-1, 1) * x_j
GCNConv
继承了使用"add"
聚合操作的MessagePass
。GCN层的所有计算逻辑都包含在其forward
方法中。
在计算好归一化系数norm
后(在GCN中norm
固定),将调用propagate()
,该函数内部会调用message()
、update()
和aggregate()
。除了edge_index
, 节点嵌入x
和归一化系数norm
将作为GCN消息传播的附加参数。
在message()
函数中,需通过norm
对邻居节点特征进行归一化。这里,x_j
表示一个 a lifted tensor,它包含每个边的source源节点特征,即每个节点的邻居。
以上就是创建一个简单的消息传递层所需的全部内容。此层可用作深层GNN的基础模块。初始化和调用它很简单:
点击查看代码
conv = GCNConv(16, 32)x = conv(x, edge_index)
3.2 实现EdgeConv层
边卷积层可以处理处理图或点云,它在数学上定义为:
\[\mathbf{x}_i^{(k)} = \max_{j \in \mathcal{N}(i)} h_{\mathbf{\Theta}} \left( \mathbf{x}_i^{(k-1)}, \mathbf{x}_j^{(k-1)} - \mathbf{x}_i^{(k-1)} \right),\]其中,\(h_{\mathbf{\Theta}}\)表示MLP。 与GCN层类似,可使用MessagePassing
类来实现它,聚合方式将使用"max"
:
点击查看代码
import torchfrom torch.nn import Sequential as Seq, Linear, ReLUfrom torch_geometric.nn import MessagePassingclass EdgeConv(MessagePassing): def __init__(self, in_channels, out_channels): super().__init__(aggr="max") # "Max" aggregation. self.mlp = Seq(Linear(2 * in_channels, out_channels), ReLU(), Linear(out_channels, out_channels)) def forward(self, x, edge_index): # x has shape [N, in_channels] # edge_index has shape [2, E] return self.propagate(edge_index, x=x) def message(self, x_i, x_j): # x_i has shape [E, in_channels] # x_j has shape [E, in_channels] tmp = torch.cat([x_i, x_j - x_i], dim=1) # tmp has shape [E, 2 * in_channels] return self.mlp(tmp)
在message()
函数内部,self.mlp
用于变换目标节点的特征x_i
和每条边 \((j,i) \in \mathcal{E}\)的相对源节点特征 x_j - x_i
。边卷积实际为是动态卷积,对GNN的每一层都在特征空间使用knn最近邻来重新计算图结构。
参考文献
[1] Pytorch-geometric官方文档-Creating Message Passing Networks[2] https://blog.csdn.net/morgan777/article/details/121183287[3] https://zhuanlan.zhihu.com/p/130796040[4] https://blog.csdn.net/weixin_39925939/article/details/121360884
-
Pytorch-geometric: Creating Message Passing Networks 构建消息传递网络教程
一、背景将卷积运算推广到不规则域通常表示为邻局聚合(neighborhoodaggregation)或消息传递(neighborhoo...
来源: Pytorch-geometric: Creating Message Passing Networks 构建消息传递网络教程
把魔兽停服当庆典营销 网易《逆水寒》被曝涉嫌抄袭暴雪IP
当前热讯:《黑神话:悟空》定档:想玩记得升级电脑
快播:2022年预制菜销量大涨!之前有专家还说“我从来不吃”
7层WAF的一些记录
天天新动态:Numpy基本使用方法
[数据结构]单向链表插入排序(C语言)
世界报道:高铁站大厅没插座 客服:为了消防安全
滚动:你遇到过没?货车安装超亮后射灯:夜晚跟车根本看不清
时讯:首发2亿像素HP2!三星Galaxy S23 Ultra万元机皇来了
观察:口碑爆棚!剧版《三体》市占率16.51%排行第一
当前要闻:BC4-牛牛学说话之-浮点数
【独家焦点】关于可迭代对象、迭代器对象、生成器对象
环球快消息!AcWing 1077. 皇宫看守
年终会员大促:B站/芒果TV/腾讯视频/优酷/百度网盘3.6折起
三电机真恐怖!特斯拉Model S Plaid瞬间撕裂马力机张力带
焦点热讯:内置LED屏见过没?Naspec推出高端HDMI 2.1数据线
焦点要闻:美国一州提案禁售电动汽车 议员:就看不惯“禁售燃油车”的提议
环球热门:电动车新国标过渡期陆续到期 雅迪股价半月暴涨3成
vue3_ts_defineProps的使用
合作谈崩了 暴雪还想让网易当半年“备胎”?
特斯拉Model S之后:一改装公司推出福特电马灵车和礼宾车
今日讯!魅族Flyme牵手中国电信天翼终端!软硬件生态全面融合
学习笔记——定义切面优先级 ;Spring中的JdbcTemplate;JdbcTemplate的常用API
当前短讯!从0开始学Java 第一期 开发前的准备
小心吃官司 央视发布声明:2023兔年春晚内容别乱用
世界焦点!华硕发布Vivobook S 16 Flip笔记本:16寸3.2K OLED翻转屏
快播:联想一大波ThinkBook笔记本来袭:全新一代处理器 32G内存
天天时讯:国服还能玩6天:《守望先锋:归来》开启春节活动
天天速看:国家级出行平台!“强国交通”完成内测即将上线:接入微信、支付宝等
天天热门:研发回家过年了,留下这个低代码开源平台真好用!
天天热门:Python基础之函数
小米城市定制机来了!小米13信阳专属版今日交付:包装盒独一无二
网易、暴雪骂战正酣 NVIDIA站台《永劫无间》:即将支持DLSS3
环球速看:火锅店回应起火后要求顾客先结账:网友甩出一张神图
世界报道:《三体》电视剧从北京正负电子对撞机取景 物理学家纷纷追剧
全球今日报丨越跌越买!特斯拉降价是“好时机”:木头姐仍在大举加仓
全球关注:SSH 远程免密登录(公钥登录)
世界观速讯丨达到你城市标准没?去年白领平均年终奖8428元:仅1城连涨三年 到手先存
今日精选:大品牌好价!振德医用外科、KN95口罩29.9元起包邮
世界观察:互联网公司春节红包缩水一半:快手最豪横 狂撒20亿元
【独家焦点】50GB包年39元!小米云服务会员春节福利:最低5.5折
世界聚焦:SpaceX重型猎鹰火箭发射美国太空军机密卫星:不怕核打击
快资讯:opencv官网例程(4.7.0版本)运行示例
【优秀论文解读】BoW3D: Bag of Words for Real-time Loop Closing in 3D LiDAR SLAM
学习笔记——Spring中的AOP(AspectJ);Spring中AOP概述;Spring中AOP相关术语;AspectJ中切入点表达式;AspectJ中Jo
当前热讯:峰值21WQps、亿级DAU,小游戏《羊了个羊》是怎么架构的?
改款特斯拉Model 3即将登场:预计今年三季度投产
苹果版“望远镜”!曝iPhone 16 Pro/16 Ultra都会配备潜望长焦
科学家警告:2024或成全球史上最热年份
天天短讯!读编程与类型系统笔记10_泛型算法和迭代器
精选!【K哥爬虫普法】辛苦钱被中间商抽走八成,还因此锒铛入狱
育碧CEO让员工少花钱多做事 巴黎工作室将罢工抗议
苹果上海被强制执行1.44亿:这么多年还是第一次
世界通讯!微软否认“万人大裁员”:纯属谣言
天天讯息:7岁男孩爱撕倒刺致手指感染 医生提醒:处理不当会引发骨髓炎
全球今亮点!春节正常发货:仁和N95灭菌级口罩25片15.9元大促
世界要闻:网友3美元淘了一颗废品锐龙9 5900X:掰正针脚 点亮!
王晶武侠电影 《天龙八部之乔峰传》明日首映:年三十三大视频平台上线
Appuploader内测版本详解
热点评!使用Python的一维卷积
全球时讯:平民也能玩8GHz超频 技嘉B760主板奉上两大绝技:内存延迟大降7ns
被偷家了!德国人不买大众 把美系车特斯拉买成销冠
12nm后 DRAM怎么办?EUV光刻也不是万能药
每日时讯!安徽一劳斯莱斯婚车撞上石墩受损严重 博主:可向设置限宽人员索赔
《蚁人3:量子狂潮》角色海报发布 蚁人女儿貌美如花
象是哪个少数民族的生肖?十二生肖儿歌顺口溜
释迦牟尼佛成道日是哪一天?释迦牟尼佛的故事
国税地税税种有哪些?国税地税税种比例怎么分?
家有恶邻后面一句是什么?家有恶邻居怎么办?
最资讯丨学习笔记——AOP-代理模式
Python使用pyppeteer搭建网页截图api
三星移动硬盘质量怎么样?三星移动硬盘打不开怎么解决?
帅康燃气灶怎么样?帅康燃气灶打火后松手就熄灭怎么解决?
qq服务器拒绝发送离线文件是什么意思?qq服务器拒绝发送离线文件怎么办?
什么八字的人长得好看?什么八字的人长得丑?
光波炉的危害有哪些?光波炉与微波炉的区别
移动硬盘目录损坏如何恢复?移动硬盘目录损坏解决方法
今日快讯:官宣:F1中国站无缘2023赛季 已连续4年缺席
世界热文:开发预算突破7亿!网易400人团队“超级项目”《逆水寒》手游获批版号
天天快报!2023全球品牌价值500强出炉:苹果跌至第2 抖音杀入前10
全球观察:买一赠一:腾讯视频京东Plus会员联名年卡148元大促
《魔兽世界》电子骨灰盒出现bug:下载存档错误 账号被锁定
全球快消息!APM vs NPM
排面!小米登上《人民日报》头版
情侣拍照时戒指不慎掉入洱海 男生立即跳湖寻找:官方回应太危险不可取
天天热文:吃播账号“浪胃仙”被判属原公司:创始人涉职务侵占被捕
全球今日讯!学习笔记——Spring中组件扫描(包含扫描、排除扫描)、Spring中完全注解开发;Spring整合Junit4步骤
10辆特斯拉新车高速上集体燃烧 只剩一堆废铁架子
美国科技巨头依然寒气逼人 微软即将裁员:1万多人丢了工作
每日消息!《最后生还者》热播 收视率仅次于《龙之家族》
全球百事通!别人“借钱不还”怎么办?网友公布微信妙招 赶紧学起来
全球快资讯丨1月23日国服停!双方谈崩 网友吐槽暴雪绿茶:网易后到底谁来接盘?
世界热资讯!冬天加油枪都被冻住了 网友吐槽:国六B汽油里水加多了
当前关注:彻底闹掰!网易:暴雪提议蛮横 不符合商业逻辑
天天速看:价值10万土壤被快递弄丢 或致无法毕业 中通:找不到愿赔1000元 后续来了
央视点赞比亚迪:不惧冰雪 用技术发力高端
【天天时快讯】网友抱怨小米13前摄开孔太大!雷军回应:升级了3200万像素 无短板
数据类型的内置方法 可变类型与不可变类型
每日视讯:P1352 没有上司的舞会+P1122 最大子树和(树形DP入门)