日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

DGL教程【二】如何通过DGL表示一个Graph

發布時間:2024/9/18 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 DGL教程【二】如何通过DGL表示一个Graph 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

通過本節,將學到:

  • 從頭開始用DGL構建一個Graph
  • 給Graph添加節點和邊的特征
  • 獲取一些圖的信息,如節點的度或節點的其他屬性
  • 將DGL graph 轉換到另一個graph
  • 加載、保存DGL graph

從頭構建Graph

DGL通過DGLGraph對象來創建一個有向圖,我們可以直接通過指定節點,以及src節點和target節點來創建一個graph。節點的id從0開始。

例如下面一段代碼構建了一個有向星型圖,共有6個節點,中心節點的id是0,邊分別是從中心到葉子節點。

import dgl import numpy as np import torchg = dgl.graph(([0, 0, 0, 0, 0], [1, 2, 3, 4, 5]), num_nodes=6) # Equivalently, PyTorch LongTensors also work. g = dgl.graph((torch.LongTensor([0, 0, 0, 0, 0]), torch.LongTensor([1, 2, 3, 4, 5])), num_nodes=6)# You can omit the number of nodes argument if you can tell the number of nodes from the edge list alone. g = dgl.graph(([0, 0, 0, 0, 0], [1, 2, 3, 4, 5])) print(g.edges())

輸出:

(tensor([0, 0, 0, 0, 0]), tensor([1, 2, 3, 4, 5]))

注意DGLGraph默認使用有向圖以方便計算,如果要創建無向圖,需要創建一個bidirectional graph。

指定節點和邊的特征

很多graph的節點和邊都包含屬性,雖然在現實中,節點和邊的屬性都是任意的,但是在DGLGraph中,只接受tensor(numerical contents)類型。因此,節點或邊的屬性必須擁有相同的shape,我們將節點或邊的屬性稱作features。

我們可以通過ndata和edata接口來分配或檢索節點和邊的features:

# Assign a 3-dimensional node feature vector for each node. g.ndata['x'] = torch.randn(6, 3) # Assign a 4-dimensional edge feature vector for each edge. g.edata['a'] = torch.randn(5, 4)# 可以給每個節點一個5*4維的特征矩陣 g.ndata['y'] = torch.randn(6, 5, 4) print(g.edata['a']) print(g.ndata)

輸出結果如下:

tensor([[-0.0667, 0.4955, -0.7605, 1.0864],[ 1.3225, -0.0638, 0.4249, -0.9549],[ 1.5967, 0.6893, 0.0693, -0.2029],[ 0.9383, -0.9211, -0.3480, -1.2578],[-0.2237, -0.3213, 0.2844, -2.1222]]) {'x': tensor([[-1.5809, 0.5587, -0.2951],[-0.6097, -0.6469, 1.1301],[-0.2151, -0.4234, 0.1623],[ 0.0742, 1.0390, 0.4727],[-0.9907, 0.0712, -1.9446],[-0.8176, -1.3116, -0.0609]]), 'y': tensor([[[ 0.5657, 1.5601, -0.5912, -0.9166],[-2.1264, -1.0500, -1.5964, 0.8197],[-0.1032, 0.8735, 0.5557, 0.2568],[-0.2407, 0.5534, -0.4418, -0.8438],[-1.3463, -1.3163, 0.4165, 0.4069]],[[ 0.5147, 0.7456, 0.5775, -0.8002],[-0.7700, -0.9576, -0.4264, 0.5365],[-0.2953, -1.0986, -0.7701, 0.6752],[-0.8701, 0.0455, -0.0241, 1.4218],[ 0.8420, 1.5854, 0.2167, -0.3292]],[[-1.9216, -1.4101, -0.8027, -0.1626],[ 0.8344, 0.6824, -0.2703, -0.6369],[-0.8784, -1.3154, 2.5829, -0.6084],[ 1.0764, 0.6415, -0.0548, 2.0256],[-0.2596, 0.9234, -0.7495, 0.4572]],[[ 0.4695, 0.4599, 1.0253, -1.6217],[-0.9483, -1.1822, 0.6945, 0.2053],[-1.6246, -0.2697, 0.3077, -0.1492],[ 0.1044, 1.3403, -2.2207, 0.7767],[-1.0187, 0.9309, 1.3097, -0.8092]],[[ 0.3566, -0.9140, -0.0288, 0.8432],[ 1.4894, -1.0284, 1.1628, 1.6677],[ 0.9602, 0.8019, 0.2072, 0.9472],[-0.8926, 0.6656, 0.2531, 0.1492],[ 1.2601, 0.5075, 0.6341, -0.6500]],[[-0.3595, 0.8457, 0.0679, -0.2255],[ 0.0466, -0.5428, -1.8730, 1.7333],[-1.2157, 0.6068, -0.4385, -1.6794],[ 0.2981, 1.2320, -0.1630, 2.4952],[-1.3436, -2.1708, -0.3203, -0.9315]]])}

