PGL图学习之图游走类metapath2vec模型[系列五]

相关项目参考:

关于图计算&图学习的基础知识概览:前置知识点学习(PGL)[系列一] https://aistudio.baidu.com/aistudio/projectdetail/4982973?contributionType=1

图机器学习(GML)&图神经网络(GNN)原理和代码实现(前置学习系列二):https://aistudio.baidu.com/aistudio/projectdetail/4990947?contributionType=1

图学习【参考资料2】-知识补充与node2vec代码注解: https://aistudio.baidu.com/aistudio/projectdetail/5012408?forkThirdPart=1

图学习【参考资料1】词向量word2vec: [https://aistudio.baidu.com/aistudio/projectdetail/5009409?contributionType=1](https://aistudio.baidu.com/aistudio/projectdetail/5009409?contributionType=1

在这里插入图片描述

1.异质图

在图结构中有一个重要概念,同构图和异构图:

同构图:节点类型仅有一种的图

异构图:节点类型有多种的图,举例如下:

异质图介绍
在真实世界中,很多的图包含了多种类别节点和边,这类图我们称之为异质图。显然,同构图是异质图中的一个特例,边和节点的种类都是一。异质图比同构图的处理上更为复杂。
为了能够处理实际世界中的这大部分异质图,PGL进一步开发了图框架来对异质图模型的支持图神经网络的计算,新增了MetaPath采样支持异质图表示学习。

本节:

  • 举例异质图数据
  • 理解PGL是如何支持异质图的计算
  • 使用PGL来实现一个简单的异质图神经网络模型,来对异质图中特定类型节点分类。

PGL中引入了异质图的支持,新增MetaPath采样支持异质图表示学习,新增异质图Message Passing机制支持基于消息传递的异质图算法,利用新增的异质图接口,能轻松搭建前沿的异质图学习算法。

真实世界中的大部分图都存在着多种类型的边和节点。其中,电子交易网络就是非常常见的异质图。这种类型的图通常包含两种以上类型的节点(商品和用户等),和两以上的边(购买和点击等)。
接下来就用图例介绍,图中有多种用户点击或者购买商品。这个图中有两种节点,分别是“用户”和“商品”。同时包含了两种类型的边,“购买”和“点击”。

在这里插入图片描述

以及学术论文

在这里插入图片描述

1.1使用PGL创建一个异质图

在异质图中,存在着多种边,我们需要对它们进行区分。使用PGL可以用一下形式来表示边:

!pip install pgl
edges = {
        'click': [(0, 4), (0, 7), (1, 6), (2, 5), (3, 6)],
        'buy': [(0, 5), (1, 4), (1, 6), (2, 7), (3, 5)],
    }

clicked = [(j, i) for i, j in edges['click']]
bought = [(j, i) for i, j in edges['buy']]
edges['clicked'] = clicked
edges['bought'] = bought
# 在异质图中,节点也有不同的类型。因此你需要对每一个节点的类别进行标记,节点的表示格式如下:
node_types = [(0, 'user'), (1, 'user'), (2, 'user'), (3, 'user'), (4, 'item'), 
             (5, 'item'),(6, 'item'), (7, 'item')]
# 由于边的类型不同,边的特征要根据不同类别来区分。
import numpy as np
import paddle
import paddle.nn as nn
import pgl
from pgl import graph  # 导入 PGL 中的图模块
import paddle.fluid as fluid # 导入飞桨框架

seed = 0
np.random.seed(0)
paddle.seed(0)

num_nodes = len(node_types)

node_features = {'features': np.random.randn(num_nodes, 8).astype("float32")}

labels = np.array([0, 1, 0, 1, 0, 1, 1, 0])
# 在准备好节点和边后,可以利用PGL来构建异质图。
g = pgl.HeterGraph(edges=edges, 
                   node_types=node_types,
                   node_feat=node_features)

#如果遇到报错显示没有pgl.HeterGraph,重启项目即可
# 在构建了异质图后,我们可以利用PGL很轻松的实现信息传递范式。在这个例子中,我们有两种类型的边,所以我们定义如下的信息传递函数:
class HeterMessagePassingLayer(nn.Layer):
    def __init__(self, in_dim, out_dim, etypes):
        super(HeterMessagePassingLayer, self).__init__()
        self.in_dim = in_dim
        self.out_dim = out_dim
        self.etypes = etypes
        
        self.weight = []
        for i in range(len(self.etypes)):
            self.weight.append(
                 self.create_parameter(shape=[self.in_dim, self.out_dim]))
        
    def forward(self, graph, feat):
        def send_func(src_feat, dst_feat, edge_feat):
            return src_feat
        
        def recv_func(msg):
            return msg.reduce_mean(msg["h"])
        
        feat_list = []
        for idx, etype in enumerate(self.etypes):
            h = paddle.matmul(feat, self.weight[idx])
            msg = graph[etype].send(send_func, src_feat={"h": h})
            h = graph[etype].recv(recv_func, msg)
            feat_list.append(h)
            
        h = paddle.stack(feat_list, axis=0)
        h = paddle.sum(h, axis=0)
        
        return h
# 通过堆叠两个 HeterMessagePassingLayer 创建一个简单的 GNN。
class HeterGNN(nn.Layer):
    def __init__(self, in_dim, hidden_size, etypes, num_class):
        super(HeterGNN, self).__init__()
        self.in_dim = in_dim
        self.hidden_size = hidden_size
        self.etypes = etypes
        self.num_class = num_class
        
        self.layers = nn.LayerList()
        self.layers.append(
                HeterMessagePassingLayer(self.in_dim, self.hidden_size, self.etypes))
        self.layers.append(
                HeterMessagePassingLayer(self.hidden_size, self.hidden_size, self.etypes))
        
        self.linear = nn.Linear(self.hidden_size, self.num_class)
        
    def forward(self, graph, feat):
        h = feat
        for i in range(len(self.layers)):
            h = self.layers[i](graph, h)
            
        logits = self.linear(h)
        
        return logits
#训练
model = HeterGNN(8, 8, g.edge_types, 2)

criterion = paddle.nn.loss.CrossEntropyLoss()

optim = paddle.optimizer.Adam(learning_rate=0.05, 
                            parameters=model.parameters())

g.tensor()
labels = paddle.to_tensor(labels)
for epoch in range(10):
    #print(g.node_feat["features"])
    logits = model(g, g.node_feat["features"])
    loss = criterion(logits, labels)
    loss.backward()
    optim.step()
    optim.clear_grad()
    
    print("epoch: %s | loss: %.4f" % (epoch, loss.numpy()[0]))
W1114 10:59:14.283356   167 gpu_resources.cc:61] Please NOTE: device: 0, GPU Compute Capability: 7.0, Driver API Version: 11.2, Runtime API Version: 11.2
W1114 10:59:14.288399   167 gpu_resources.cc:91] device: 0, cuDNN Version: 8.2.


