概述
图神经网路:DGL基础
DGL是一种用于简化图神经网络实现的包
1.构建图
import dgl
import torch
import numpy as np
# 构建图
src_idx = np.random.randint(0, 3, 5) # 起始节点的编号 5个节点,范围是[0,3]
dst_idx = np.random.randint(0, 3, 5) # 终止节点的编号
print(src_idx)
print(dst_idx)
G = dgl.graph((src_idx, dst_idx)) # 构建一个图
print(G)
print("nodes: ", G.num_nodes())
print("edges: ", G.num_edges())
# 增加图的节点特征
node_features = torch.rand(G.num_nodes(), 3) # 给每个节点 随机生成一个张量 1*3
G.ndata['X'] = node_features # 节点分配特征,X:名称,每个节点分配一个长度为3的向量
G.ndata['Y'] = node_features
# 查看图的边数据,和节点数据
print(G.edata, G.ndata)
2.apply_edges 方法、apply_nodes 方法
# 定义一个消息传递函数,函数指定一个 edges 对象,该对象具有:src、dst、data 三个属性。
# src: 这条边的sorce节点,src['x'] 表示sorce节点的x特征
# dst:这条边的destination节点
# data:这条边的属性,data['e']表示变得e特征
def fn_es(edges):
return {'e': edges.src['X'] + edges.dst['X']}
G.apply_edges(fn_es) # 增加边的信息,为起始节点到终止节点的X特征信息之和
print(G)
print(G.ndata, G.edata)
# 定义一个聚合函数,函数指定一个 nodes 对象,该对象具有:mailbox、data 属性。
# mailbox:存储了通过消息传递到节点的信息,这里暂时用不到
# data:保持了该节点的特征
def fn_ns(nodes):
print(nodes.mailbox) # 查看一下mailbox
return {'h': nodes.data['X'] + 1}
G.apply_nodes(fn_ns)
print(G.ndata, G.edata)
创建图形以及如何读写节点和边以及他们的表示
可以从networkx创建图形并将其转换为DGLGraph,反之亦然
import networkx as nx
import dgl
g_nx = nx.petersen_graph() # 使用networkx创建一个petersen grpah
g_dgl = dgl.DGLGraph(g_nx) # 将networkx grpah 转换 为DGLGraph # add direction,bidirectional
import matplotlib.pyplot as plt
plt.subplot(121) # 在画布上绘制子图,第一个‘1’代表共有一行,‘2’代表有两列,‘1’代表该图片将位于1号位置
nx.draw(g_nx, with_labels=True)
plt.subplot(122) # 在画布上绘制子图,在2号位置
nx.draw(g_dgl.to_networkx(), with_labels=True)
plt.show()
相同的图,但是DGLGraph是有向的
加节点、加边、及可视化图
# 构建图,添加节点和边
import networkx as nx
import dgl
import matplotlib.pyplot as plt
# 构建星型图
u = [0, 0, 0, 0, 0]
v = [1, 2, 3, 4, 5]
# 第一种方式,u和v的数组,他们是相同的长度
star1 = dgl.DGLGraph((u, v))
nx.draw(star1.to_networkx(), with_labels=True) # 可视化图
plt.show()
# star2 = dgl.DGLGraph((0, v))
# # 对于星型,是可以广播的
# nx.draw(star2.to_networkx(), with_labels=True)
# plt.show()
#
# # star3 = dgl.DGLGraph([(0, 1), (0, 2), (0, 3), (0, 4), (0, 5)])
# # # 直接枚举
# # nx.draw(star3.to_networkx(), with_labels=True)
# # plt.show()
# 也可以边构图,边加边,而不是在构造函数里面加边
g = dgl.DGLGraph() # 这是一张空白图
g.add_nodes(9) # 添加节点,注意一定要先加节点,后加边
for i in range(1, 8):
g.add_edge(0, i)
nx.draw(g.to_networkx(), with_labels=True)
plt.show()
图的创建,保存、加载
import dgl
import torch as th
from dgl.data.utils import save_graphs
g1 = dgl.DGLGraph()
g1.add_nodes(3)
g1.add_edges([0, 0, 0, 1, 1, 2], [0, 1, 2, 1, 2, 2]) # 建立六条边
g1.ndata["x"] = th.ones(3, 5) # 3个节点的embedding 大小为5的向量全1
g1.edata['y'] = th.zeros(6, 5) # 6条边的embedding
print(g1.ndata,g1.edata)
# 补充:添加边的方式
# g1.add_edges(th.tensor([3, 4, 5]), 1) # three edges: 3->1, 4->1, 5->1
# g1.add_edges(4, [7, 8, 9]) # three edges: 4->7, 4->8, 4->9
# g1.add_edges([1, 2, 3], [3, 4, 5]) # three edges: 1->3, 2->4, 3->5
g2 = dgl.DGLGraph()
g2.add_nodes(3)
g2.add_edges([0, 1, 2], [1, 2, 1])
g2.edata["e"] = th.ones(3, 4)
# 可以通过dgl.save_graphs保存图或图列表,然后可使用dgl.load_graphs将其加载
graph_labels = {"graph_sizes": th.tensor([3, 3])}
save_graphs("data/try1.bin", [g1, g2], graph_labels)
from dgl.data.utils import load_graphs
from dgl.data.utils import load_labels
# glist, label_dict = load_graphs("data/small.bin") # glist will be [g1, g2]
glist, label_dict = load_graphs("data/try1.bin", [0]) # glist will be [g1]
graph_sizes = load_labels("data/try1.bin")
print(glist)
# [DGLGraph(num_nodes=3, num_edges=6,
# ndata_schemes={'x': Scheme(shape=(5,), dtype=torch.float32)}
# edata_schemes={'y': Scheme(shape=(5,), dtype=torch.float32)})]
print(label_dict)
# {'graph_sizes': tensor([3, 3])}
print(graph_sizes)
# {'graph_sizes': tensor([3, 3])}
最后
以上就是长情口红为你收集整理的图神经网络dgl基础--个人笔记(1)的全部内容,希望文章能够帮你解决图神经网络dgl基础--个人笔记(1)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复