DGL官方教程--API--dgl.DGLGraph

本文详细介绍DGL图神经网络库的基本用法,包括图的创建、节点与边的添加、特征存储、消息传递等核心功能,以及如何利用DGL进行图数据的处理和分析。
部署运行你感兴趣的模型镜像

参考:https://docs.dgl.ai/en/latest/api/python/graph.html#

class dgl.DGLGraph(graph_data=None, node_frame=None, edge_frame=None, multigraph=None,
 readonly=False, sort_csr=False, batch_num_nodes=None, batch_num_edges=None, parent=None)

基本的图的类。

图的类存储节点,边及其特征。

DGL图始终是有方向的。可以使用两个双向边来表示无向图。

节点由从零开始的连续整数标识。

当给图添加边时,可以通过两个端点(u,v)或分配的整数id来指定边。边的ID是顺序自动分配,即,添加的第一个边的ID为0,第二个边的ID为1,依此类推。

节点和边的特征存储方式是:以“特征名”为键和以“特征数据”为值的字典(以张量表示)。

DGL图形接受多种格式的图形数据:

  • NetworkX图,
  • scipy 矩阵
  • DGLGraph。

如果输入图数据是DGLGraph,则构造的DGLGraph仅包含其图索引。

参数:
  • graph_data (graph data, optional)–用于初始化图形的数据。
  • node_frame (FrameRef, optional)–节点特征存储。
  • edge_frame (FrameRef, optional)–边缘特征存储。
  • multigraph (booloptional)–图形是否为多图数据。如果不存在,则将通过扫描整个图形来确定该标志。(默认值:None)
  • readonly (booloptional)–图形结构是否为只读(默认:False)。

例子

创建一个没有节点和边的空图。

>>> G = dgl.DGLGraph()

G可以通过几种方式生长。

节点:

添加N个节点:

>>> G.add_nodes(10)  # 10 isolated nodes are added

边:

一次添加一条边,

>>> G.add_edge(0, 1)

或多个边,

>>> G.add_edges([1, 2, 3], [3, 4, 5])  # three edges: 1->3, 2->4, 3->5

或从同一节点开始的多个边,

>>> G.add_edges(4, [7, 8, 9])  # three edges: 4->7, 4->8, 4->9

或指向同一节点的多个边

>>> G.add_edges([2, 6, 8], 5)  # three edges: 2->5, 6->5, 8->5

或使用张量类型的多个边

在这里,使用pytorch框架进行演示,一般可以适用于其他变化较小的框架。(例如,替换 torch.tensor为mxnet.ndarray)。

>>> import torch as th
>>> G.add_edges(th.tensor([3, 4, 5]), 1)  # three edges: 3->1, 4->1, 5->1

注意:DGLGraph不支持删除节点和边。

特征:

节点和边都可以具有特征数据。特征数据存储为键/值对。键必须是可选的,而值必须是张量类型。特征在第一维度上被批次化。(这里有点没懂。。。)

使用G.ndata获取/设置所有节点的特征

>>> G = dgl.DGLGraph()
>>> G.add_nodes(3)
>>> G.ndata['x'] = th.zeros((3, 5))  # init 3 nodes with zero vector(len=5)
>>> G.ndata
{'x' : tensor([[0., 0., 0., 0., 0.],
               [0., 0., 0., 0., 0.],
               [0., 0., 0., 0., 0.]])}
 

使用G.nodes获取/设置某些节点的特征

>>> G.nodes[[0, 2]].data['x'] = th.ones((2, 5))
>>> G.ndata
{'x' : tensor([[1., 1., 1., 1., 1.],
               [0., 0., 0., 0., 0.],
               [1., 1., 1., 1., 1.]])}

同样,使用G.edata和G.edges获取/设置边的特征。

>>> G.add_edges([0, 1], 2)  # 0->2, 1->2
>>> G.edata['y'] = th.zeros((2, 4))  # init 2 edges with zero vector(len=4)
>>> G.edata
{'y' : tensor([[0., 0., 0., 0.],
               [0., 0., 0., 0.]])}
