图神经网络实战深入浅出地学习图神经网络gnn(上)(代码片段)

WSKH0929 WSKH0929     2022-12-04     146

关键词:

文章目录


本文为学习产物,学习链接(如有侵权,请告知删除):
人工智能【图神经网络实战】教程,让你一天就学会深入浅出图神经网络GNN,从入门到精通!

一、图神经网络应用领域

1.1 芯片设计

芯片的设计比较耗费人力和物力,如果可以通过AI算法自动设计芯片,则可以大大提高芯片制造的效率,降低芯片制造的成本

1.2 场景分析与问题推理

例如剧本杀中的推理,警匪片中嫌疑人的图推理等

1.3 推荐系统

例如,刷抖音,经常看英雄联盟的游戏视频,那么说明你对游戏比较感兴趣,系统会根据网络图结构推荐更多和英雄联盟相关的内容给你

1.4 欺诈检测与风控相关

贷款软件,读取用户的通讯录信息和app使用情况,从而测评用户的还款能力,然后决定用户的借款额度

1.5 知识图谱

智能客服

1.6 道路交通的流量预测

预测道路上每条边的流量

1.7 自动驾驶(无人机等场景)

1.8 化学,医疗等场景

利用AI对化学结构进行分析,预测

1.9 物理模型相关

根据分子结构进行相关分析


二、图神经网络基本知识

2.1 图基本模块定义

V:点,每个点都有自己的特征向量(特征举例:邻居点数量、一阶二阶相似度)
E:边,每个边都有自己的特征向量(特征举例:边的权重值、边的定义)
U:整个图,每个图都有自己的特征向量(特征举例:节点数量、图直径)

2.2 图神经网络要做的事情

  • 为每个节点整合特征向量,根据其对节点做分类或者回归
  • 为每条边整合特征向量,根据其对边做分类或者回归
  • 为每张图整合特征向量,根据其对图做分类或者回归

2.3 邻接矩阵的定义

2.3.1 图数据的邻接矩阵

2.3.2 文本数据的邻接矩阵

2.4 GNN中的常见任务

传统神经网络(CNN、RNN、DNN)要求输入格式是固定的(如24×24、128×128等)。

但在实际场景中(例如道路交通),不同城市的道路数量和节点数量都不同,即输入数据格式不固定。对此,传统神经网络不能很好地解决,但是GNN可以用来解决此类问题

对于输入数据格式不固定的情况,GNN的常见任务有以下几种:

2.4.1 Graph级别任务

基于整个图,做分类和回归。
例如,给定一个分子结构图,判断它里面存在几个环 或者 判断该分子结构属于哪一类

2.4.2 Node与Edge级别任务

预测这个点是教练还是学员,即预测点
预测两个点之间的关系(是打架关系还是观看关系),即预测边

2.5 消息传递计算方法

2.5.1 优化邻接矩阵

之前学过,邻接矩阵的大小为N*N,当节点很多的时候,邻接矩阵的大小也会特别大

为了解决这个问题,我们一般采取只保存source数组和target数组的方式

source数组即起点(起源点)数组,target数组即终点(目标点)数组

这两个数组的维度是一样的

对应位置的source和target值就可以代表一条可连接的有向边,对于没有连接关系的边则不需要保存其信息,这样就可以大大减少数据规模

2.5.2 点的特征重构

汇总 = 自身的信息 + 所有邻居点的信息

所有邻居点信息的表达有几种:

  • 求解Sum
  • 求平均Mean
  • 求最大Max
  • 求最小Min

2.6 多层GNN的作用

层数越多,GNN的“感受野”越大,每个点考虑其他点的信息越多,考虑越全面

GNN输出特征的用处


三、GCN详解

3.1 GCN基本模型概述

3.1.1 卷积 vs 图卷积

卷积:卷积核平移计算

图卷积:自身信息+所有邻居信息

3.1.2 图中常见任务

3.1.3 如果获取特征

3.1.4 半监督学习

GCN属于半监督学习(不需要每个节点都有标签都可以进行训练)

计算Loss时,只需要考虑有标签的节点即可。

为了减少有标签节点的Loss,其周围的点也会做相应的调整,这也是图结构的特点,因此GNN和GCN中,不需要所有节点都有标签也可以进行训练(当然至少需要一个节点有标签)

3.2 图卷积的基本计算方法

