最近、グラフニューラルネットワークに触れましたが、このガジェットはマルチグラニュラーな視点を提供できると感じています。調査オブジェクトを抽象化した後、ノード、エッジ、およびグラフ全体を分類できます。グラフニューラルネットワークの構造は、特定のオブジェクトを記述するためのマルチグラニュラリティ機能を提供します。それについて考えるのはかなり良いことです。
だから私はグラフニューラルネットワークをします。
現在、グラフニューラルネットワークの理論的な学習ルートは次のとおりです。
- グラフ理論の基礎知識。これは非常によく知られているので、学ぶ必要はありません。
- 線形代数、特にフーリエ変換の行列形式。戻って本を読んでください。グラフ畳み込みネットワークの理論的基礎を読みました。これは実際にはフーリエ変換行列形式のアプリケーションです。これは行列分析クラスではすでに非常に一般的であり、新しい知識ポイントではありません。 。ただし、グラフニューラルネットワークにアクセスしたい場合は、この部分を注意深く習得する必要があります。
- ニューラルネットワーク関連の知識。
「ニューラルネットワークの深くて簡単な説明」を読んだことがあるかもしれませんが、同じように感じますが、それでも実用的です。だから、実用的な側面について書いてください。
グラフニューラルネットワークライブラリ
私が使用しているライブラリはDGLです:https:
//docs.dgl.ai/index.html githubアドレス:https://github.com/dmlc/dgl
このライブラリはニューヨーク大学によって作成されたようです。現在の一般的なグラフニューラルネットワークモデルを実装します。このモデルは、ビルディングブロックのようにネットワークを直接構築してから、データを構築します。
DGLライブラリをインストールする
cudaのインストールなし:
pip3 install dgl -i https://mirrors.aliyun.com/pypi/simple/
cuda10のインストール:
python3 -m pip install dgl-cu100 -i https://mirrors.aliyun.com/pypi/simple/
DGLは、デフォルトで基礎となるニューラルネットワークライブラリとしてpytorchを使用します
チュートリアル
ノードの追加、エッジの追加、グラフの視覚化
DGLのエッジはすべて有向エッジです。無向エッジの場合、2つの反対側のエッジを同時に作成できます。
__author__ = 'dk'
#构建图,添加节点和边
import networkx as nx
import dgl
import matplotlib.pyplot as plt
#构建星型图
u=[0,0,0,0,0]
v=[1,2,3,4,5]
#第一种方式,u和v的数组,他们是相同的长度
star1 = dgl.DGLGraph((u,v))
nx.draw(star1.to_networkx(),with_labels=True)#可视化图
plt.show()
star2 = dgl.DGLGraph((0,v))
#对于星型,是可以广播的
nx.draw(star2.to_networkx(),with_labels=True)
plt.show()
star3= dgl.DGLGraph([(0,1),(0,2),(0,3),(0,4),(0,5)])
#直接枚举
nx.draw(star3.to_networkx(),with_labels=True)
plt.show()
コンストラクターでエッジを追加する代わりに、後でエッジを追加することもできます。
#也可以边构图,边加边,而不是在构造函数里面加边
g = dgl.DGLGraph()#这是一张空白图
g.add_nodes(9)#添加节点,注意一定要先加节点,后加边
for i in range(1,8):
g.add_edge(0,i)
nx.draw(g.to_networkx(),with_labels=True)
plt.show()
注意!エッジ(u、v)を追加する場合、uとvは、ネットワークがすでに持っている最大ノードID(ノード数から1を引いた数)を超えることはできません。不一致のない冗長ノードの場合、DGLはそれらを分離していると見なします。
たとえば、上の図:ノード8は変更なしで接続されています。
ノードフィーチャの割り当てと抽出
グラフを作成した後、ノードに機能を追加できます。
DGLでは、ノードの特性は辞書として扱われます。ユーザーは、ノードの機能に特徴的な意味を持つkey_nameを取得できます。また、ユーザーは、ノードに複数の機能を同時に定義することもできます。
たとえば、上記のスターモデル:
import numpy as np
features = np.random.normal(0,1,(9,5)) #随机生成一个9x5的正态分布矩阵
print(features)
g.ndata['features'] = features
出力:
[[-0.73241917 0.78738566 1.21160063 -0.83944648 -0.15739715]
[-0.05520377 0.83418124 -0.68477259 -1.29054549 -1.2375015 ]
[-0.23807425 -0.40030208 1.74318389 -0.70699831 -0.61449034]
[-0.48597221 0.65284435 -0.27101916 -0.69242791 -0.83134013]
[-0.00580359 1.29773141 1.28545031 -0.41703836 0.97254182]
[-1.19173936 1.18409306 -0.24284504 -1.93560515 -1.1080128 ]
[-0.4854841 0.06257814 -1.3432515 -0.53297016 -0.01270537]
[-0.16906863 0.17349874 1.0057332 1.85554737 0.13355367]
[-1.45619866 0.77784642 1.52454762 -0.86608947 0.28595569]]
ndata属性は、node-dataの略語です。それは口述です。
フィーチャの行数は、グラフが現在所有しているノードの数と同じである必要があることに注意してください。
それ以外の場合は、エラーが報告されます。
dgl._ffi.base.DGLError: Expect number of features to match number of nodes (len(u)). Got 7 and 9 instead.
ノード機能へのアクセス:
直接g.ndata [機能名] [ノードID]は次のことができます:
例:ノード3の機能にアクセスする
print(g.ndata['features'][3])
出力:特徴行列の3行目
tensor([-0.4860, 0.6528, -0.2710, -0.6924, -0.8313], dtype=torch.float64)
もちろん、ノードの特性を変更することもできます。
g.ndata['features'][3]=th.zeros(1,5)
print(g.ndata['features'][3])
出力:
tensor([0., 0., 0., 0., 0.], dtype=torch.float64)
DGLは、ノードの特徴を格納するために内部的にテンソルを使用していることがわかります。ノード特性の変更とアクセスは、このマトリックスの変更とアクセスに最終的に実装されます。
print(g.ndata)
出力:
{
'features': tensor([[-0.4771, 1.7900, -1.1160, 0.2916, -0.7986],
[-1.6190, -0.5006, -0.0437, 1.6412, -1.6979],
[ 1.8872, 0.5236, 0.5123, -0.7658, -0.5050],
[ 0.0000, 0.0000, 0.0000, 0.0000, 0.0000],
[-0.3382, -0.4218, 0.8622, 1.1720, 0.3460],
[-0.1710, 0.2713, -0.1639, -1.1159, -0.3623],
[-0.9241, 1.2943, 0.1137, 1.5348, 0.1791],
[-1.0372, 1.4145, -2.0653, -0.1469, -0.6041],
[ 0.1035, -1.4215, 0.3288, -0.5195, -1.4120]], dtype=torch.float64)}
エッジ機能の割り当て、アクセス、および変更
ノードフィーチャーと同様に、エッジもフィーチャーを指定し、フィーチャーにアクセスして変更することができます。
割り当て:
g.edata['w']=th.randn(len(g.edges),2)
割り当て行列の行関数は、
特定のエッジの機能にアクセスするためにエッジの数と等しくする必要があり、最終的にはエッジ行列の特定の行にアクセスするために実装する必要があることに注意してください。そして、どの線がエッジのIDです。
したがって、アクセスしているエッジのIDを判別する必要があります。
例:エッジのID(0,7)を取得します。
g.edge_id(0,7)
このエッジの機能にアクセスします。
g.edata(g.edge_id(0,7))
次に、機能を削除することもできます。これは実際には辞書操作です。
g.ndata.pop('features')
g.edata.pop('w')