>>> G.edges[1, 2].data['y'] = th.ones((1, 4))
>>> G.edata
{'y' : tensor([[0., 0., 0., 0.],
               [1., 1., 1., 1.]])}

 

注意,为每个边都分配了一个唯一的ID,该ID等于其添加顺序。因此,边(1-> 2)的ID为1。DGL支持直接使用边的ID访问边的特征。

>>> G.edges[0].data['y'] += 2.
>>> G.edata
{'y' : tensor([[2., 2., 2., 2.],
               [1., 1., 1., 1.]])}

 

讯息传递:

更新节点特征的一个常见操作是消息传递,其中源结点通过边向目的结点发送消息。在DGLGraph,我们可以使用send()recv()

在下面的示例中,源节点将节点特征做加1操作后,作为消息,并将消息发送到目标。

>>> #定义发送消息的函数。
>>> def send_source(edges): return {'m': edges.src['x'] + 1}
>>> #将这个函数定义为默认消息函数。
>>> G.register_message_func(send_source)
>>> #通过所有边 发送信息。
>>> G.send(G.edges())

 

就像您需要进入邮箱以检索邮件一样,目标节点也需要接收消息并可能更新其特征。

>>> #定义一个用于总结接收到的消息并替换原始特征的函数。
>>> def simple_reduce(nodes): return {'x': nodes.mailbox['m'].sum(1)}
>>> #定义为默认消息约简函数。
>>> G.register_reduce_func(simple_reduce)
>>> #所有现有边都以节点2作为目标。
>>> #节点2接收消息并更新其特征。
>>> G.recv(v=2)
>>> G.ndata
{'x': tensor([[1., 1., 1., 1., 1.],
              [0., 0., 0., 0., 0.],
              [3., 3., 3., 3., 3.]])} # 3 = (1 + 1) + (0 + 1)

 

有关消息传递的更多示例,请阅读我们的教程。

PS:下面函数API建议看官方的文档,有源码实现

网址:https://docs.dgl.ai/en/latest/api/python/graph.html#

添加节点和边

DGLGraph.add_nodes(* args,** kwargs) 
DGLGraph.add_edge(* args,** kwargs) 
DGLGraph.add_edges(* args,** kwargs) 
DGLGraph.clear()从图中删除所有节点和边线及其特征。

查询图结构

DGLGraph.number_of_nodes()返回图中的节点数。
DGLGraph.number_of_edges()返回图中的边数。
DGLGraph.__len__()返回图中的节点数。
DGLGraph.is_multigraph如果图形是多图,则为True,否则为False。
DGLGraph.has_node(vid)如果图形包含节点vid,则返回True 。
DGLGraph.has_nodes(vids)给定节点ID数组,返回一个包含0-1的数组a。
DGLGraph.__contains__(vid)如果图形包含节点vid,则返回True 。
DGLGraph.has_edge_between(u,v)如果边(u,v)在图中,则返回True。
DGLGraph.has_edges_between(u,v)给定源节点ID数组u和目标节点ID数组v,返回一个包含0-1的数组a。
DGLGraph.predecessors(v)返回图中的节点v的前继结点。
DGLGraph.successors(v)返回图中的节点v的后继结点。
DGLGraph.edge_id(u,v [,force_multi])返回源节点u和目标节点v之间的边的ID或边的ID数组。
DGLGraph.edge_ids(u,v [,force_multi])返回源节点数组u和目标节点数组v之间的所有边的ID 。
DGLGraph.find_edges(eid)给定一个边的ID数组,返回源和目标节点ID数组s和d。
DGLGraph.in_edges(v[, form])返回节点的入边。
DGLGraph.out_edges(v[, form])返回节点的出边。
DGLGraph.all_edges([form, order])返回所有边。
DGLGraph.in_degree(v)返回节点v的入度。
DGLGraph.in_degrees([v])返回节点数组v的入度数组。
DGLGraph.out_degree(v)返回节点v的出度。
DGLGraph.out_degrees([v])返回节点数组v的出度数组。