目前有很多成熟的方法可以將屬性編碼成numerical features:
對于分類屬性(比如性別,職業),可以通過one-hot進行編碼
對于字符串型的屬性(比如文章引用),可以考慮nlp模型
對于圖像的屬性,可以考慮CNN等視覺模型

獲取Graph的結構信息

DGLGraph對象提供了很多方法來獲取Graph的結構信息:

print(g.num_nodes()) # 6 print(g.num_edges()) # 5 # Out degrees of the center node print(g.out_degrees(0)) # 5 出度 圖中每個節點出度的最大值 # In degrees of the center node - note that the graph is directed so the in degree should be 0. print(g.in_degrees(0)) # 0 入度 圖中每個節點入度的最大值

Graph 轉換

DGL提供了很多轉換的API,例如從一個圖中抽取一張子圖。

# 從原始圖中獲取節點0、節點1和節點3來成成一個子圖 sg1 = g.subgraph([0, 1, 3]) # 從原始圖中抽取邊0、邊1和邊3來成成一個子圖 sg2 = g.edge_subgraph([0, 1, 3])

可以在子圖中通過dgl.NID或者dgl.EID來獲取父圖中節點和邊的映射。

# The original IDs of each node in sg1 print(sg1.ndata[dgl.NID]) # The original IDs of each edge in sg1 print(sg1.edata[dgl.EID]) # The original IDs of each node in sg2 print(sg2.ndata[dgl.NID]) # The original IDs of each edge in sg2 print(sg2.edata[dgl.EID])

輸出:

tensor([0, 1, 3]) tensor([0, 2]) tensor([0, 1, 2, 4]) tensor([0, 1, 3])

subgraph和edge_subgraph同樣會將父圖的屬性復制一份給子圖:

# sg1的每個原始節點的屬性 print(sg1.ndata['x']) # sg1的每個原始邊的屬性 print(sg1.edata['a']) # sg2中每個原始節點的屬性 print(sg2.ndata['x']) # sg2中每個原始邊的屬性 print(sg2.edata['a'])

還有一種常用的轉換方式就是通過給原始graph添加反向邊dgl.add_reverse_edges

newg = dgl.add_reverse_edges(g) newg.edges()

如果你有一個無向圖,可以通過這種方式來轉成bidirectional graph。這種方式會將原始圖中所有的邊都添加一個反向邊。

保存、加載Graph

我們可以通過dgl.save_graphs來保存一個Graph或者一個Graph列表,通過dgl.load_graphs來加載graph

# 保存graph dgl.save_graphs('graph.dgl', g) dgl.save_graphs('graphs.dgl', [g, sg1, sg2]) # 加載graph (g,), _ = dgl.load_graphs('graph.dgl') print(g) (g, sg1, sg2), _ = dgl.load_graphs('graphs.dgl') print(g) print(sg1) print(sg2)

輸出:

Graph(num_nodes=6, num_edges=5,ndata_schemes={'y': Scheme(shape=(5, 4), dtype=torch.float32), 'x': Scheme(shape=(3,), dtype=torch.float32)}edata_schemes={'a': Scheme(shape=(4,), dtype=torch.float32)}) Graph(num_nodes=6, num_edges=5,ndata_schemes={'y': Scheme(shape=(5, 4), dtype=torch.float32), 'x': Scheme(shape=(3,), dtype=torch.float32)}edata_schemes={'a': Scheme(shape=(4,), dtype=torch.float32)}) Graph(num_nodes=3, num_edges=2,ndata_schemes={'_ID': Scheme(shape=(), dtype=torch.int64), 'x': Scheme(shape=(3,), dtype=torch.float32), 'y': Scheme(shape=(5, 4), dtype=torch.float32)}edata_schemes={'_ID': Scheme(shape=(), dtype=torch.int64), 'a': Scheme(shape=(4,), dtype=torch.float32)}) Graph(num_nodes=4, num_edges=3,ndata_schemes={'_ID': Scheme(shape=(), dtype=torch.int64), 'x': Scheme(shape=(3,), dtype=torch.float32), 'y': Scheme(shape=(5, 4), dtype=torch.float32)}edata_schemes={'_ID': Scheme(shape=(), dtype=torch.int64), 'a': Scheme(shape=(4,), dtype=torch.float32)})

總結

以上是生活随笔為你收集整理的DGL教程【二】如何通过DGL表示一个Graph的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。