GCN的基础理论

news2024/11/16 3:50:55

文章目录

  • GCN的基础理论
    • 1. 图的表示
    • 2. GCN的原理
    • 3. GCN的底层实现(pytorch)
      • 3.1 Data Handling of Graphs(图数据处理)
      • 3.2 Common Benchmark Datasets(通用基准数据集)
      • 3.3 Mini-batches
    • 4. 实现GCN层
    • 5. GCN简单实例

GCN的基础理论

1. 图的表示

在这里插入图片描述
A :图结构的邻接矩阵 A ~ :有自连接的邻接矩阵 A ~ = A + I D ~ :有自连接的邻接矩阵的度矩阵 D ~ i i = ∑ j A ~ i j H :图节点的特征 l : 神经网络层数 \begin{aligned} & A:图结构的邻接矩阵 \\& \widetilde{A}:有自连接的邻接矩阵 \\& \widetilde{A} = A + I \\& \widetilde{D}:有自连接的邻接矩阵的度矩阵 \\& \widetilde{D}_{ii} = \sum_{j} \widetilde{A}_{ij} \\& H:图节点的特征 \\&l:神经网络层数\end{aligned} A:图结构的邻接矩阵A :有自连接的邻接矩阵A =A+ID :有自连接的邻接矩阵的度矩阵D ii=jA ijH:图节点的特征l:神经网络层数

2. GCN的原理

H ( l + 1 ) = δ ( D ~ − 1 / 2 A ~ D ~ − 1 / 2 H ( l ) W ( l ) ) H^{(l+1)} = \delta(\widetilde{D}^{-1/2}\widetilde{A}\widetilde{D}^{-1/2}H^{(l)}W^{(l)}) H(l+1)=δ(D 1/2A D 1/2H(l)W(l))

  • GCN的输入是邻接矩阵A和节点特征H,直接做内积,再乘一个参数矩阵W,然后激活一下,不就相当于一个的神经网络层?为什么要有自连接的邻接矩阵?
    提示:无法区分“自身节点”与“无连接节点”。只使用A的话,由于A的对角线上都是0,所以在和特征矩阵H相乘的时候,只会计算一个节点的所有邻居的特征的加权和,该节点本身的特征却被忽略了。
  • 为什么需要有自连接的邻接矩阵的度矩阵?
    提示:A是没有经过归一化的矩阵,这样与特征矩阵H相乘会改变特征原本的分布,所以对A做一个标准化处理。平衡度很大的节点的重要性。(对称归一化拉普拉斯矩阵)
    N o r m A i j = A i j d i d j NormA_{ij} = \frac{A_{ij}}{\sqrt{d_{i}}\sqrt{d_{j}}} NormAij=di dj Aij

3. GCN的底层实现(pytorch)

Pytorch-Geometric (PyG):https://github.com/pyg-team/pytorch_geometric

官方文档 https://pytorch-geometric.readthedocs.io/en/latest/notes/introduction.html

PyG 提供了以下几个主要功能:

  • Data Handling of Graphs(图数据处理)
  • Common Benchmark Datasets(通用基准数据集)
  • Mini-batches
  • Data Transforms(数据转换)
  • Learning Methods on Graphs(图学习算法)
  • Exercises(训练)

3.1 Data Handling of Graphs(图数据处理)

图用于对对象(节点)之间的成对关系(边)进行建模。 PyG 中的单个图由torch_geometric.data.Data 的实例描述,该实例默认包含以下属性:

  • data.x: 节点特征矩阵H,形状:[num_nodes, num_node_features]
  • data.edge_index: 图邻接矩阵A,形状: [2, num_edges],数据类型: torch.long

    举例:[[0,1,1,2],[1,0,2,1]]:表示0节点和1节点之间有边,1节点和2节点之间有边
    即:[[所有起点节点],[所有终点节点]]。这里和一般思维不同,它们互为转置。注意使用时要转化为这种形式之后再使用

  • data.edge_attr: 边特征矩阵,形状:[num_edges, num_edge_features]
  • data.y: 训练目标(可以是任意形状),e.g., 节点尺度上的标签,形状: [num_nodes, *] or 整张图尺度上的标签 [1, *]
  • data.pos: 节点坐标矩阵,形状:[num_nodes, num_dimensions]
