學(xué)習(xí)內(nèi)容:DGL - Get Started
討論問題
1. 如何借助networkx創(chuàng)建dgl圖袱衷?如何直接創(chuàng)建dgl圖
networkx可以將圖形可視化。
借助networkx創(chuàng)建dgl圖
import networkx as nx
import dgl
g_nx = nx.petersen_graph()
g_dgl = dgl.DGLGraph(g_nx)
直接創(chuàng)建dgl圖
import dgl
g = dgl.DGLGraph()
2. 如何添加結(jié)點和邊牛欢?
添加結(jié)點:
# add 34 nodes into the graph; nodes are labeled from 0~33
g.add_nodes(34)
添加邊:
邊緣在DGL是有方向的,讓邊具有雙向性
# add edges two lists of nodes: src and dst
src, dst = tuple(zip(*edge_list))
g.add_edges(src, dst)
# edges are directional in DGL; make them bi-directional
g.add_edges(dst, src)
3. 如何訪問結(jié)點的屬性嘁扼?
# access node set with integer, list, or integer tensor
g.nodes[0].data['x'] = th.zeros(1, 3)
g.nodes[[0, 1, 2]].data['x'] = th.zeros(3, 3)
g.nodes[th.tensor([0, 1, 2])].data['x'] = th.zeros(3, 3)
4. 訪問邊的屬性有哪兩種方法拷肌?
g.edata['w'] = th.randn(9, 2)
# access edge set with IDs in integer, list, or integer tensor
g.edges[1].data['w'] = th.randn(1, 2)
g.edges[[0, 1, 2]].data['w'] = th.zeros(3, 2)
g.edges[th.tensor([0, 1, 2])].data['w'] = th.zeros(3, 2)
# one can also access the edges by giving endpoints
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
5. 邊和點的屬性用什么數(shù)據(jù)結(jié)構(gòu)進(jìn)行存貯?邊和點屬性對應(yīng)的scheme包含哪些信息娜亿?
用字典來進(jìn)行存貯
#After assignments, each node/edge field will be associated with a scheme containing the shape and data type (dtype) of its field value.
print(g.node_attr_schemes())
g.ndata['x'] = th.zeros((10, 4))
print(g.node_attr_schemes())
對應(yīng)的scheme包含了形狀和數(shù)據(jù)類型
#Out:
{'x': Scheme(shape=(3,), dtype=torch.float32)}
{'x': Scheme(shape=(4,), dtype=torch.float32)}
6. 如何刪除邊或節(jié)點的屬性丽已?
#One can also remove node/edge states from the graph. This is particularly useful to save memory during inference.
g.ndata.pop('x')
g.edata.pop('w')
7. 什么叫multi graph。請舉出一個現(xiàn)實的例子
Multigraphs ~~~ Many graph applications need multi-edges.
許多圖的應(yīng)用都需要多邊买决。
構(gòu)造類:DGLGraph with multigraph=True
實際例子:
1沛婴、地圖,兩個地點之間在地圖上可能會有不同的路徑督赤。
2嘁灯、同學(xué)之間的關(guān)系:兩個同學(xué)可能有合作關(guān)系,合作論文躲舌,互相做實驗丑婿,但是做的事情是不同的。
8. 在dgl庫中没卸,message
和reduce
分別完成什么功能羹奉?
首先,我們使用DGL的內(nèi)置函數(shù)定義消息傳遞:
使用源節(jié)點“h”作為信息傳遞
def gcn_message(edges):
# The argument is a batch of edges.
# This computes a (batch of) message called 'msg' using the source node's feature 'h'.
return {'msg' : edges.src['h']}
定義消息累和函數(shù)约计。
def gcn_reduce(nodes):
# The argument is a batch of nodes.
# This computes the new 'h' features by summing received 'msg' in each node's mailbox.
return {'h' : torch.sum(nodes.mailbox['msg'], dim=1)}
9. 說明send诀拭, recv, update_all, copy_src
的功能煤蚌。
發(fā)送消息到所有邊
def pagerank_naive(g):
# Phase #1: send out messages along all edges.
for u, v in zip(*g.edges()):
g.send((u, v))
接受消息來計算新的頁面排名的值
# Phase #2: receive messages to compute new PageRank values.
for v in g.nodes():
g.recv(v)
通過所有的邊來獲取消息并更新所有的節(jié)點
def pagerank_level2(g):
g.update_all()
利用源結(jié)點的特征屬性來計算輸出
dgl.function.copy_src(src, out) is an edge UDF that computes the output using the source node feature data.
10. 使用builtin
函數(shù)有什么好處耕挨?
使用內(nèi)置函數(shù)的好處是:使用內(nèi)置函數(shù)细卧,比普通的Python實現(xiàn),速度要快一倍左右筒占。 代碼簡潔贪庙,提升性能。
11. 例子
Batched Graph Classification with DGL
在Classifier.forward()
中翰苫,設(shè)隱層1節(jié)點數(shù)為256止邮,隱層2節(jié)點數(shù)為266。輸入層節(jié)點為1革骨,對應(yīng)一個graph农尖,輸出層 節(jié)點為8,對應(yīng)8個類別良哲。一個batch的大小為32,圖的節(jié)點數(shù)為400筑凫。經(jīng)過以下變換后滑沧,h的維度是多少巍实?
- 調(diào)用 g.update_all 之前 :1
- g.update_all 之后 :1
- 經(jīng)過線性變換之后:256
- 再次調(diào)用g.update_all 之后 :256
- 再次經(jīng)過線性變換之后:266
- 調(diào)用dgl.mean_nodes之后 :266
- 調(diào)用classify之后:8