epoch: 0 | loss: 1.3536
epoch: 1 | loss: 1.1593
epoch: 2 | loss: 0.9971
epoch: 3 | loss: 0.8670
epoch: 4 | loss: 0.7591
epoch: 5 | loss: 0.6629
epoch: 6 | loss: 0.5773
epoch: 7 | loss: 0.5130
epoch: 8 | loss: 0.4782
epoch: 9 | loss: 0.4551

2. methpath2vec及其变种(原理)

上篇项目讲的deepwalk、node2vec两种方法都是在同构图中进行游走,如果在异构图中游走,会产生下面的问题:

  • 偏向于出现频率高的节点类型

  • 偏向于相对集中的节点(度数高的节点)

因此在异构图中采用methpath2vec算法。

metapath2vec: Scalable Representation Learning for Heterogeneous Networks

论文网址

项目主页

发表时间: KDD 2017

论文作者: Yuxiao Dong, Nitesh V. Chawla, Ananthram Swami

作者单位: Microsoft Research

Metapath2vec是Yuxiao Dong等于2017年提出的一种用于异构信息网络(Heterogeneous Information Network, HIN)的顶点嵌入方法。metapath2vec使用基于meta-path的random walks来构建每个顶点的异构邻域,然后用Skip-Gram模型来完成顶点的嵌入。在metapath2vec的基础上,作者还提出了metapath2vec++来同时实现异构网络中的结构和语义关联的建模。

methpath2vec中有元路径(meta path)的概念,含义就是在图中选取的节点类型构成的组合路径,这个路径是有实际意义的,例如以上面的异构图为例,A-P-A代表同一篇论文的两个作者,A-P-C-P-A代表两个作者分别在同一个会议上发表了两篇论文。

2.1前置重要概念:

2.1.1 网络嵌入;异构图/同构图

1)网络嵌入Network Embedding

针对网络嵌入的相关工作主要有两大部分构成,一部分是图嵌入,一部分是图神经网络。图嵌入方面的相关代表有Deepwalk、LINE、Node2vec以及NetMF,Deepwalk源于NLP(自然语言处理)方面的Word2vec,将Word2vec应用到社交网络体现出了良好的效果,LINE主要是针对大规模网络,Node2vec是在Deepwalk的随机游走上进行了改进,使得游走不再变得那么随机,使得其概率可控,具体就不做过多赘述。对于图神经网络,GCN通过卷积神经网络结合了邻居节点的特征表示融入到节点的表示中,GraphSAGE它就是一个典型的生成式模型,且它结合了节点的结构信息,而且,它不是直接为每个节点生成嵌入,而是生成一个可以表示节点嵌入的函数表示形式,这样的模型,也就是这种生成式模型,有助于它在训练期间对未观察到的节点进行归纳和判断。

2)同构Homogeneous与异构Heterogeneous

Heterogeneity:表示节点/边的单类还是多类

Heterogeneous/Heterogeneous:表示节点是单类还是多类

为了区分,论文添加了

  • Multiplex:表示边是单类还是多类
  • Attribute:是否是属性图,图的节点是否具有属性信息

根据图结构(同构/异构)以及是否包含节点特征,作者将图分为如下六类(缩写):

  • 同构图:HOmogeneous Network (or HON),
  • 属性同构图Attributed HOmogeneous Network (or AHON),
  • 点异构图HEterogeneous Network (orHEN),
  • 属性点异构图Attributed HEterogeneous Network (or AHEN),
  • 边异构图Multiplex HEterogeneous Network (or MHEN),
  • 带节点属性的异构图Attributed Multiplex HEterogeneous Network (or AMHEN)

论文归纳了以及每一种网络类型对应的经典的研究方法,如下表:

在这里插入图片描述

3)节点属性的异构图AMHEN

论文给出一个带节点属性的异构图的例子。在左侧原始的图中,用户包含了性别、年龄等属性,商品包含了价格、类目等属性。用户与商品之间包含了4种类型的边,分别对应点击、收藏、加入购物车以及购买行为。
在这里插入图片描述

传统的 graph embedding 算法比如 DeepWalk 的做法会忽略图中边的类型以及节点的特征,然后转换成一个 HON。

如果将边的类型考虑进去,那么就得到一个 MHEN,能够取得非常明显的效果。

此外,如果将节点的属性也同时考虑进去,那么就利用了原图的所有信息,可以得到最好的效果。

4)AMHEN嵌入难点

除了异构性和多样性外,处理 AMHEN 也面临着多重挑战:

  1. 多路复用的边(Multiplex Edges):每个节点对可能含有多种不同的类型边,如何将不同的关系边进行统一嵌入;
  2. 局部交互(Partial Observations): 存在大量的长尾客户(可能只与某些产品进行很少的交互);
  3. 归纳学习(Inductive):如何解决冷启动问题;
  4. 可扩展性(Scalability),如何拓展到大规模网络中。

2.1.2 信息网络(Information Network)

信息网络(Information Network)是指一个有向图 G=(V,E), 同时还有一个object类型映射函数 ϕ : V → A \phi : V \to \mathcal{A} ϕ:VA,边类型映射函数 ψ : E → R \psi : E \to \mathcal{R} ψ:ER。每一个object v ∈ V v \in V vV, 都有一个特定的object 类型 ϕ ( v ) ∈ A \phi (v) \in \mathcal{A} ϕ(v)A;每一条边 e ∈ E e \in E eE 都有一个特定的relation ψ ( e ) ∈ R \psi(e) \in \mathcal{R} ψ(e)R
异质网络(Heterogeneous Network)指的是object的类型 ∣ A ∣ > 1 |\mathcal{A}|>1 A>1或者relation的类型 ∣ R > 1 ∣ |\mathcal{R}>1| R>1

2.1.3 网络模式(Network schema)