查询批处理汇总

DGLGraph.batch_size此批次中的图形数。
DGLGraph.batch_num_nodes此批次中每个图的节点数。
DGLGraph.batch_num_edges此批处理中每个图的边数。

查询子图/父图所属信息

DGLGraph.parent如果当前图是父图的子图,则返回其父图,否则返回None。

删除节点和边

DGLGraph.remove_nodes(* args,** kwargs) 
DGLGraph.remove_edges(* args,** kwargs) 

改造图

DGLGraph.subgraph(nodes)返回在给定节点上导出的子图。
DGLGraph.subgraphs(nodes)返回一个子图列表,每个子图在列表中相应的给定节点中诱导。
DGLGraph.edge_subgraph(edges[,preserve_nodes])返回在给定边上导出的子图。
DGLGraph.line_graph([backtracking, shared])返回此图的折线图。
DGLGraph.reverse([share_ndata,share_edata])返回此图的反面。
DGLGraph.readonly([readonly_state])设置此图的只读状态。
DGLGraph.flatten()删除该图的所有批处理信息,并将当前图视为一个独立图,而不是一个批处理图。
DGLGraph.detach_parent()从其父级分离当前图,并将当前图视为独立图而不是子图。

从/转换为其他格式

DGLGraph.to_networkx([node_attrs,edge_attrs])转换为networkx图。
DGLGraph.from_networkx(nx_graph [,…])从networkx图转换。
DGLGraph.from_scipy_sparse_matrix(spmat [,…])从scipy稀疏矩阵转换。
DGLGraph.adjacency_matrix([transpose, ctx])返回此图的邻接矩阵表示。
DGLGraph.adjacency_matrix_scipy([transpose, …])返回此图的scipy邻接矩阵表示形式。
DGLGraph.incidence_matrix(typestr[, ctx])返回此图的关联矩阵表示。

使用节点/边缘特征

DGLGraph.nodes返回可用于设置/获取要素数据的节点视图。
DGLGraph.edges返回可用于设置/获取要素数据的边视图。
DGLGraph.ndata返回所有节点的数据视图。
DGLGraph.edata返回所有边的数据视图。
DGLGraph.node_attr_schemes()返回节点特征方案。
DGLGraph.edge_attr_schemes()返回边缘特征方案。
DGLGraph.set_n_initializer(initializer[, field])为空节点功能设置初始化程序。
DGLGraph.set_e_initializer(initializer[, field])为空边缘特征设置初始值设定项。
DGLGraph.local_var()返回可以在局部函数范围内使用的图形对象。
DGLGraph.local_scope()输入此图的本地范围上下文。

使用DGLGraph计算

DGLGraph.register_message_func(func)注册全局消息功能。
DGLGraph.register_reduce_func(func)注册全局消息减少功能。
DGLGraph.register_apply_node_func(func)注册全局节点应用功能。
DGLGraph.register_apply_edge_func(func)注册全局边缘应用功能。
DGLGraph.apply_nodes([func,v,inplace])在节点上应用功能以更新其功能。
DGLGraph.apply_edges([func, edges, inplace])在边缘应用功能以更新其功能。
DGLGraph.group_apply_edges(group_by,func [,…])按节点对边缘进行分组,然后将功能应用到分组的边缘上
DGLGraph.send([edges,message_func])沿给定的边缘发送消息。
DGLGraph.recv([v,reduce_func,…])接收和减少传入消息并更新节点的功能 vv。
DGLGraph.send_and_recv(edges[, …])沿边缘发送消息,并让目的地接收它们。
DGLGraph.pull(v [,message_func,…])从节点的前任提取消息,然后更新其功能。
DGLGraph.push(u [,message_func,…])将消息从节点发送到其后继节点并进行更新。
DGLGraph.update_all([message_func,...])通过所有边缘发送消息并更新所有节点。
DGLGraph.prop_nodes(nodes_generator [,…])通过pull()在节点上触发,使用图遍历传播消息。
DGLGraph.prop_edges(edges_generator [,…])通过send_and_recv()边沿触发使用图遍历传播消息。
DGLGraph.filter_nodes(predicate[, nodes])返回满足给定谓词的节点ID的张量。
DGLGraph.filter_edges(predicate[, edges])返回满足给定谓词的边缘ID的张量。
DGLGraph.to(ctx)将ndata和edata都移动到目标模式(cpu / gpu)与框架无关

