飞桨图神经网络七日打卡营----图采样学习心得
- 图采样算法详解
-
- GraphSAGE(SAmple & aggreGatE)
-
- PinSAGE(SAmple & aggreGatE)
- 图采样算法之后—邻居聚会
- 源码实现
- GraphSage采样函数实现
import numpy as np
def traverse(item):
"""traverse
"""
if isinstance(item, list) or isinstance(item, np.ndarray):
for i in iter(item):
for j in traverse(i):
yield j
else:
yield item
def flat_node_and_edge(nodes):
"""flat_node_and_edge
"""
nodes = list(set(traverse(nodes)))
return nodes
def my_graphsage_sample(graph, batch_train_samples, samples):
"""
输入:graph - 图结构 Graph
batch_train_samples - 中心节点 list (batch_size,)
samples - 采样时的最大邻节点数列表 list
输出:被采样节点下标的集合
对当前节点进行k阶采样后得到的子图
"""
start_nodes = batch_train_samples
nodes = start_nodes
edges = []
for max_deg in samples:
pred_nodes = graph.sample_predecessor(nodes,max_deg)
for dst_node, src_nodes in zip(nodes, pred_nodes):
for node in src_nodes:
edges.append((node, dst_node))
last_nodes = nodes
nodes = [nodes, pred_nodes]
nodes = flat_node_and_edge(nodes)
start_nodes = list(set(nodes) - set(last_nodes))
if len(start_nodes) == 0:
break
subgraph = graph.subgraph(
nodes=nodes,
edges=edges,
with_node_feat=False,
with_edge_feat=False)
return nodes, subgraph
- MaxPool Aggregator实现
import paddle.fluid as fluid
def my_graphsage_maxpool(gw,
feature,
hidden_size,
act,
name,
inner_hidden_size=512):
"""
输入:gw - GraphWrapper对象
feature - 当前节点表示 (num_nodes, embed_dim)
hidden_size - 新的节点表示维数 int
act - 激活函数名 str
name - 聚合函数名 str
inner_hidden_size - 消息传递过程中邻居信息的维数 int
输出:新的节点表示
"""
def copy_send(src_feat, dst_feat, edge_feat):
return src_feat["h"]
def maxpool_recv(feat):
return fluid.layers.sequence_pool(feat, pool_type="max")
neigh_feature = fluid.layers.fc(feature, inner_hidden_size, act="relu")
msg = gw.send(copy_send, nfeat_list=[("h", neigh_feature)])
neigh_feature = gw.recv(msg, maxpool_recv)
self_feature = feature
self_feature = fluid.layers.fc(self_feature,
hidden_size,
act=act,
name=name + '_l')
neigh_feature = fluid.layers.fc(neigh_feature,
hidden_size,
act=act,
name=name + '_r')
output = fluid.layers.concat([self_feature, neigh_feature], axis=1)
output = fluid.layers.l2_normalize(output, axis=1)
return output