网络模式(Network schema),定义为: T G = ( A , R ) T_G=(\mathcal{A,R}) TG=(A,R),是信息网络 G=(V, E)的一种 meta模板,这个信息网络有一个object类型映射函数 ϕ : V → A \phi : V \to \mathcal{A} ϕ:VA 和 link 类型映射函数 ψ : E → R \psi: E \to \mathcal{R} ψ:ER。信息网络G是一个定义在object类型 A \mathcal{A} A上的有向图,并且边是 R \mathcal{R} R中的relation。

在这里插入图片描述

2.1.4 元路径(Meta Path)

Meta Path 是2011年 Yizhou Sun etc. 在Mining Heterogeneous Information Networks: Principles and Methodologies提出的, 针对异质网络中的相似性搜索。Meta Path 是一条包含relation序列的路径,而这些 relation 定义在不同类型object之间。

元路径P是定义在网络模式TG = (A, R)上的,如 A 1 → R A 2 → R A 3 . . . → R A l + 1 A_1→^RA_2→^RA_3...→^RA_{l+1} A1RA2RA3...RAl+1表示了从 A 1 A_1 A1 A l + 1 A_{l+1} Al+1的复杂的关系, R = R 1 ∘ R 2 ∘ R 3 ∘ R l 。 R = R_1 ∘ R_2 ∘ R_3 ∘R_l。 R=R1R2R3Rl元路径P的长度即为关系R的个数.

确定元路径的意义在于我们会根据确定的元路径进行随机游走,如果元路径没有意义,会导致后续的训练过程中无法充分体现节点的意义,元路径通常需要人工进行筛选。

在基于元路径的游走过程中,只要首尾节点类型相同,就可以继续游走,直到达到最大游走长度或者找不到指定要求的节点。通常来说,元路径是对称的。

目前大部分的工作都集中在同构网络中,但真实场景下异构网络才是最常见的。针对同构网络设计的模型很多都没法应用于异构网络,比如说,对于一个学术网络而言:

  1. 如何高效根据上下文信息表征不同类型的节点?
  2. 能否用 Deepwalk 或者 Node2Vec 来学习网络中的节点?
  3. 能否直接将应用于同构网络的 Embedding 模型直接应用于异构网络?

解决诸如此类的挑战,有利于更好的在异构网络中应用多种网络挖掘任务:

  1. 传统的方法都是基于结构特征(如元路径 meta-path)来求相似性,类似的方法有 PathSim、PathSelClus、RankClass 等:
  2. 但这种方式挖掘出来的元路径(如 “APCPA”)经常会出现相似度为 0 的情况。如果我们能够将 Embedding 的思想应用于异构网络,则不会再出现这种情况。
  3. 基于这种观察,作者提出了两个可以应用于异构网络的 Graph Embedding 的算法模型——metapath2vec 以及 metapath2vec++。

问题定义Problem Definition

Definition 1: 异质网络(Heterogeneous Network):

G = ( V , E , T ) G = (V,E,T) G=(V,E,T),其中每个节点和边分别对应一个映射 ϕ ( v ) : V → T V \phi(v) : V \rightarrow T_{V} ϕ(v):VTV ψ ( e ) : E → T E \psi(e) : E \rightarrow T_{E} ψ(e):ETE。 其中 T V T_V TV T E T_E TE分别表示节点的类型集合以及关系的类型集合。且 ∣ T V ∣ + ∣ T E ∣ > 2 \left|T_{V}\right|+\left|T_{E}\right|>2 TV+TE>2

Definition 2: 异质网络表示学习(Heterogeneous Network Representation Learning):

给定一个异构网络,学习一个维的潜在表征可以表征网络中顶点之间的结构信息和语义场景关系。异构网络表征学习的输出是一个低维的矩阵,其中行是一个维的向量,表示顶点的表征。这里需要注意的是,虽然顶点的类型不同,但是不同类型的顶点的表征向量映射到同一个维度空间。由于网络异构性的存在,传统的基于同构网络的顶点嵌入表征方法很难有效地直接应用在异构网络上。异质网络中的节点学习一个 d d d维的表示 X ∈ R ∣ V ∣ × d \mathrm{X} \in \mathbb{R}^{|V| \times d} XRV×d d ≪ ∣ V ∣ d \ll|V| dV。节点的向量表示可以捕获节点间结构和语义关系。

2.2 Metapath2vec框架

在正式介绍metapath2vec方法之前,作者首先介绍了同构网络上的基于random walk的graph embedding算法的基本思想,如:Deepwalk和node2vec等。该类方法采用了类似word2vec的思想,即:使用skip-gram模型对每个顶点的局部领域顶点信息进行预测,进而学习到每个顶点的特征表示。通常,对于一个同构网络 G = ( V , E ) G = (V,E) G=(V,E),目标是从每个顶点的局部领域上最大化网络似然:
arg ⁡ max ⁡ θ ∏ v ∈ V ∏ c ∈ N ( v ) p ( c ∣ v ; θ ) \arg \max _{\theta} \prod_{v \in V} \prod_{c \in N(v)} p(c \mid v ; \theta) argθmaxvVcN(v)p(cv;θ)
其中 N ( v ) N(v) N(v) 表示顶点 v v v 的领域, 如1-hop以内的邻接页点, 2 -hop以内的邻接顶点。 p ( c ∣ v ; θ ) p(c \mid v ; \theta) p(cv;θ) 表 示给定顶点 v v v 后, 顶点 c c c 的条件概率。下面正式给出基于异构网络的metapath2vec嵌入算法。
metapath2vec分为两个部分,分别是Meta-Path-Based Random Walks和Heterogeneous Skip-Gram

2.2.1 Heterogeneous Skip-Gram

在metapath2vec中,作者使用Skip-Gram模型通过在顶点 v v v 的领域 N t ( v ) , t ∈ T V N_{t}(v), t \in T_{V} Nt(v),tTV 上最大化 条件概率来学习异构网络 G = ( V , E , T ) G=(V, E, T) G=(V,E,T) 上的顶点表征。
arg ⁡ max ⁡ θ ∑ v ∈ V ∑ t ∈ T V ∑ c t ∈ N t ( v ) log ⁡ p ( c t ∣ v ; θ ) \arg \max _{\theta} \sum_{v \in V} \sum_{t \in T_{V}} \sum_{c_{t} \in N_{t}(v)} \log p\left(c_{t} \mid v ; \theta\right) argθmaxvVtTVctNt(v)logp(ctv;θ)
其中 N t ( v ) N_{t}(v) Nt(v) 表示顶点 v v v 的类型为 t t t 的领域顶点集合。 p ( c t ∣ v ; θ ) p\left(c_{t} \mid v ; \theta\right) p(ctv;θ) 通常定义为一个softmax函数,
即:
p ( c t ∣ v ; θ ) = e X c t ⋅ X v ∑ u ∈ V e X u ⋅ X v p\left(c_{t} \mid v ; \theta\right)=\frac{e^{X_{c_{t}} \cdot X_{v}}}{\sum_{u \in V} e^{X_{u} \cdot X_{v}}} p(ctv;θ)=uVeXuXveXctXv