批处理和Unbatch 

batch(graph_list [,node_attrs,edge_attrs])批处理的一个集合DGLGraph并返回一个DGLGraph独立于的批处理对象,graph_list以便可以同时对一批图形执行消息传递和读出,返回图形的批大小为的长度graph_list
unbatch(graph)返回此批处理中的图形列表。

子图和父图之间的映射

DGLGraph.parent_nid获取父节点ID。
DGLGraph.parent_eid获取父边缘ID。
DGLGraph.map_to_subgraph_nid(parent_vids)将父图中的节点ID映射到子图中的节点ID。

在子图和父图之间同步功能

DGLGraph.copy_from_parent()从父图中复制节点/边缘特征。
DGLGraph.copy_to_parent([inplace])将节点/边特征写入父图。

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

<think>我们有两个警告信息:一个是关于创建图的方式,另一个是关于TypedStorage的弃用。 1. DGLWarning: 建议使用 `dgl.graph(data)` 而不是 `dgl.DGLGraph(data)` 来创建图。 2. UserWarning: TypedStorage已被弃用,将来会被移除,UntypedStorage将成为唯一的存储类。 解决方案: 1. 对于DGL图创建:将代码中的 `dgl.DGLGraph(data)` 替换为 `dgl.graph(data)`。 2. 对于TypedStorage警告:这个警告来自PyTorch,通常是因为使用了`tensor.storage()`方法。应将其替换为`tensor.untyped_storage()`。但请注意,这个警告可能来自DGL内部,所以我们需要等待DGL更新以适配PyTorch的最新变更。同时,如果我们的代码中没有直接使用storage,可以暂时忽略。 但是,如果用户希望消除这些警告,可以采取以下措施: 步骤1:修改图创建方式 将原来的: g = dgl.DGLGraph() 或 g = dgl.DGLGraph(data) 改为: g = dgl.graph(data) 步骤2:抑制警告(不推荐,但可作为临时措施) 如果第二个警告来自DGL内部,我们无法直接修改,可以选择忽略警告: ```python import warnings warnings.filterwarnings("ignore", message="TypedStorage is deprecated") ``` 然而,更好的做法是检查是否有新版本的DGL已经修复了这个问题,并升级DGL。 根据用户之前安装的DGL版本(1.1.0),我们可以查看是否有更新的版本修复了该问题。 由于用户使用的是PyTorch 2.8.0+cu126,我们可以尝试升级DGL到最新版本(目前最新为1.1.x,但需要确认是否有1.1.1或更高版本)。 升级命令: ```bash pip install --upgrade dgl -f https://data.dgl.ai/wheels/cu126/repo.html ``` 如果最新版本已经修复,则升级后警告会消失。 如果问题仍然存在,并且用户不想看到警告,可以暂时忽略,因为这两个警告不会影响程序运行。 示例修改代码: 原代码可能如下: ```python import dgl # 旧的创建图方式 g = dgl.DGLGraph() g.add_nodes(3) g.add_edges([0, 1], [1, 2]) ``` 修改为: ```python import dgl # 新的创建图方式 u = torch.tensor([0, 1]) v = torch.tensor([1, 2]) g = dgl.graph((u, v), num_nodes=3) ``` 或者使用更简洁的方式(如果节点数可以从边推断): ```python g = dgl.graph(([0, 1], [1, 2])) ``` 关于TypedStorage的警告,如果出现在DGL库内部,我们只能等待DGL更新。但我们可以检查自己的代码中是否有使用storage的地方,并进行替换。 例如,将: ```python storage = tensor.storage() ``` 替换为: ```python storage = tensor.untyped_storage() ``` 注意:在PyTorch 2.0+中,TypedStorage已被标记为弃用。 因此,总结解决方案: 1. 修改图创建方式。 2. 升级DGL到最新兼容版本(确保与PyTorch 2.8.0兼容)。 3. 检查并修改自己的代码中关于storage的使用。 4. 如果警告来自DGL内部,且暂时无法解决,可以忽略警告(使用warnings.filterwarnings)。 提供代码示例: 修改图创建方式: ```python # 旧方式(不推荐) # g = dgl.DGLGraph() # g.add_nodes(3) # g.add_edges([0, 1], [1, 2]) # 新方式(推荐) import torch u = torch.tensor([0, 1]) v = torch.tensor([1, 2]) g = dgl.graph((u, v), num_nodes=3) # 可以指定节点数,也可以不指定(自动推断) ``` 忽略警告(如果必要): ```python import warnings # 忽略DGL关于图创建的警告(可能已经按照新方式创建,所以不需要忽略,但这里针对的是弃用警告) warnings.filterwarnings("ignore", category=dgl.DGLWarning, message="Recommend creating graphs by `dgl.graph\(data\)` instead of `dgl.DGLGraph\(data\)`") # 忽略TypedStorage的弃用警告 warnings.filterwarnings("ignore", message="TypedStorage is deprecated") ``` 但是,忽略警告不是最佳实践,我们应优先考虑代码更新。 最后,根据问题提出3-5个相关问题。</think>### 解决 DGL 警告和 PyTorch 弃用警告的方案 #### 1. 解决 DGL 图创建方式警告 ```python # 不推荐的方式(会触发警告) g = dgl.DGLGraph(data) # 推荐的新方式(消除警告) g = dgl.graph(data) # 直接使用 dgl.graph 构造函数 ``` #### 2. 解决 PyTorch TypedStorage 弃用警告 ```python # 弃用的方式(会触发警告) storage = tensor.storage() # 推荐的新方式(兼容未来版本) storage = tensor.untyped_storage() # 使用 untyped_storage 替代 ``` #### 3. 完整代码修改示例 ```python import dgl import torch import warnings # 忽略特定警告(可选,推荐先尝试修复代码) warnings.filterwarnings("ignore", category=UserWarning, message="TypedStorage is deprecated") warnings.filterwarnings("ignore", category=dgl.DGLWarning) # 创建图的正确方式 src = torch.tensor([0, 1, 2]) dst = torch.tensor([1, 2, 3]) g = dgl.graph((src, dst)) # 使用 dgl.graph 而非 dgl.DGLGraph # 处理张量存储的正确方式 tensor_data = torch.randn(5) storage = tensor_data.untyped_storage() # 使用 untyped_storage print(f"Storage size: {storage.size()}") ``` ### 根本原因分析 1. **DGLWarning 原因**: - DGL 0.8+ 版本弃用了 `dgl.DGLGraph()` 构造函数 - 推荐直接使用 `dgl.graph()` 创建图对象 - 这是库的API演进,不影响功能但需更新代码风格 2. **TypedStorage 弃用原因**: - PyTorch 2.1+ 开始弃用 TypedStorage - 将在未来版本中完全移除 - 所有存储操作应迁移到 untyped_storage ### 预防措施 1. **版本兼容性检查**: ```python print(f"DGL version: {dgl.__version__}") print(f"PyTorch version: {torch.__version__}") # 检查最小兼容版本 assert dgl.__version__ >= "0.8.0", "请升级DGL到0.8.0+" assert torch.__version__ >= "1.13.0", "请升级PyTorch到1.13.0+" ``` 2. **自动化代码迁移工具**: ```bash # 使用2to3工具迁移旧代码(示例) 2to3 -w -f dgl_graph_constructor your_script.py ```
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值