import torch
from torch_geometric.data import Data

# 注意:edge_index是定义所有边的源节点和目标节点的张量,不是索引元组的列表。
# --------------------第一种定义方法-----------------------------
edge_index = torch.tensor([[0, 1, 1, 2],
                           [1, 0, 2, 1]], dtype=torch.long)
x = torch.tensor([[-1], [0], [1]], dtype=torch.float)

data = Data(x=x, edge_index=edge_index)
>>> Data(edge_index=[2, 4], x=[3, 1])

# --------------------第二种定义方法-----------------------------
edge_index = torch.tensor([[0, 1],
                           [1, 0],
                           [1, 2],
                           [2, 1]], dtype=torch.long)
x = torch.tensor([[-1], [0], [1]], dtype=torch.float)

data = Data(x=x, edge_index=edge_index.t().contiguous()) # 注意这里edge_index进行了转置
>>> Data(edge_index=[2, 4], x=[3, 1])

3.2 Common Benchmark Datasets(通用基准数据集)

包含一些测试使用的基本数据集

3.3 Mini-batches

神经网络通常以批处理的方式训练。PyG 通过创建稀疏块对角邻接矩阵(由’ edge_index '定义),并在节点维度上连接特征矩阵和目标矩阵来实现小批的并行化。

这种组合允许不同数量的节点和边在一个批次的例子(即A1~An它们的维度可以不同):
在这里插入图片描述

4. 实现GCN层

此公式可分为以下步骤:

  1. 在邻接矩阵中添加自循环。
  2. 线性变换节点特征矩阵。
  3. 计算归一化系数。
  4. 规范化节点特征
  5. 对相邻节点特征求和(“add”聚合)。
import torch
from torch_geometric.nn import MessagePassing
from torch_geometric.utils import add_self_loops, degree

class GCNConv(MessagePassing):
    def __init__(self, in_channels, out_channels):
        super().__init__(aggr='add')  # "Add" aggregation (Step 5).
        self.lin = torch.nn.Linear(in_channels, out_channels)

    def forward(self, x, edge_index):
        # x has shape [N, in_channels]
        # edge_index has shape [2, E]

        # Step 1: 在邻接矩阵中添加自循环。~A
        edge_index, _ = add_self_loops(edge_index, num_nodes=x.size(0))

        # Step 2: 线性变换节点特征矩阵。H*W
        x = self.lin(x)

        # Step 3: 计算归一化系数。
        row, col = edge_index # row:第一行数据,col:第二行数据
        deg = degree(col, x.size(0), dtype=x.dtype) # deg:度矩阵D; 参数为col算入度,参数为row算出度
        deg_inv_sqrt = deg.pow(-0.5) # D^(-0.5)
        deg_inv_sqrt[deg_inv_sqrt == float('inf')] = 0
        # The result is saved in the tensor norm of shape [num_edges, ]
        norm = deg_inv_sqrt[row] * deg_inv_sqrt[col] # D^(-0.5) * ~A * D^(-0.5)

        # Step 4-5: 规范化节点特征,对相邻节点特征求和(“add”聚合)。
        return self.propagate(edge_index, x=x, norm=norm) # D^(-0.5) * ~A * D^(-0.5) * H * W

    def message(self, x_j, norm): # 扩展相乘,保证A和H能够相乘
        # x_j has shape [E, out_channels]

        # Step 4: Normalize node features.
        return norm.view(-1, 1) * x_j

5. GCN简单实例

import torch
import torch.nn.functional as F
from torch_geometric.nn import GCNConv

class GNN(torch.nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = GCNConv(dataset.num_node_features, 16) # 参数1: 节点特征数,参数2: 随机
        self.conv2 = GCNConv(16, dataset.num_classes) # 参数1: 与上一层一致,参数2: label类别数

    def forward(self, data):
        x, edge_index = data.x, data.edge_index
        
        x = self.conv1(x, edge_index) # x为特征矩阵,edge_index为邻接矩阵
        x = F.relu(x)
        x = F.dropout(x, training=self.training)
        x = self.conv2(x, edge_index)

        return F.log_softmax(x, dim=1)
from torch_geometric.datasets import Planetoid
dataset = Planetoid(root='./data/Cora', name='Cora')

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = GNN().to(device)
data = dataset[0].to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)

model.train()
for epoch in range(200):
    optimizer.zero_grad()
    out = model(data)
    loss = F.nll_loss(out[data.train_mask], data.y[data.train_mask])
    loss.backward()
    optimizer.step()
model.eval()
pred = model(data).argmax(dim=1)
correct = (pred[data.test_mask] == data.y[data.test_mask]).sum()
acc = int(correct) / int(data.test_mask.sum())
print(f'Accuracy: {acc:.4f}')

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Nacos注册中心和配置中心使用详情

Nacos Nacos就是Alibaba推出的一款 配置中心和注册中心结合的一款工具,属于SpringCloudAlibaba技术栈下 Nacos官网地址 https://nacos.io/zh-cn/index.html 安装启动 下载 目录结构 根据目录结构可以看出Nacos本身也就是一个java程序。SpringBoot程序 启动 c…

Qt线程池QThreadPool使用示例

目录前言1.线程池原理介绍2.QThreadPool详细介绍反复执行同一个任务设置线程过期时间线程数量信息3.QThreadPool示例4.总结前言 线程池顾名思义就是同时管理多个线程的"池子",它是一种并发处理技术,在程序中使用线程池能够提高线程的使用效率…

Spring之推断构造方法源码解析

Spring之推断构造方法源码解析 1、推断构造方法流程图 https://www.processon.com/view/link/5f97bc717d9c0806f291d7eb 2、AutowiredAnnotationBeanPostProcessor中推断构造方法的不同情况分析 https://www.processon.com/view/link/6146def57d9c08198c58bb26 // 有多个构…

Word控件Spire.Doc 【Table】教程(17):如何在 C#、VB.NET 中删除 Word 表格中的行和列

Spire.Doc for .NET是一款专门对 Word 文档进行操作的 .NET 类库。在于帮助开发人员无需安装 Microsoft Word情况下,轻松快捷高效地创建、编辑、转换和打印 Microsoft Word 文档。拥有近10年专业开发经验Spire系列办公文档开发工具,专注于创建、编辑、转…

【CS224图机器学习】task4 图嵌入表示学习

前言:本期学习是由datawhale(公众号)组织,由子豪兄讲解的202302期CS224图机器学习的学习笔记。本次学习为图嵌入表示学习,主要通过无监督或半监督的方法让图中的信息表示为指定尺寸向量。不用人工完成特征工程&#xf…

CCNP350-401学习笔记(301-350题)

301、Drag and drop the virtual component from the left onto their descriptions on the right. 302、Which two actions, when applied in the LAN network segment, will facilitate Layer 3 CAPWAP discovery for lightweight AP? (Choose two.)A. Utilize DHCP option …

37k*16 薪,年后直接上岗,3年自动化测试历经3轮面试成功拿下阿里Offer....

前言 转眼过去,距离读书的时候已经这么久了吗?,从18年5月本科毕业入职了一家小公司,到现在快4年了,前段时间社招想着找一个新的工作,前前后后花了一个多月的时间复习以及面试,前几天拿到了阿里…

Yield Guild Games:社区更新——2022 年第四季度

在这篇文章中,Yield Guild Games(YGG)分享了 2022 年第 4 季度社区更新的主要内容,包括公会发展计划(GAP)的最新细节,公会在电竞领域的持续发展,最新的合作伙伴关系,以及…

git中git push origin master推送远程操作失败,报错解决方案

报错图片如下所示: 解决方案: 使用下面代码进行本地与远程仓库的链接: git remote add origin http://xxxxx///xxx(https://gitee.com/peach-fog/shopping-cart-car-warehouse.git)链接完成之后就会输出:fatal: remote origin already exists. 链接完成之后就需要使用git br…

知识蒸馏论文阅读:FGD算法笔记

标题:Focal and Global Knowledge Distillation for Detectors 会议:CVPR2022 论文地址:https://ieeexplore.ieee.org/document/9879869/ 官方代码:https://github.com/yzd-v/FGD 作者单位:清华大学深圳国际研究生院、…

【mircopython】ESP32配置与烧录版本

下载ESP32的Micropython固件 官方连接https://www.micropython.org/download/esp32/ 看了下描述,上面的是IDF4.x系列编译,下面是IDF3.x系列编译,我们默认选新的 下载安装CP2102驱动 CP210x USB to UART Bridge VCP Drivers - Silicon Labs…

自托管提醒平台Noted Reminders

什么是 Noted Reminders ? Noted 是一个简单的自托管应用程序,用于创建使用 Apprise API 推送到设备的提醒。您可以向几乎每个平台发送消息,包括定时电子邮件! 什么是 Apprise API ? Apprise 允许您向我们今天可用的几乎所有最流…

OpenSumi 是信创开发云的首选

原文作者:行云创新技术总监 邓冰寒 引言 随着云原生应用的日益普及,开发上云也逐步被越来越多的厂商和开发者接受,在这个赛道国内外有不少玩家,国外的 GitHub Codespaces、CodeSandbox,GitPod、亚马逊 Cloud9&#xf…

Pytorch GPU版本简明下载安装教程

1.根据自己的显卡型号下载显卡驱动并安装。这一步会更新你的显卡驱动,也可忽略第1步,如果第2步出现问题,返回执行第1步。 点击这里下载英伟达显卡驱动 2.安装完成后,wincmd打开命令行,输入nvidia-smi,查看…

分享三个可以在家做的正规兼职工作,看到就是赚到

你可以在家做正式的兼职工作。在线兼职工作值得考虑,时间相对自由。在线兼职收入可能不如线下滴滴和外卖立竿见影,但仍然可以坚持收入。有些人比工作工资发展得更高。当然,天上不会有馅饼,不劳无获。那么有哪些正规的兼职可以在家…

【C++】引用、内联函数、auto关键字、范围for、nullptr

引用什么叫引用引用的特性常引用使用场景传值、传引用效率比较引用和指针的区别内联函数auto关键字(C11)基于范围的for循环(C11)指针空值nullptr(C11)引用 什么叫引用 引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内…

《python3网络爬虫开发实战 第二版》之基本库的使用-requests的使用 详解

文章目录1 requests库的使用1.1 准备工作1.2 实例引入1. 3 GET请求1.3.1 基本实例1.3.2 抓取网页1.3.3 抓取二进制数据1.3.4 添加请求头1.4 POST请求1.5 响应1.6 高级用法1.6.1 文件上传1.6.2 Cookie设置1.6.3 Session维持1.6.4 SSL证书验证1.6.5 超时设置1.6.6 身份认证1.6.7 …

旅游地如何搭好影视剧“顺风车”

新春伊始,《满江红》《三体》《狂飙》等影视剧给影片取景地带来的关注和旅游热潮引人瞩目——从太原古县城到襄阳古城墙上的“岳”字砖、从宁波博物馆到江门的历史文化街区乃至地方特产新会陈皮……都被影视剧带上了热搜。影视作品与取景地的相互成全由来已久&#…

JavaWab开发的总括以及HTML知识

一、Web开发的总括在这里我来给大家介绍一下Wab开发需要配合哪些前后端的对应语言:首先是Java(Java通常的工作):Wab开发android开发大数据开发另外,Wab开发想要学好就需要配合之前博客中的内容,如:多线程/IO/网络/数据结构/数据库......这里建议学懂前面的内容再往下走.JavaWab…

2023年,都在说软件测试饱和了,大环境不好?为何每年还会增加40万测试员?

最近和一些刚进入软件测试行业的朋友交流,发现了一个有趣的现象,那就是对这个行业很多问题的认识是一致的、片面的,也可以理解为误解。利用你的时间列出他们对这个行业的所有误解,然后结合你多年的工作经验和你交流。毕竟你是从这…