其中 X v X_{v} Xv 是矩阵 X X X 的第 v v v 行矩阵, 表示页点 v v v 的嵌入向量。为了提升参数更新效率 metapath2vec采用了Negative Sampling进行参数迭代更新, 给定一个Negative Sampling的大 小 M , M, M, 参数更新过程如下:
log ⁡ σ ( X c t ⋅ X v ) + ∑ m = 1 M E u m ∼ P ( u ) [ log ⁡ σ ( − X u m ⋅ X v ) ] \log \sigma\left(X_{c_{t}} \cdot X_{v}\right)+\sum_{m=1}^{M} \mathbb{E}_{u^{m} \sim P(u)}\left[\log \sigma\left(-X_{u^{m}} \cdot X_{v}\right)\right] logσ(XctXv)+m=1MEumP(u)[logσ(XumXv)]
其中 σ ( x ) = 1 1 + e − x \sigma(x)=\frac{1} {1+e^{-x}} σ(x)=1+ex1, $P(u)是一个negative node u m u^m um在M次采样中的预定义分布。
metapath2vec通过不考虑顶点的类型进行节点抽取来确定当前顶点的频率。

2.2.2Meta-Pathe-Based Random Walks

在同构网络中,DeepWalk和node2vec等算法通过随机游走的方式来构建Skip-Gram模型的上下文语料库,受此启发,作者提出了一种异构网络上的随机游走方式。在不考虑顶点类型和边类型的情况下, p ( v i + 1 ∣ v i ) p(v^{i+1}|v^i) p(vi+1vi)表示从顶点 v i v^i vi向其邻居顶点 v i + 1 v^{i+1} vi+1的转移概率。然而Sun等已证明异构网络上的随机游走会偏向于某些高度可见的类型的顶点,这些顶点的路径在网络中具有一定的统治地位,而这些有一定比例的路径指向一小部分节点的集合。鉴于此,作者提出了一种基于meta-path的随机游走方式来生成Skip-Gram模型的邻域上下文。该随机游走方式可以同时捕获不同类型顶点之间语义关系和结构关系,促进了异构网络结构向metapath2vec的Skip-Gram模型的转换。
  一个meta-path的scheme可以定义成如下形式:
V 1 ⟶ R 1 V 2 ⟶ R 2 … V t ⟶ R t V t + 1 … V l − 1 ⟶ R l − 1 V l V_{1} \stackrel{R_{1}}{\longrightarrow} V_{2} \stackrel{R_{2}}{\longrightarrow} \ldots V_{t} \stackrel{R_{t}}{\longrightarrow} V_{t+1} \ldots V_{l-1} \stackrel{R_{l-1}}{\longrightarrow} V_{l} V1R1V2R2VtRtVt+1Vl1Rl1Vl
其中
R = R 1 ∘ R 2 ∘ ⋯ ∘ R l − 1 R=R_{1} \circ R_{2} \circ \cdots \circ R_{l-1} R=R1R2Rl1
表示顶点 V 1 V_{1} V1 和顶点 V l V_{l} Vl 之间的路径组合。例如下图中, "APA"表示一种固定语义的metapath, "APVPA"表示另外一种固定语义的meta-path。并且很多之前的研究成果都表明, meta-path在很多异构网络数据挖掘中很很大作用。因此,在本文中,作者给出了基于meta-path的随机游走方式。给定一个异构网络 G = ( V , E , T ) G=(V, E, T) G=(V,E,T) 和一个meta-path的scheme P \mathcal{P} P :
V 1 ⟶ R 1 V 2 ⟶ R 2 … V t ⟶ R t V t ± 1 … V l − 1 ⟶ R l − 1 V l V_{1} \stackrel{R_{1}}{\longrightarrow} V_{2} \stackrel{R_{2}}{\longrightarrow} \ldots V_{t} \stackrel{R_{t}}{\longrightarrow} V_{t \pm 1} \ldots V_{l-1} \stackrel{R_{l-1}}{\longrightarrow} V_{l} V1R1V2R2VtRtVt±1Vl1Rl1Vl

在这里插入图片描述