3.2.1 GCN基本思想

  • 对每个节点计算特征
  • 然后合成每个节点的特征
  • 将合成的特征传入全连接网络进行分类

3.2.2 GCN层数

图卷积也可以做多层,但是一般不做太深层,一般只做2-3层
(类似于一种说法,你只需要认识6个人就可以认识全世界)


实验表明:GCN中,深层的网络结构往往不会带来更好的效果。
直观解释:我表哥认识的朋友的朋友的朋友的朋友认识市长,不代表我和市长关系就很好。

层数越多,特征表达就越发散

一般2-5层即可

3.2.3 图中基本组成

3.2.4 特征计算方法

3.3 邻接矩阵的变换

单位矩阵相当于给每个节点加了一条自连接的边


但是现在存在一个问题:一个节点的度越大,其做矩阵乘法后的值就越大(累加次数变多了),这种情况是不好的(相当于一个人认识的人越多,其的特征值就越大,这样不好)

为了解决这个问题,我们需要对度矩阵求倒数,相当于平均的感觉,对度数大的节点加以限制


上面的左乘相当于对行做了归一化操作,那么列也需要做归一化操作

但是又有问题了,行和列都做了归一化,那不是会存在2次归一化的情况吗(行列重叠处)

所以我们需要在度矩阵倒数那加一个0.5次方来抵消这个2次归一化的影响

3.4 GCN变换原理解读

如下图所示,假设绿色框中的人是个富人,红色框中的人是个穷人,他们只是小时候认识,穷人只认识富人,而富人认识很多人。

如果只对行做归一化,由于穷人只认识富人,所以其度为1,则其在进行特征重构的时候很大一部分信息会来自于富人,这样的模型大概率会认为穷人和富人是同一种人。显然,这是不合理的

所以,我们需要同时对行和列都进行归一化,这样不仅只考虑富人对穷人的关系,还考虑了穷人对富人的关系。

简单来说,对行做归一化考虑到了,富人对穷人来说很重要;对列作归一化,考虑到了穷人对富人可能没那么重要(因为富人的度很大,穷人的度很小,富人很可能不记得穷人了),这样相对更加合理。

3.5 GCN传播公式

softmax是作多分类常用的激活函数


四、PyTorch Geometric 库的基本使用

4.1 PyTorch Geometric 的安装

注意: 千万不要直接pip install 去安装这个库!!!

进入这个GitHub网址: https://github.com/pyg-team/pytorch_geometric

进入页面后往下滑,找到如下图所示的字样,点击here

选择你电脑中已经安装的torch版本(一定要和你已经安装的torch版本一致)

怎么查看torch版本?

在Pycharm中,点击底部栏的Terminal,输入pip show torch,即可查看torch版本


选择完正确的torch版本后,会进入下面的界面,一共有4个不同的.whl文件,每一种选一个符合你的版本下载即可

例如:torch_cluster-1.5.9-cp36-cp36m-win_amd64.whl 指的是python为3.6的windows版本


我的电脑是windows的,python版本为3.8.12,所以我下载的四个包如下图所示:

下载好之后,直接pip install 你的.whl文件地址

下面是我安装时候的命令(仅供参考):

pip install C:\\Users\\WSKH\\Desktop\\torch_cluster-1.5.9-cp38-cp38-win_amd64.whl
pip install ‪C:\\Users\\WSKH\\Desktop\\torch_scatter-2.0.6-cp38-cp38-win_amd64.whl
pip install C:\\Users\\WSKH\\Desktop\\torch_sparse-0.6.9-cp38-cp38-win_amd64.whl
pip install ‪C:\\Users\\WSKH\\Desktop\\torch_spline_conv-1.2.1-cp38-cp38-win_amd64.whl

最后,一定要等上面四步完成之后,再执行下面的操作

pip install torch-geometric

4.2 数据集与邻接矩阵格式

4.2.1 数据集介绍

Hello World 级别的数据集,34个节点

4.2.2 数据探索

from torch_geometric.datasets import KarateClub

dataset = KarateClub()
print(f'Dataset:dataset:')
print('=' * 30)
print(f'Number of graphs:len(dataset)')
print(f'Number of features:dataset.num_features')
print(f'Number of classes:dataset.num_classes')

