图神经网络dgl基础--个人笔记(1)

图神经网路: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])}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值