那么在第 i i i 步的转移概率定义如下:
p ( v i + 1 ∣ v t i , P ) = { 1 ∣ N t + 1 ( v t i ) ∣ ( v i + 1 , v i ) ∈ E , ϕ ( v i + 1 ) = t + 1 0 ( v i + 1 , v i ) ∈ E , ϕ ( v i + 1 ) ≠ t + 1 0 ( v i + 1 , v i ) ∉ E p\left(v^{i+1} \mid v_{t}^{i}, \mathcal{P}\right)=\left\{\begin{array}{ll} \frac{1}{\left|N_{t+1}\left(v_{t}^{i}\right)\right|} & \left(v^{i+1}, v^{i}\right) \in E, \phi\left(v^{i+1}\right)=t+1 \\ 0 & \left(v^{i+1}, v^{i}\right) \in E, \phi\left(v^{i+1}\right) \neq t+1 \\ 0 & \left(v^{i+1}, v^{i}\right) \notin E \end{array}\right. p(vi+1vti,P)=Nt+1(vti)100(vi+1,vi)E,ϕ(vi+1)=t+1(vi+1,vi)E,ϕ(vi+1)=t+1(vi+1,vi)/E
其中 v t i ∈ V t , N t + 1 ( v t i ) v_{t}^{i} \in V_{t}, \quad N_{t+1}\left(v_{t}^{i}\right) vtiVt,Nt+1(vti) 表示页点 v t i v_{t}^{i} vti V t + 1 V_{t+1} Vt+1 类型的领域顶点集合。换言之, v i + 1 ∈ V t + 1 , v^{i+1} \in V_{t+1}, vi+1Vt+1, 也 就是说随机游走是在预定义的meta-path scheme P \mathcal{P} P 条件下的有偏游走。初次之外, meta-path 通常是以一种对称的方式来使用, 也就是说在上述路径组合中,顶点 V 1 V_{1} V1 的类型和 V l V_{l} Vl 的类型相同。即:
p ( v i + 1 ∣ v t i ) = p ( v i + 1 ∣ v l i ) ,  if  t = 1 p\left(v^{i+1} \mid v_{t}^{i}\right)=p\left(v^{i+1} \mid v_{l}^{i}\right), \text { if } \mathbf{t}=1 p(vi+1vti)=p(vi+1vli), if t=1
基于meta-path的随机游走保证不同类型顶点之间的语义关系可以适当的融入Skip-Gram模型中。

在这里插入图片描述

2.3 Metapath2vec++框架

methpath2vec的变种:

  • methpath2vec++:在负采样时考虑节点类型
  • multi-methpath2vec++:针对多条元路径进行游走
  • side info+multi-methpath2vec++:在获取元路径的基础上考虑了节点的特征

metapath2vec在为每个顶点构建领域时,通过meta-path来指导随机游走过程向指定类型的顶点进行有偏游走。但是在softmax环节中,并没有顶点的类型,而是将所有的顶点认为是同一种类型的顶点。换言之,metapath2vec在Negative Sampling环节采样的negative 样本并没有考虑顶点的类型,也就是说metapath2vec支持任意类型顶点的Negative Sampling。于是作者在metapath2vec的基础上又提出了改进方案metapath2vec++。

2.3.1Heterogeneous Negative Sampling

在metapath2vec++中, softmax函数根据不同类型的顶点的上下文 c t c_{t} ct 进行归一化。也就是说 p ( c t ∣ v ; θ ) p\left(c_{t} \mid v ; \theta\right) p(ctv;θ) 根据固定类型的页点进行调整。即:
p ( c t ∣ v ; θ ) = e X c t ⋅ X v ∑ u t ∈ V t e X u t ⋅ X v p\left(c_{t} \mid v ; \theta\right)=\frac{e^{X_{c_{t}} \cdot X_{v}}}{\sum_{u_{t} \in V_{t}} e^{X_{u_{t}} \cdot X_{v}}} p(ctv;θ)=utVteXutXveXctXv

其中 V t V_{t} Vt 是网络中 t t t 类型顶点集合。在这种情况下, metapath2vec++为Skip-Gram模型的输出层中的每种类型的领域指定了一个多项式分布的集合。而在metapath2vec, DeepWalk和node2vec中, Skip-Gram输出多项式分布的维度等于蜂个网络中顶点的数目,然而对于metapath2vec++的Skip-Gram, 其针对特定类型的输出多项式的维度取决于网络中当前类型顶点的数目。如下图示。

在这里插入图片描述

最终我们可以得到如下的目标函数:
O ( X ) = log ⁡ σ ( X c t ⋅ X v ) + ∑ m = 1 M E u t m ∼ P t ( u t ) [ log ⁡ σ ( − X u t m ⋅ X v ) ] O(X)=\log \sigma\left(X_{c_{t}} \cdot X_{v}\right)+\sum_{m=1}^{M} \mathbb{E}_{u_{t}^{m} \sim P_{t}\left(u_{t}\right)}\left[\log \sigma\left(-X_{u_{t}^{m}} \cdot X_{v}\right)\right] O(X)=logσ(XctXv)+m=1MEutmPt(ut)[logσ(XutmXv)]

可以得出其梯度如下:
∂ O ( X ) ∂ X u t m = ( σ ( X u t m ⋅ X v − I c t [ u t m ] ) ) X v ∂ O ( X ) ∂ X v = ∑ m = 0 M ( σ ( X u i ∗ n ⋅ X v − I c i [ u t m ] ) ) X v t m \begin{array}{c} \frac{\partial O(X)}{\partial X_{u_{t}^{m}}}=\left(\sigma\left(X_{u_{t}^{m}} \cdot X_{v}-\mathbb{I}_{c_{t}}\left[u_{t}^{m}\right]\right)\right) X_{v} \\ \frac{\partial O(X)}{\partial X_{v}}=\sum_{m=0}^{M}\left(\sigma\left(X_{u_{i}^{* n}} \cdot X_{v}-\mathbb{I}_{c_{i}}\left[u_{t}^{m}\right]\right)\right) X_{v_{t}^{m}} \end{array} XutmO(X)=(σ(XutmXvIct[utm]))XvXvO(X)=m=0M(σ(XuinXvIci[utm]))Xvtm
其中 I c t [ u t m ] \mathbb{I}_{c_{t}}\left[u_{t}^{m}\right] Ict[utm] 是一个指示函数, 用来指示 u t m u_{t}^{m} utm m = 0 , u t 0 = c t m=0, u_{t}^{0}=c_{t} m=0,ut0=ct 时是否是顶点 c t c_{t} ct 的上下文。该 算法使用随机梯度下降进行参数优化。整个metapath2vec++算法如下。

在这里插入图片描述

3.分布式图引擎(快速入门)

因为会存在许多无法在一台机器上加载的巨大图,例如社交网络和引文网络。为了处理这样的图,PGL 开发了一个分布式图引擎框架来支持大规模图网络上的图采样,以进行分布式 GNN 训练。

下面将介绍执行分布式图引擎以进行图采样的步骤。

如何启动分布式图引擎服务的示例:

  1. 假设我们有一个下图,它有两种类型的节点(u 和 t)。

  2. 首先,我们应该创建一个配置文件并指定每台机器的 ip 地址。 这里我们使用两个端口来模拟两台机器。

  3. 创建配置文件和 ip 地址文件后,我们现在可以启动两个图形服务器。

  4. 然后我们可以使用客户端从图服务器中采样邻居或采样节点。

# !pip install pgl
import os
import sys
import re
import time
import tqdm
import argparse
import unittest
import shutil
import numpy as np

from pgl.utils.logger import log

from pgl.distributed import DistGraphClient, DistGraphServer
edges_file = """37	45	0.34
37	145	0.31
37	112	0.21
96	48	1.4
96	247	0.31
96	111	1.21
59	45	0.34
59	145	0.31
59	122	0.21
97	48	0.34
98	247	0.31
7	222	0.91
7	234	0.09
37	333	0.21
47	211	0.21
47	113	0.21
47	191	0.21
34	131	0.21
34	121	0.21
39	131	0.21"""

node_file = """u	98
u	97
u	96
u	7
u	59
t	48
u	47
t	45
u	39
u	37
u	34
t	333
t	247
t	234
t	222
t	211
t	191
t	145
t	131
t	122
t	121
t	113
t	112
t	111"""


tmp_path = "./tmp_distgraph_test"
if not os.path.exists(tmp_path):
    os.makedirs(tmp_path)

with open(os.path.join(tmp_path, "edges.txt"), 'w') as f:
    f.write(edges_file)

with open(os.path.join(tmp_path, "node_types.txt"), 'w') as f:
    f.write(node_file)
# configuration file
config = """
etype2files: "u2e2t:./tmp_distgraph_test/edges.txt"
symmetry: True

ntype2files: "u:./tmp_distgraph_test/node_types.txt,t:./tmp_distgraph_test/node_types.txt"

"""

ip_addr = """127.0.0.1:8342
127.0.0.1:8343"""


with open(os.path.join(tmp_path, "config.yaml"), 'w') as f:
    f.write(config)
    
with open(os.path.join(tmp_path, "ip_addr.txt"), 'w') as f:
    f.write(ip_addr)
config = os.path.join(tmp_path, "config.yaml")

ip_addr = os.path.join(tmp_path, "ip_addr.txt")
shard_num = 10
gserver1 = DistGraphServer(config, shard_num, ip_addr, server_id=0)
gserver2 = DistGraphServer(config, shard_num, ip_addr, server_id=1)

client1 = DistGraphClient(config, shard_num=shard_num, ip_config=ip_addr, client_id=0)

client1.load_edges()
client1.load_node_types()
print("data loading finished")
I1114 14:08:04.593564   261 graph_py_service.cc:102] start to build server
I1114 14:08:04.593607   261 graph_py_service.cc:112] build server done
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pgl/distributed/helper.py:60: UserWarning: nfeat_info attribute is not existed, return None
  warnings.warn("%s attribute is not existed, return None" % attr)