print('=' * 30)
data = dataset[0]
# train_mask = [True,False,...] :代表第1个点是有标签的,第2个点是没标签的,方便后面LOSS的计算
print(data)  # Data(x=[节点数, 特征数], edge_index=[2, 边的条数], y=[节点数], train_mask=[节点数])

输出:

Dataset:KarateClub():
==============================
Number of graphs:1
Number of features:34
Number of classes:4
==============================
Data(x=[34, 34], edge_index=[2, 156], y=[34], train_mask=[34])

4.2.3 使用networkx进行可视化展示

import os
from torch_geometric.datasets import KarateClub
from torch_geometric.utils import to_networkx
import networkx as nx
import matplotlib.pyplot as plt


# 画图函数
def visualize_graph(G, color):
    plt.figure(figsize=(7, 7))
    plt.xticks([])
    plt.yticks([])
    nx.draw_networkx(G, pos=nx.spring_layout(G, seed=42), with_labels=False,
                     node_color=color, cmap="Set2")
    plt.show()


# 画点函数
def visualize_embedding(h, color, epoch=None, loss=None):
    plt.figure(figsize=(7, 7))
    plt.xticks([])
    plt.yticks([])
    h = h.detach().cpu().numpy()
    plt.scatter(h[:, 0], h[:, 1], s=140, c=color, cmap="Set2")
    if epoch is not None and loss is not None:
        plt.xlabel(f'Epoch:epoch,Loss:loss.item():.4f', fontsize=16)
    plt.show()


if __name__ == '__main__':
	# 不加这个可能会报错
    os.environ['KMP_DUPLICATE_LIB_OK'] = 'True'

    dataset = KarateClub()
    print(f'Dataset:dataset:')
    print('=' * 30)
    print(f'Number of graphs:len(dataset)')
    print(f'Number of features:dataset.num_features')
    print(f'Number of classes:dataset.num_classes')

    print('=' * 30)
    data = dataset[0]
    # train_mask = [True,False,...] :代表第1个点是有标签的,第2个点是没标签的,方便后面LOSS的计算
    print(data)  # Data(x=[节点数, 特征数], edge_index=[2, 边的条数], y=[节点数], train_mask=[节点数])

    G = to_networkx(data, to_undirected=True)
    visualize_graph(G, color=data.y)

可视化结果:

4.2.4 GCN模型搭建

import torch
from torch.nn import Linear
from torch_geometric.nn import GCNConv


class GCN(torch.nn.Module):
    def __init__(self, num_features, num_classes):
        super(GCN, self).__init__()
        torch.manual_seed(520)
        self.num_features = num_features
        self.num_classes = num_classes
        self.conv1 = GCNConv(self.num_features, 4)  # 只定义子输入特证和输出特证即可
        self.conv2 = GCNConv(4, 4)
        self.conv3 = GCNConv(4, 2)
        self.classifier = Linear(2, self.num_classes)

    def forward(self, x, edge_index):
        # 3层GCN
        h = self.convl(x, edge_index)  # 给入特征与邻接矩阵(注意格式,上面那种)
        h = h.tanh()
        h = self.conv2(h.edge_index)
        h = h.tanh()
        h = self.conv3(h, edge_index)
        h = h.tanh()
        # 分类层
        out = self.classifier(h)
        return out, h

4.2.5 使用搭建好的GCN模型

import os
import time

from torch_geometric.datasets import KarateClub
import networkx as nx
import matplotlib.pyplot as plt
import torch
from torch.nn import Linear
from torch_geometric.nn import GCNConv


# 画图函数
def visualize_graph(G, color):
    plt.figure(figsize=(7, 7))
    plt.xticks([])
    plt.yticks([])
    nx.draw_networkx(G, pos=nx.spring_layout(G, seed=42), with_labels=False,
                     node_color=color, cmap="Set2")
    plt.show()


# 画点函数
def visualize_embedding(h, color, epoch=None, loss=None):
    plt.figure(figsize=(7, 7))
    plt.xticks([])
    plt.yticks([])
    h = h.detach().cpu().numpy()
    plt.scatter(h[:, 0], h[:, 1], s=140, c=color, cmap="Set2")
    if epoch is not None and loss is not None:
        plt.xlabel(f'Epoch:epoch,Loss:loss.item():.4f', fontsize=16)
    plt.show()


