DGL官方教程--DGL图和节点/边的特征

Note:
Click here to download the full example code

DGLGraph and Node/edge Features

Author: Minjie Wang, Quan Gan, Yu Gai, Zheng Zhang

在本教程中,您将学习如何创建图形以及如何读写节点和边以及他们的表示。

Creating a graph

DGLGraph的设计受到其他图形库的影响。 您可以从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始终是有向的。

您还可以通过调用DGL接口来创建图形。

在下一个示例中,您将构建一个星形图。 DGLGraph节点是介于 0 0 0number_of_nodes()之间的连续整数范围,并且可以通过调用add_nodes来增长节点的数目。 DGLGraph的边缘按其添加顺序。 请注意,边缘的访问方式与节点几乎相同,但具有一项附加功能:边缘广播(edge broadcasting)

import dgl
import torch as th

g = dgl.DGLGraph()
g.add_nodes(10)
# 一个一个的添加边缘
for i in range(1, 4):
    g.add_edge(i, 0)
# 使用list批量添加边缘
src = list(range(5, 8)); dst = [0]*3
g.add_edges(src, dst)
# 通过一对 tensors进行边缘添加
src = th.tensor([8, 9]); dst = th.tensor([0, 0])
g.add_edges(src, dst)

# Edge broadcasting可以一次性构建一个星形图!
g.clear(); g.add_nodes(10)
src = th.tensor(list(range(1, 10)));
g.add_edges(src, 0)

import networkx as nx
import matplotlib.pyplot as plt
nx.draw(g.to_networkx(), with_labels=True)
plt.show()

在这里插入图片描述

Assigning a feature 分配特征

你可以为一个DGLgraph的边缘与节点分配特征。这些特征表示为名称(字符串的字典或者张量,称为字段。
以下代码段为每个节点分配了一个向量(len = 3)。

Note:
DGL的目标是与框架无关,并且目前支持PyTorch和MXNet张量。 以下示例仅使用PyTorch。

import dgl
import torch as th

x = th.randn(10, 3)
g.ndata['x'] = x#特征初始化
print(g.nodes[:].data['x'])#g.nodes[index]访问图中的任意节点,grpah.nodes[index].data[‘feat’],访问图中索引为index的node的特征向量

out:

tensor([[ 1.0989,  0.3419, -1.0445],
         [-0.9715, -1.7298,  0.0836],         
         [-0.5382, -0.2993,  0.1527],         
         [-0.9170, -1.2425,  0.3527],         
         [ 0.8964,  0.1867,  0.1127],         
         [ 0.9920, -1.1541,  0.1261],         
         [ 1.4054, -1.3463, -0.3350],         
         [ 1.0039,  0.6788,  0.1929],         
         [ 0.8373,  0.1658,  1.9415],         
         [-0.5668, -1.0294,  0.1013]])

ndata是用于访问所有节点状态的语法接口。 状态存储在承载用户定义的字典的容器data中。

print(g.ndata['x'] == g.nodes[:].data['x'])

# Access node set with integer, list, or integer tensor
g.nodes[0].data['x'] = th.zeros(1, 3)##将0号节点的特性修改为一个一行三列,元素为0的张量
g.nodes[[0, 1, 2]].data['x'] = th.zeros(3, 3)#批量修改0,1,2三个节点的‘X’特征
g.nodes[th.tensor([0, 1, 2])].data['x'] = th.zeros(3, 3)

Out:

tensor([[True, True, True],
         [True, True, True],
         [True, True, True],         
         [True, True, True],         
         [True, True, True],         
         [True, True, True],         
         [True, True, True],         
         [True, True, True],         
         [True, True, True],         
         [True, True, True]])

分配边的特征与节点特征相似,不同之处在于您还可以通过指定边缘的端点来进行分配。

g.edata['w'] = th.randn(9, 2)#边的特征初始化  
# 通过边的索引访问,修改feature tensor 
g.edges[1].data['w'] = th.randn(1, 2)#修改1号边的特征张量
#print(g.edges[:].data['w'])
#打印出所有边的特征张量 
g.edges[[0, 1, 2]].data['w'] = th.zeros(3, 2)#批量修改边的特征张量 
g.edges[th.tensor([0, 1, 2])].data['w'] = th.zeros(3, 2)#同上一行 
# 通过边两端连接的节点访问 
g.edges[1, 0].data['w'] = th.ones(1, 2)                 # edge 1 -> 0 
g.edges[[1, 2, 3], [0, 0, 0]].data['w'] = th.ones(3, 2) # edges [1, 2, 3] -> 0  
# shape,type 
g.ndata['x'] = th.zeros((10, 4)) 
#print(g.node_attr_schemes()) 
#print(g.ndata['x'])

分配后,每个节点或边字段将与包含其字段值的形状和数据类型(dtype)的方案关联。

print(g.node_attr_schemes())
g.ndata['x'] = th.zeros((10, 4))
print(g.node_attr_schemes())

Out:

{'x': Scheme(shape=(3,), dtype=torch.float32)} 
{'x': Scheme(shape=(4,), dtype=torch.float32)}

您也可以从图中删除节点或边的状态。 这对于在训练期间节省内存特别有用。

##g.ndata.pop('x')表示移除DGL图中节点的‘x’特征,g.edata.pop('w')表示移除DGL图中边的‘w’特征
g.ndata.pop('x') 
g.edata.pop('w')

Working with multigraphs

许多图形应用程序需要平行边。 为此,请使用multigraph = True构造DGLGraph

g_multi = dgl.DGLGraph(multigraph=True)#创建一个多图
g_multi.add_nodes(10)#添加10个节点
g_multi.ndata['x'] = th.randn(10, 2)#为每个节点添加特征张量

g_multi.add_edges(list(range(1, 10)), 0)#建立从1-9号,9个节点到0号节点的边
g_multi.add_edge(1, 0) # two edges on 1->0,再添加一条从1到0的边

g_multi.edata['w'] = th.randn(10, 2)#为每一个边添加特征张量
g_multi.edges[1].data['w'] = th.zeros(1, 2)#为编号为1的边添加特征张量
print(g_multi.edges())#输出两个张量,一个张量是边的开头,一个张量是边的截止

Out:

(tensor([1, 2, 3, 4, 5, 6, 7, 8, 9, 1]), tensor([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]))

多图的情况下(u,v)不能唯一的标识一条边,可以通过dege_id(u, v)来获得edge的唯一id,通过id来访问边特征.

eid_10 = g_multi.edge_id(1, 0) 
g_multi.edges[eid_10].data['w'] = th.ones(len(eid_10), 2) print(g_multi.edata['w'])

Out:

tensor([[ 1.0000,  1.0000],
         [ 0.0000,  0.0000],
         [-0.8381, -0.2076],         
         [-1.0214, -0.0418],         
         [-0.4424, -1.2469],         
         [ 0.3718, -0.7005],         
         [-0.3940,  0.8561],         
         [-0.5408,  0.1206],         
         [ 1.0355,  0.4003],         
         [ 1.0000,  1.0000]])

Note:
可以添加但不能删除节点和边。
更新不同方案的功能会增加单个节点(或节点子集)出错的风险。

Total running time of the script: ( 0 minutes 0.518 seconds)

下载代码:2_basic.py

下载代码:2_basic.ipynb

  • 6
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值