I1114 14:08:04.594841   261 graph_py_service.cc:141] pserver-ptr created 
I1114 14:08:04.594894   261 common_graph_table.cc:1493] in graphTable initialize
I1114 14:08:04.594902   261 table.cc:81] accessor initializing: table_id: 0, accessor_name: CommMergeAccessor
I1114 14:08:04.594925   261 common_graph_table.cc:1506] in graphTable initialize over
I1114 14:08:04.595789   261 common_graph_table.cc:1547] got 2edge types in total
I1114 14:08:04.595795   261 common_graph_table.cc:1550] in initialize: get a edge_type u2e2t
I1114 14:08:04.595800   261 common_graph_table.cc:1550] in initialize: get a edge_type t2e2u
I1114 14:08:04.595804   261 common_graph_table.cc:1557] got 2node types in total
I1114 14:08:04.595810   261 common_graph_table.cc:1584]  init graph table type  table name cpu_graph_table
I1114 14:08:04.595813   261 common_graph_table.cc:1588] in init graph table shard num = 10 shard_idx0
I1114 14:08:04.595815   261 common_graph_table.cc:1593] in init graph table shard idx = 0 shard_start 0 shard_end 5
I1114 14:08:04.607513   261 graph_brpc_server.cc:119] servers peer2peer connection success:127.0.0.1:8342,127.0.0.1:8343,
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pgl/distributed/helper.py:60: UserWarning: node_batch_stream_shuffle_size attribute is not existed, return None
  warnings.warn("%s attribute is not existed, return None" % attr)
I1114 14:08:04.609443   261 graph_py_service.cc:102] start to build server
I1114 14:08:04.609468   261 graph_py_service.cc:112] build server done
I1114 14:08:04.609534   261 graph_py_service.cc:141] pserver-ptr created 
I1114 14:08:04.609572   261 common_graph_table.cc:1493] in graphTable initialize
I1114 14:08:04.609580   261 table.cc:81] accessor initializing: table_id: 0, accessor_name: CommMergeAccessor
I1114 14:08:04.609597   261 common_graph_table.cc:1506] in graphTable initialize over
I1114 14:08:04.610419   261 common_graph_table.cc:1547] got 2edge types in total
I1114 14:08:04.610426   261 common_graph_table.cc:1550] in initialize: get a edge_type u2e2t
I1114 14:08:04.610431   261 common_graph_table.cc:1550] in initialize: get a edge_type t2e2u
I1114 14:08:04.610435   261 common_graph_table.cc:1557] got 2node types in total
I1114 14:08:04.610440   261 common_graph_table.cc:1584]  init graph table type  table name cpu_graph_table
I1114 14:08:04.610443   261 common_graph_table.c/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pgl/distributed/dist_graph.py:180: UserWarning: node_batch_stream_shuffle_size is not specified, default value is 20000
  warnings.warn("node_batch_stream_shuffle_size is not specified, "
[INFO] 2022-11-14 14:08:04,615 [dist_graph.py:  212]:	load edges of type u2e2t from ./tmp_distgraph_test/edges.txt
c:1588] in init graph table shard num = 10 shard_idx1
I1114 14:08:04.610446   261 common_graph_table.cc:1593] in init graph table shard idx = 1 shard_start 5 shard_end 10
I1114 14:08:04.611663   261 graph_brpc_server.cc:119] servers peer2peer connection success:127.0.0.1:8342,127.0.0.1:8343,
I1114 14:08:04.613366   261 graph_py_service.cc:102] start to build server
I1114 14:08:04.613386   261 graph_py_service.cc:112] build server done
[INFO] 2022-11-14 14:08:04,618 [dist_graph.py:  222]:	load nodes of type u from ./tmp_distgraph_test/node_types.txt
I1114 14:08:04.617766   829 common_graph_table.cc:1105] 2/20 edges are loaded successfully in ./tmp_distgraph_test/edges.txt
[INFO] 2022-11-14 14:08:04,619 [dist_graph.py:  222]:	load nodes of type t from ./tmp_distgraph_test/node_types.txt


data loading finished