class GCN(torch.nn.Module):
    def __init__(self, num_features, num_classes):
        super(GCN, self).__init__()
        torch.manual_seed(520)
        self.num_features = num_features
        self.num_classes = num_classes
        self.conv1 = GCNConv(self.num_features, 4)  # 只定义子输入特证和输出特证即可
        self.conv2 = GCNConv(4, 4)
        self.conv3 = GCNConv(4, 2)
        self.classifier = Linear(2, self.num_classes)

    def forward(self, x, edge_index):
        # 3层GCN
        h = self.conv1(x, edge_index)  # 给入特征与邻接矩阵(注意格式,上面那种)
        h = h.tanh()
        h = self.conv2(h, edge_index)
        h = h.tanh()
        h = self.conv3(h, edge_index)
        h = h.tanh()
        # 分类层
        out = self.classifier(h)
        return out, h


# 训练函数
def train(data):
    optimizer.zero_grad()
    out, h = model(data.x, data.edge_index)
    loss = criterion(out[data.train_mask], data.y[data.train_mask])
    loss.backward()
    optimizer.step()
    return loss, h


if __name__ == '__main__':
    # 不加这个可能会报错
    os.environ['KMP_DUPLICATE_LIB_OK'] = 'True'

    # 数据集准备
    dataset = KarateClub()
    data = dataset[0]

    # 声明GCN模型
    model = GCN(dataset.num_features, dataset.num_classes)

    # 损失函数 交叉熵损失
    criterion = torch.nn.CrossEntropyLoss()
    # 优化器 Adam
    optimizer = torch.optim.Adam(model.parameters(), lr=0.01)

    # 训练
    for epoch in range(401):
        loss, h = train(data)
        if epoch % 100 == 0:
            visualize_embedding(h, color=data.y, epoch=epoch, loss=loss)
            time.sleep(0.3)

输出图片:





五、文献引用数据集分类案例实战(基于点的任务)

5.1 数据集介绍

5.2 数据探索

from torch_geometric.datasets import Planetoid
from torch_geometric.transforms import NormalizeFeatures

