公式ドキュメント学DGLフレームワークの翌日-DGLGraphとノード/エッジフィーチャー


主な参考:https://docs.dgl.ai/tutorials/basics/2_basics.html
DGLGraphで図を作成する方法
図を作成する場合は、次の方法があります.
1)dgl.DGLGraph(g_nx)
まずnetworkxで図を作成し、DGLGraph形式に変換できます.DGLGraphの図はnetworkx形式に変換することもできます.デモコードは次のとおりです.
import networkx as nx
import dgl

g_nx = nx.petersen_graph()
g_dgl = dgl.DGLGraph(g_nx)

import matplotlib.pyplot as plt
plt.subplot(121)
nx.draw(g_nx, with_labels=True)
plt.subplot(122)
nx.draw(g_dgl.to_networkx().to_undirected(), with_labels=True)

plt.show()

1.dglを使うだけです.DGLGraph(g_nx)はnetworkxの図をDGLGraphに変換することができる.逆過程はg_dgl.to_networkx()
2.右の図に矢印があるのはg_dgl自体は有向図であり、無向図に移行すると矢印がない:g_dgl.to_networkx().to_undirected()
2)dgl.DGLGraph((u, v))
ここで、uとvはそれぞれヘッダノードとテールノードを格納し、デモコードは以下の通りである.
import torch as th

# Create a star graph from a pair of arrays (using ``numpy.array`` works too).
u = th.tensor([0, 0, 0, 0, 0])
v = th.tensor([1, 2, 3, 4, 5])
star1 = dgl.DGLGraph((u, v))

3)dgl.DGLGraph(adj)
図の隣接行列adjをscipy疎行列で表す.デモコードは次のとおりです.
import numpy as np
import scipy.sparse as spp

# Create the same graph from a scipy sparse matrix (using ``scipy.sparse.csr_matrix`` works too).
adj = spp.coo_matrix((np.ones(len(u)), (u.numpy(), v.numpy())))
star3 = dgl.DGLGraph(adj)

4)ポイント毎にエッジ毎に図を構築する
i)エッジを追加するたびにg.add_edge(src,dst),srcはヘッダノード,dstはテールノードである.
g = dgl.DGLGraph()
g.add_nodes(10)
# A couple edges one-by-one
for i in range(1, 4):
    g.add_edge(i, 0)

ii)一度に複数のエッジを追加するg.add_edges([src1, src2, …], [dst1, dst2, …]).
# A few more with a paired list
src = list(range(5, 8)); dst = [0]*3
g.add_edges(src, dst)
# finish with a pair of tensors
src = th.tensor([8, 9]); dst = th.tensor([0, 0])
g.add_edges(src, dst)

iii)あるノードを指す複数のエッジを一度に追加し、g.add_edges([src1, src2, …], dst).
# Edge broadcasting will do star graph in one go!
g = dgl.DGLGraph()
g.add_nodes(10)
src = th.tensor(list(range(1, 10)));
g.add_edges(src, 0)

ポイントにフィーチャーを割り当てるには
1)すべてのポイントに一度にフィーチャーを割り当てることができます.
import torch as th

x = th.randn(10, 3)
g.ndata['x'] = x

2)特定のポイントに対して個別にフィーチャーを割り当てることもできます.
g.ndata['x'][0] = th.zeros(1, 3)
g.ndata['x'][[0, 1, 2]] = th.zeros(3, 3)
g.ndata['x'][th.tensor([0, 1, 2])] = th.randn((3, 3))

エッジにフィーチャーを割り当てる
1)すべてのエッジに一度にフィーチャーを割り当てることができます
g.edata['w'] = th.randn(9, 2)

2)特定のエッジに個別にフィーチャーを割り当てることもできます.
# Access edge set with IDs in integer, list, or integer tensor
g.edata['w'][1] = th.randn(1, 2)
g.edata['w'][[0, 1, 2]] = th.zeros(3, 2)
g.edata['w'][th.tensor([0, 1, 2])] = th.zeros(3, 2)

3)端点でフィーチャーを割り当てるエッジを指定することもできます.
# You can get the edge ids by giving endpoints, which are useful for accessing the features.
g.edata['w'][g.edge_id(1, 0)] = th.ones(1, 2)                   # edge 1 -> 0
g.edata['w'][g.edge_ids([1, 2, 3], [0, 0, 0])] = th.ones(3, 2)  # edges [1, 2, 3] -> 0
# Use edge broadcasting whenever applicable.
g.edata['w'][g.edge_ids([1, 2, 3], [0, 0, 0])] = th.ones(3, 2)          # edges [1, 2, 3] -> 0

点またはエッジフィーチャーのshapeとdtypeの表示
print(g.node_attr_schemes())

点またはエッジのフィーチャーを削除するには
g.ndata.pop('x')
g.edata.pop('w')

マルチグラフ
DGLGraphのデフォルトでは、2つのノード間で複数の平行エッジが許可されるマルチマップがサポートされています.
1)平行エッジを追加するには、元の図面でadd_を実行するだけです.edge(src,dst)でいいです.
g_multi = dgl.DGLGraph()
g_multi.add_nodes(10)
g_multi.ndata['x'] = th.randn(10, 2)

g_multi.add_edges(list(range(1, 10)), 0)
g_multi.add_edge(1, 0) # two edges on 1->0

g_multi.edata['w'] = th.randn(10, 2)

2)平行エッジにアクセスするにはedge_id
原文は「,,eid_10 = g_multi.edge_id(1,0,return_uv=True)',実行時にエラーが発生しますので'eid_に変更してみます10 = g_multi.edge_ids(1,0)’は、実行できます(sがあることに注意してください).また、平行エッジのフィーチャーを修正し、'g_を使用します.multi.edata[‘w’][g_multi.edge_ids(1, 0)] = th.ones(len(eid_10),2)'でもよい.
# _, _, eid_10 = g_multi.edge_ids(1, 0, return_uv=True)
eid_10 = g_multi.edge_ids(1, 0)
g_multi.edges[eid_10].data['w'] = th.ones(len(eid_10), 2)
# g_multi.edata['w'][g_multi.edge_ids(1, 0)] = th.ones(len(eid_10), 2)
print(g_multi.edata['w'])