I1114 14:08:04.617785   809 common_graph_table.cc:1105] 18/20 edges are loaded successfully in ./tmp_distgraph_test/edges.txt
I1114 14:08:04.618180   794 common_graph_table.cc:1105] 12/20 edges are loaded successfully in ./tmp_distgraph_test/edges.txt
I1114 14:08:04.618256   838 common_graph_table.cc:1105] 8/20 edges are loaded successfully in ./tmp_distgraph_test/edges.txt
I1114 14:08:04.619464   856 common_graph_table.cc:990] 0 nodes are loaded from filepath
I1114 14:08:04.619477   856 common_graph_table.cc:991] u	34
I1114 14:08:04.619490   856 common_graph_table.cc:1019] 1/12 nodes in type u are loaded successfully in ./tmp_distgraph_test/node_types.txt
I1114 14:08:04.619515   808 common_graph_table.cc:990] 0 nodes are loaded from filepath
I1114 14:08:04.619529   808 common_graph_table.cc:991] u	98
I1114 14:08:04.619549   808 common_graph_table.cc:1019] 8/12 nodes in type u are loaded successfully in ./tmp_distgraph_test/node_types.txt
I1114 14:08:04.620455   808 common_graph_table.cc:990] 0 nodes are loaded from filepath
I1114 14:08:04.620469   808 common_graph_table.cc:991] u	34
I1114 14:08:04.620510   808 common_graph_table.cc:1019] 11/12 nodes in type t are loaded successfully in ./tmp_distgraph_test/node_types.txt
I1114 14:08:04.620549   805 common_graph_table.cc:990] 0 nodes are loaded from filepath
I1114 14:08:04.620563   805 common_graph_table.cc:991] u	98
I1114 14:08:04.620580   805 common_graph_table.cc:1019] 4/12 nodes in type t are loaded successfully in ./tmp_distgraph_test/node_types.txt
#  random sample nodes by node type
client1.random_sample_nodes(node_type="u", size=3)
[59, 39, 7]
# traverse all nodes from each server
node_generator = client1.node_batch_iter(batch_size=3, node_type="t", shuffle=True)
for nodes in node_generator:
    print(nodes)
[247, 145, 45]
[48]
[234, 191, 222]
[333, 211, 112]
[131, 111, 122]
[121, 113]
# sample neighbors
# note that the edge_type "u2eut" is defined in config.yaml file
nodes = [98, 7]
neighs = client1.sample_successor(nodes, max_degree=10, edge_type="u2e2t")
print(neighs)
[[247], [222, 234]]

4 methpath2vec(实践)

4.1数据集介绍

链接:https://ericdongyx.github.io/metapath2vec/m2v.html

将所有数据和代码下载到一个 zip 文件中—metapath2vec.zip 6.7 GB,包括以下 B、C、D、E 和 F 部分(DropBox |百度云)。