if __name__ == "__main__":
    # 数据准备
    dataset = Planetoid(root='../data/Planetoid', name='Cora', transform=NormalizeFeatures())  # transform预处理
    data = dataset[0]
    print(f'Dataset:dataset:')
    print(f'Number of graphs:len(dataset)')
    print(f'Number of features:dataset.num_features')
    print(f'Number of classes:dataset.num_classes')
    print(查看详情  

《深入浅出图神经网络》gnn原理解析☄学习笔记神经网络基础(代码片段)

《深入浅出图神经网络》GNN原理解析☄学习笔记(二)神经网络基础文章目录《深入浅出图神经网络》GNN原理解析☄学习笔记(二)神经网络基础机器学习基本概念机器学习分类机器学习流程概述常见的损失函数... 查看详情

《深入浅出图神经网络:gnn原理解析》

 深入浅出图神经网络:GNN原理解析https://cread.jd.com/read/startRead.action?bookId=30567027&readType=1 作者:ZZU_chenhao仅仅是一名普通的研究生而已。原创 【学习日记】《深入浅出:图神经网络》:第四天---表示学习表示学习表... 查看详情

深入浅出图神经网络|gnn原理解析☄学习笔记表示学习(代码片段)

深入浅出图神经网络|GNN原理解析☄学习笔记(四)表示学习文章目录深入浅出图神经网络|GNN原理解析☄学习笔记(四)表示学习表示学习表示学习的意义离散表示与分布式表示端到端学习基于重构损失的方法—... 查看详情

《深入浅出图神经网络》gnn原理解析☄学习笔记卷积神经网络(代码片段)

《深入浅出图神经网络》GNN原理解析☄学习笔记(三)卷积神经网络文章目录《深入浅出图神经网络》GNN原理解析☄学习笔记(三)卷积神经网络卷积与池化信号处理中的卷积单通道卷积多通道卷积池化卷积神经... 查看详情

深入浅出图神经网络|gnn原理解析☄学习笔记图的概述(代码片段)

《深入浅出图神经网络》GNN原理解析☄学习笔记(一)图的概述文章目录《深入浅出图神经网络》GNN原理解析☄学习笔记(一)图的概述图的基本定义图的基本类型邻居和度子图与路径图的存储与遍历邻接矩阵和... 查看详情

人工智能中图神经网络gnn是什么?

...于:机器之心在社交网络分析等一些应用中,图神经网络已经得到了广泛的应用。新加坡科技研究局(A*STAR)的研究者RishabhAnand近日通过图解的方式介绍了图与图神经网络的基本概念,或许能帮助初学者更直... 查看详情

图神经网络学习笔记|基础知识与gnn介绍直观透彻理解

一、基础知识GNN是指使用神经网络来学习图结构数据,提取和挖掘图结构数据中有效的特征和模式,满足聚类、分类、预测、分割、生成、异常检测等图学习任务需求的算法总称。GCN实现了CNN在图上的平移不变、局部感知和权值... 查看详情

图机器学习(gml)&图神经网络(gnn)原理和代码实现(前置学习系列二)(代码片段)

...一展示,详情进入项目链接即可图机器学习(GML)&图神经网络(GNN)原理和代码实现(PGL 查看详情

作业车间问题的调度学习:使用图神经网络(gnn)和强化学习(rl)的表示和策略学习

相关研究:论文阅读|图神经网络+Actor-Critic求解静态JSP(End-to-EndDRL)《基于深度强化学习的调度规则学习》(附带源码)_太剧烈的快乐与太剧烈的悲哀是有相同之点的——同样地需要远离人群!-CSDN博客https://blog.... 查看详情

深度学习与图神经网络核心技术实践应用高级研修班-day3图神经网络(gnn)(代码片段)

图神经网络基础和基本思想1.图神经网络1.1图神经网络的定义和目标1.2图神经网络的思想和工作原理1.3图神经网络的应用场景2.图卷积神经网络2.1图卷积神经网络的定义2.2图卷积神经网络的卷积方式2.3卷积神经网络与图卷积神经... 查看详情

###haohaohao###图神经网络之神器——pytorchgeometric上手&实战(代码片段)

图神经网络(GraphNeuralNetworks,GNN)最近被视为在图研究等领域一种强有力的方法。跟传统的在欧式空间上的卷积操作类似,GNNs通过对信息的传递,转换和聚合实现特征的提取。这篇博客主要想分享下,怎样在... 查看详情

图神经网络gnn学习路径(代码片段)

...点。1.DL库及数据集1.1GNN通用DL库pyg和dgl是比较火的两个图神经网络仓库。但是用起来也有缺陷,比如使用比较流行的图数据集很方便,但是如果要自定义数据集,那就要对其数据集构建风格足够了解。因此对要使用新... 查看详情

图神经网络gnn学习路径(代码片段)

...点。1.DL库及数据集1.1GNN通用DL库pyg和dgl是比较火的两个图神经网络仓库。但是用起来也有缺陷,比如使用比较流行的图数据集很方便,但是如果要自定义数据集,那就要对其数据集构建风格足够了解。因此对要使用新... 查看详情

08-gnn图机器学习之图神经网络

图神经网络nodeembedding回顾了之前node2vec的例子以及深度学习卷积的一些基础浅层encoder的局限性:参数数量O(v):节点间没有共享参数,每个节点有自己的embedding不能表征未见过的节点没有综合考虑节点特征本节学习图神经网络,多... 查看详情

李宏毅机器学习|图神经网络graphnerualnetworks(gnn)|学习笔记-part1

...IN(GraphIsomorphismNetwork)前言最近看的论文里面主要是就是图神经网络GraphNerualNetworks,然后就来学习下李宏毅机器学习中的图神经网络的内容,记个笔记。视频地址1Introduction GNN简单来说就是Graph+NerualNetworks,关键问题就是... 查看详情

zz清华nlp图神经网络gnn论文分门别类,16大应用200+篇论文最新推荐

【清华NLP】图神经网络GNN论文分门别类,16大应用200+篇论文最新推荐图神经网络研究成为当前深度学习领域的热点。最近,清华大学NLP课题组JieZhou,GanquCui,ZhengyanZhangandYushiBai同学对GNN相关的综述论文、模型与应用进行了综述,并... 查看详情

深度之眼gnn图神经网络核心培养计划视频代码齐全

2012年,Kryzhevsky等人提出了AlexNet,展现出了卷积神经网络(CNN)在大规模图像分类任务上相较于其他机器学习方法的优势。此后不久,CNN和深度学习扩展至了计算机视觉的很多其他领域以及计算机视觉以外的... 查看详情