Bibtex:
@inproceedings{dong2017metapath2vec,
title={metapath2vec: 异构网络的可扩展表示学习},
author={Dong, Yuxiao and Chawla, Nitesh V and Swami, Ananthram},
booktitle={KDD '17},
pages={135- -144},
年份={2017},
组织={ACM}
}

引用:
Yuxiao Dong、Nitesh V. Chawla 和 Ananthram Swami。2017. metapath2vec:异构网络的可扩展表示学习。在 KDD’17 中。135–144。

原始网络数据

  1. AMiner计算机科学 (CS) 数据: CS 数据集由 1,693,531 名计算机科学家和 3,194,405 篇论文组成,来自 3,883 个计算机科学场所——包括会议和期刊——截至 2016 年。我们构建了一个异构协作网络,其中有是三种类型的节点:作者、论文和地点。

Citation: Jie Tang, Jing Zhang, Limin Yao, Juanzi Li, Li Zhang, and Zhong Su. 2008. ArnetMiner: Extraction and Mining of Academic Social Networks. In KDD’08. 990–998. Œ

  1. 数据库和信息系统(DBIS)数据: DBIS 数据集由 Sun 等人构建和使用。它涵盖了 464 个场所、其前 5000 位作者以及相应的 72,902 篇出版物。我们还从 DBIS 构建了异构协作网络,其中一个链接可以连接两位作者,一位作者和一篇论文,以及一篇论文和一个地点。

Citation: Yizhou Sun, Jiawei Han, Xifeng Yan, Philip S. Yu, and Tianyi Wu. 2011. Pathsim: Meta path-based top-k similarity search in heterogeneous information networks. In VLDB’11. 992–1003.

4.2 PGL实现metapath2vec算法

利用PGL来复现metapath2vec模型。和前面xxx2vec的方法类似,先做网络嵌入系数矩阵的训练,然后使用训练好的矩阵在做预测。

Dataset.py 包含了对图数据进行深度游走生成walks等接口

model.py 包含用于训练metapath2vec的skipgram模型定义

utils.py 包含了对配置文件config.yaml的读取接口

# 解压数据集
!unzip -o /home/aistudio/data/data177163/label.zip -d data
!unzip -o /home/aistudio/data/data177163/net_aminer.zip -d data
# 异构图游走生成walks,生成需要使用GPU环境,生成时间也要比较长,已经生成好在data_文件下
!unzip -o /home/aistudio/data/data177163/data_.zip -d data_
# !mv -f data_/home/aistudio/data_/* data_/
# !python sample.py -c config.yaml
!mkdir /home/aistudio/data/walks
!cp /home/aistudio/data_/out_aminer_CPAPC/walks/* /home/aistudio/data/walks
!cp /home/aistudio/data_/out_aminer_CPAPC/* /home/aistudio/data
cp: 略过目录'/home/aistudio/data_/out_aminer_CPAPC/walks'
!pip install pgl
# 下载数据集后,运行以下命令对数据进行预处理:
!python data_preprocess.py --config config.yaml
[INFO] 2022-11-14 14:40:14,580 [data_preprocess.py:   85]:	3883 venues have been loaded.
[INFO] 2022-11-14 14:40:17,631 [data_preprocess.py:   91]:	1693531 authors have been loaded.
[INFO] 2022-11-14 14:40:24,270 [data_preprocess.py:   98]:	3194405 papers have been loaded.
[INFO] 2022-11-14 14:40:36,860 [data_preprocess.py:  106]:	9323605 paper2author edges have been loaded.
[INFO] 2022-11-14 14:40:41,720 [data_preprocess.py:  111]:	3194405 paper2conf edges have been loaded.
[INFO] 2022-11-14 14:40:42,539 [data_preprocess.py:  118]:	saving node_types to ./graph_data/node_types.txt
100%|████████████████████████████| 4891819/4891819 [00:02<00:00, 1969575.02it/s]
[INFO] 2022-11-14 14:40:45,046 [data_preprocess.py:  125]:	saving paper2author edges to ./graph_data/paper2author_edges.txt
100%|████████████████████████████| 9323605/9323605 [00:07<00:00, 1299162.39it/s]
[INFO] 2022-11-14 14:40:52,280 [data_preprocess.py:  132]:	saving paper2conf edges to ./graph_data/paper2conf_edges.txt
100%|████████████████████████████| 3194405/3194405 [00:02<00:00, 1408762.74it/s]
[INFO] 2022-11-14 14:40:54,554 [data_preprocess.py:  138]:	saving author label to ./graph_data/author_label.txt
100%|██████████████████████████████| 246678/246678 [00:00<00:00, 1463788.81it/s]
[INFO] 2022-11-14 14:40:54,723 [data_preprocess.py:  144]:	saving conf label to ./graph_data/conf_label.txt
100%|█████████████████████████████████████| 133/133 [00:00<00:00, 393123.63it/s]

.txt
100%|█████████████████████████████████████| 133/133 [00:00<00:00, 393123.63it/s]

超参数

所有超参数都保存在config.yaml文件中,所以在训练之前,你可以打开config.yaml来修改你喜欢的超参数。

PGL 图形引擎启动

现在我们支持使用PGL Graph Engine分布式加载图数据。我们还开发了一个简单的教程来展示如何启动图形引擎

要启动分布式图服务,请按照以下步骤操作。

1)IP地址设置

第一步是为每个图形服务器设置 IP 列表。每个带有端口的 IP 地址代表一个服务器。在ip_list.txt文件中,我们为演示设置了 4 个 IP 地址如下:

127.0.0.1:8553
127.0.0.1:8554
127.0.0.1:8555
127.0.0.1:8556

2)通过 OpenMPI 启动图形引擎

在启动图形引擎之前,您应该在中设置以下超参数config.yaml:

etype2files: "p2a:./graph_data/paper2author_edges.txt,p2c:./graph_data/paper2conf_edges.txt"
ntype2files: "p:./graph_data/node_types.txt,a:./graph_data/node_types.txt,c:./graph_data/node_types.txt"
symmetry: True
shard_num: 100

然后,我们可以在 OpenMPI 的帮助下启动图形引擎。

mpirun -np 4 python -m pgl.distributed.launch --ip_config ./ip_list.txt --conf ./config.yaml --mode mpi --shard_num 100

手动启动图形引擎
如果您没有安装 OpenMPI,您可以手动启动图形引擎。

Fox 示例,如果我们要使用 4 个服务器,我们应该在 4 个终端上分别运行以下命令。

# terminal 3
python -m pgl.distributed.launch --ip_config ./ip_list.txt --conf ./config.yaml --shard_num 100 --server_id 3

# terminal 2
python -m pgl.distributed.launch --ip_config ./ip_list.txt --conf ./config.yaml --shard_num 100 --server_id 2

# terminal 1
python -m pgl.distributed.launch --ip_config ./ip_list.txt --conf ./config.yaml --shard_num 100 --server_id 1

# terminal 0
python -m pgl.distributed.launch --ip_config ./ip_list.txt --conf ./config.yaml --shard_num 100 --server_id 0

注意下属程序运行在终端先执行;server_id 0最后一个执行

that the server_id of 0 should be the last one to be launched.

#在终端执行!!!
# !python -m pgl.distributed.launch --ip_config ./ip_list.txt --conf ./config.yaml --shard_num 100 --server_id 3
# !python -m pgl.distributed.launch --ip_config ./ip_list.txt --conf ./config.yaml --shard_num 100 --server_id 2
# !python -m pgl.distributed.launch --ip_config ./ip_list.txt --conf ./config.yaml --shard_num 100 --server_id 1
# 注意下属程序运行在终端先执行;server_id 0最后一个执行
# !python -m pgl.distributed.launch --ip_config ./ip_list.txt --conf ./config.yaml --shard_num 100 --server_id 0
# 成功启动图形引擎后,您可以运行以下命令来训练模型。
!export CUDA_VISIBLE_DEVICES=0
!python train.py --config ./config.yaml --ip ./ip_list.txt

结果展示:

[INFO] 2022-11-14 15:25:59,685 [    train.py:   80]:	sec/batch: 0.013914 | Epoch: 9 | step: 64000 | train_loss: 0.481755
[INFO] 2022-11-14 15:26:13,563 [    train.py:   80]:	sec/batch: 0.013878 | Epoch: 9 | step: 65000 | train_loss: 0.484076
[INFO] 2022-11-14 15:26:27,441 [    train.py:   80]:	sec/batch: 0.013878 | Epoch: 9 | step: 66000 | train_loss: 0.479972
[INFO] 2022-11-14 15:26:41,493 [    train.py:   80]:	sec/batch: 0.014052 | Epoch: 9 | step: 67000 | train_loss: 0.482121
[INFO] 2022-11-14 15:26:55,440 [    train.py:   80]:	sec/batch: 0.013947 | Epoch: 9 | step: 68000 | train_loss: 0.477837
[INFO] 2022-11-14 15:26:58,543 [     walk.py:   79]:	total [19440] number walks in rank [1]
[INFO] 2022-11-14 15:26:58,543 [     pair.py:   68]:	total [1739294] pairs in rank [1]
[INFO] 2022-11-14 15:26:58,642 [     walk.py:   79]:	total [19440] number walks in rank [0]
[INFO] 2022-11-14 15:26:58,643 [     pair.py:   68]:	total [1739294] pairs in rank [0]
[INFO] 2022-11-14 15:26:58,770 [     walk.py:   79]:	total [19420] number walks in rank [2]
[INFO] 2022-11-14 15:26:58,770 [     pair.py:   68]:	total [1737473] pairs in rank [2]
[INFO] 2022-11-14 15:26:58,780 [     walk.py:   79]:	total [19360] number walks in rank [3]
[INFO] 2022-11-14 15:26:58,781 [     pair.py:   68]:	total [1731727] pairs in rank [3]
[INFO] 2022-11-14 15:27:09,312 [    train.py:   80]:	sec/batch: 0.013871 | Epoch: 9 | step: 69000 | train_loss: 0.480193
[INFO] 2022-11-14 15:27:14,978 [    train.py:   82]:	saving model in epoch 9

6.总结

介绍了异质图,利用pgl对metapath2vec、metapath2vec 进行了实现,并给出了多个框架版本的demo满足个性化需求

metapath2vec是一种用于异构网络中表示学习的算法框架,其中包含多种类型的节点和链接。给定异构图,metapath2vec 算法首先生成基于元路径的随机游走,然后使用 skipgram 模型训练语言模型。基于 PGL重现了 metapath2vec 算法,用于可扩展的表示学习。

在这里插入图片描述

参考资料


此文章为搬运
原项目链接

Logo

学大模型,用大模型上飞桨星河社区!每天8点V100G算力免费领!免费领取ERNIE 4.0 100w Token >>>

更多推荐