版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
圖神經網絡《Python機器學習與項目實踐》XXX大學圖神經網絡(GraphNeuralNetwork,GNN)圖神經網絡(GraphNeuralNetwork,GNN)是一類用于處理圖數(shù)據(jù)的機器學習模型。與傳統(tǒng)的神經網絡主要針對向量或矩陣數(shù)據(jù)的處理不同,圖神經網絡專門設計用于對圖數(shù)據(jù)進行建模和推理。7.1圖的定義與術語1.圖的定義圖(Graph)由節(jié)點的有窮非空集合和節(jié)點之間邊的集合組成,通常表示為G(V,E),其中7.1圖的定義與術語2.圖的分類(1)無向圖(UndirectedGraph)和有向圖(DirectedGraph):根據(jù)圖中邊的方向性進行分類。在無向圖中,邊是沒有方向的;而在有向圖中,邊具有明確的方向,如圖7-2所示。(2)加權圖(WeightedGraph)和非加權圖(UnweightedGraph):根據(jù)圖中邊的權重進行分類。在加權圖中,邊具有權重;而在非加權圖中,邊沒有權重。加權圖如圖7-3所示。(3)完全圖(CompleteGraph)和非完全圖(Non-CompleteGraph):根據(jù)圖中節(jié)點之間是否都有邊連接進行分類。在完全圖中,每對節(jié)點之間都有邊連接;而在非完全圖中,可能存在節(jié)點之間沒有邊連接的情況。(4)稀疏圖(SparseGraph)和稠密圖(DenseGraph):根據(jù)圖中邊的數(shù)量和節(jié)點的數(shù)量之間的比例進行分類。稀疏圖指的是邊相對較少的圖,而稠密圖指的是邊相對較多的圖。(5)連通圖(ConnectedGraph)和非連通圖(DisconnectedGraph):根據(jù)圖中節(jié)點之間是否存在路徑連接進行分類。在連通圖中,任意兩個節(jié)點之間都存在路徑連接;而在非連通圖中,可能存在節(jié)點之間沒有路徑連接的部分。7.1圖的定義與術語3.圖的節(jié)點和邊節(jié)點的度是指與該節(jié)點直接相連的邊的數(shù)量。節(jié)點的度可以用于描述節(jié)點在圖中的連接程度或重要性。度可以分為入度(In-Degree)和出度(Out-Degree),具體取決于圖是有向圖還是無向圖。7.2圖神經網絡模型結構圖神經網絡的基本思想是將圖中的節(jié)點和邊作為輸入,通過迭代更新節(jié)點的表示,從而學習節(jié)點的特征表示和整個圖的全局特征。圖神經網絡模型通常由多個圖卷積層組成,每個圖卷積層都包含了節(jié)點特征的更新規(guī)則。這些規(guī)則可以聚合節(jié)點的鄰居信息,并將其與節(jié)點自身的特征進行融合,以生成新的節(jié)點表示。圖神經網絡有以下特點。忽略節(jié)點的輸入順序。在計算過程中,節(jié)點的表示受其周圍鄰居節(jié)點的影響,而圖本身連接不變。圖結構的表示使得可以進行基于圖的推理。7.2圖神經網絡模型結構7.3圖神經網絡常用模型如何用FNN去模擬一個有限狀態(tài)自動機?7.3.1GCN模型GCN(GraphConvolutionalNetwork,圖卷積神經網絡)是一種用于處理圖數(shù)據(jù)的神經網絡模型。它的主要用途是對節(jié)點進行分類或預測節(jié)點的屬性。GCN的目標是學習每個節(jié)點的表示向量,使得這些向量能夠捕捉到節(jié)點在圖中的結構信息和上下文關系。通過利用節(jié)點的鄰居信息,GCN可以對節(jié)點的特征進行聚合和更新,同時保留了圖結構的局部特征和全局特征。GCN的核心操作是基于鄰居節(jié)點特征的卷積操作。7.2圖神經網絡模型結構2.GCN的結構GCN的結構如下。(1)輸入層:接收圖數(shù)據(jù)的輸入,包括節(jié)點特征和圖的鄰接矩陣。(2)圖卷積層:GCN的核心部分。每個圖卷積層將節(jié)點特征和鄰接矩陣作為輸入,并通過聚合鄰居節(jié)點信息來更新節(jié)點的表示。具體的圖卷積操作根據(jù)不同的GCN變體有所不同,但通常包括節(jié)點特征的線性變換和鄰居節(jié)點特征的聚合操作。(3)非線性激活層:位于圖卷積層之后,通常會應用一個非線性激活函數(shù)(如ReLU函數(shù))來引入非線性性質。(4)全連接層:將最終的節(jié)點表示映射到所需的輸出空間,如節(jié)點分類的類別數(shù)。(5)輸出層:根據(jù)任務的不同,可以使用不同的輸出層,如Softmax層用于多類別分類任務。7.3圖神經網絡常用模型1.GCN的結構GGNN模型7.3.2GGNN模型GGNN(GatedGraphNeuralNetwork,門控圖神經網絡)是一種用于圖數(shù)據(jù)的深度學習模型,它擴展了傳統(tǒng)的圖神經網絡,通過引入門控機制來增強信息傳遞和聚合的能力。7.3.3GAT模型GAT(GraphAttentionNetwork,注意力圖神經網絡)是一種用于圖數(shù)據(jù)的深度學習模型,它在節(jié)點之間引入了注意力機制來學習節(jié)點之間的重要性,從而更準確地進行信息聚合和表示學習。GCN/publication/12314435_Neural_system_identification_model_of_human_sound_localization7.4圖神經網絡實例7.4.1數(shù)據(jù)集及預處理我們使用的是Cora數(shù)據(jù)集,該數(shù)據(jù)集由2708篇論文,以及它們之間的引用關系構成的5429條邊構成。這些論文根據(jù)主題劃分為7類,分別是神經網絡、強化學習、規(guī)則學習、概率方法、遺傳算法、理論研究、案例相關。每篇論文的特征(向量)通過詞袋模型得到,維度為1433(詞典大?。?,每一維表示一個詞,1表示該詞在該論文中出現(xiàn),0表示未出現(xiàn)。7.4圖神經網絡實例1.#導入必要的庫
2.import
itertools
3.import
os
4.import
os.path
as
osp
5.import
pickle
6.import
urllib
7.from
collections
import
namedtuple
8.import
numpy
as
np
9.import
scipy.sparse
as
sp
#鄰接矩陣用稀疏矩陣形式存儲,節(jié)省空間
10.import
torch
11.import
torch.nn
as
nn
12.import
torch.nn.functional
as
F
13.import
torch.nn.init
as
init
14.import
torch.optim
as
optim
15.import
matplotlib.pyplot
as
plt
16.%matplotlib
inline
7.4圖神經網絡實例進行數(shù)據(jù)預處理,定義CoraData類1.Data=namedtuple('Data',['x','y','adjacency',
2.
'train_mask','val_mask','test_mask'])
3.def
tensor_from_numpy(x,device):
#將數(shù)據(jù)從數(shù)組格式轉換為Tensor格式
并轉移到相關設備上4.
return
torch.from_numpy(x).to(device)
5.class
CoraData(object):
6.
#數(shù)據(jù)集下載鏈接
7.
download_url="/kimiyoung/planetoid/master/data"
8.
#數(shù)據(jù)集中包含的文件名
9.
filenames=["ind.cora.{}".format(name)
for
name
in
10.
['x','tx','allx','y','ty','ally','graph','test.index']]
11.
def
__init__(self,data_root="cora",rebuild=False):
12.
"""Cora數(shù)據(jù),包括數(shù)據(jù)下載、處理、讀取等功能
13.
當數(shù)據(jù)的緩存文件存在時,將使用緩存文件,否則將下載、進行處理,并緩存到磁盤
14.
處理之后的數(shù)據(jù)可以通過屬性
.data
獲得,它將返回一個數(shù)據(jù)對象,包括如下部分:
15.
*
x:
節(jié)點的特征,維度為
2708
×
1433,類型為
np.ndarray
16.
*
y:
節(jié)點的標記,總共包括7個類別,類型為
np.ndarray
7.4圖神經網絡實例17.
*
adjacency:
鄰接矩陣,維度為
2708
×
2708,類型為
scipy.sparse.coo.coo_matrix
18.
*
train_mask:
訓練集掩碼向量,維度為
2708,當節(jié)點屬于訓練集時,相應位置為True,否則為False
19.
*
val_mask:
驗證集掩碼向量,維度為
2708,當節(jié)點屬于驗證集時,相應位置為True,否則為False
20.
*
test_mask:
測試集掩碼向量,維度為
2708,當節(jié)點屬于測試集時,相應位置為True,否則False
21.
Args:
22.
-------
23.
data_root:
string,optional
24.
存儲數(shù)據(jù)的目錄,原始數(shù)據(jù)路徑:
{data_root}/raw
25.
緩存數(shù)據(jù)路徑:
{data_root}/processed_cora.pkl
7.4圖神經網絡實例26.
rebuild:
boolean,optional
27.
是否需要重新構建數(shù)據(jù)集,當設為True時,即使存在緩存數(shù)據(jù),也會重新構建28.
"""
29.
self.data_root=data_root
30.
save_file=osp.join(self.data_root,"processed_cora.pkl")
31.
if
osp.exists(save_file)
and
not
rebuild:
#使用緩存數(shù)據(jù)
32.
print("Using
Cached
file:
{}".format(save_file))
33.
self._data=pickle.load(open(save_file,"rb"))
34.
else:
35.
self.maybe_download()
#下載或使用原始數(shù)據(jù)集
36.
self._data=cess_data()
#數(shù)據(jù)預處理
37.
with
open(save_file,"wb")
as
f:
#把處理好的數(shù)據(jù)保存為緩存文件.pkl,下次直接使用
38.
pickle.dump(self.data,f)
39.
print("Cached
file:
{}".format(save_file))
7.4圖神經網絡實例40.
41.
@property
42.
def
data(self):
43.
"""返回Data數(shù)據(jù)對象,包括x,y,adjacency,train_mask,val_mask,test_mask"""
44.
return
self._data
45.
46.
def
process_data(self):
47.
"""
48.
處理數(shù)據(jù),得到節(jié)點特征和標記、鄰接矩陣、訓練集、驗證集及測試集
49.
引用自:/rusty1s/pytorch_geometric
50.
"""
51.
print("Process
data
...")
52.
#讀取下載的數(shù)據(jù)文件
53.
_,tx,allx,y,ty,ally,graph,test_index=[self.read_data(
54.
osp.join(self.data_root,"raw",name))
for
name
in
self.filenames]
55.
56.
train_index=np.arange(y.shape[0])
#訓練集索引
57.
val_index=np.arange(y.shape[0],y.shape[0]
+
500)#驗證集索引
58.
sorted_test_index=sorted(test_index)
#測試集索引
59.
7.4圖神經網絡實例60.
x=np.concatenate((allx,tx),axis=0)
#節(jié)點特征61.
y=np.concatenate((ally,ty),axis=0).argmax(axis=1)#節(jié)點標記62.
63.
x[test_index]=x[sorted_test_index]
64.
y[test_index]=y[sorted_test_index]
65.
num_nodes=x.shape[0]
#節(jié)點個數(shù)/數(shù)據(jù)量
66.
67.
#訓練集掩碼向量、驗證集掩碼向量、測試集掩碼向量
68.
#初始化為0
7.4圖神經網絡實例69.
train_mask=np.zeros(num_nodes,dtype=np.bool)
70.
val_mask=np.zeros(num_nodes,dtype=np.bool)
71.
test_mask=np.zeros(num_nodes,dtype=np.bool)
72.
73.
train_mask[train_index]=True
74.
val_mask[val_index]=True
75.
test_mask[test_index]=True
76.
77.
#構建鄰接矩陣
78.
adjacency=self.build_adjacency(graph)
79.
print("Node's
feature
shape:
",x.shape)
#(N*D)
80.
print("Node's
label
shape:
",y.shape)#(N,)
81.
print("Adjacency's
shape:
",adjacency.shape)
#(N,N)
82.
#訓練集、驗證集、測試集各自的大小
83.
print("Number
of
training
nodes:
",train_mask.sum())
84.
print("Number
of
validation
nodes:
",val_mask.sum())
85.
print("Number
of
test
nodes:
",test_mask.sum())
7.4圖神經網絡實例86.
87.
return
Data(x=x,y=y,adjacency=adjacency,
88.
train_mask=train_mask,val_mask=val_mask,test_mask=test_mask)
89.
90.
def
maybe_download(self):
91.
#原始數(shù)據(jù)存儲路徑
92.
save_path=os.path.join(self.data_root,"raw")
93.
#下載相應的文件
94.
for
name
in
self.filenames:
95.
if
not
osp.exists(osp.join(save_path,name)):
96.
self.download_data(
97.
"{}/{}".format(self.download_url,name),save_path)
98.
7.4圖神經網絡實例99.
@staticmethod
100.
def
build_adjacency(adj_dict):
101.
"""根據(jù)下載的鄰接表構建鄰接矩陣"""
102.
edge_index=[]
103.
num_nodes=len(adj_dict)
104.
for
src,dst
in
adj_dict.items():
105.
edge_index.extend([src,v]
for
v
in
dst)
106.
edge_index.extend([v,src]
for
v
in
dst)
107.
#
去除重復的邊
108.
edge_index=list(k
for
k,_
in
itertools.groupby(sorted(edge_index)))
109.
edge_index=np.asarray(edge_index)
110.
#稀疏矩陣,存儲非0值,節(jié)省空間
111.
adjacency=sp.coo_matrix((np.ones(len(edge_index)),
7.4圖神經網絡實例112.
(edge_index[:,0],edge_index[:,1])),
113.
shape=(num_nodes,num_nodes),dtype="float32")
114.
return
adjacency
115.
116.
@staticmethod
117.
def
read_data(path):
118.
"""使用不同的方式讀取原始數(shù)據(jù)以進一步處理"""
119.
name=osp.basename(path)
120.
if
name
==
"ind.cora.test.index":
121.
out=np.genfromtxt(path,dtype="int64")
122.
return
out
123.
else:
124.
out=pickle.load(open(path,"rb"),encoding="latin1")
125.
out=out.toarray()
if
hasattr(out,"toarray")
else
out
126.
return
out
127.
128.
@staticmethod
129.
def
download_data(url,save_path):
130.
"""數(shù)據(jù)下載工具,當原始數(shù)據(jù)不存在時將會進行下載"""
131.
if
not
os.path.exists(save_path):
7.4圖神經網絡實例132.
os.makedirs(save_path)
133.
data=urllib.request.urlopen(url)
134.
filename=os.path.split(url)[-1]
135.
136.
with
open(os.path.join(save_path,filename),'wb')
as
f:
137.
f.write(data.read())
138.
139.
return
True
140.
141.
@staticmethod
142.
def
normalization(adjacency):
143.
"""計算
L=D^-0.5
*
(A+I)
*
D^-0.5"""
144.
adjacency
+=
sp.eye(adjacency.shape[0])
#
增加自連接,不僅考慮鄰居節(jié)點特征,還考慮節(jié)點自身的特征
145.
degree=np.array(adjacency.sum(1))
#此時的度矩陣的對角線的值為鄰接矩陣按行求和
146.
d_hat=sp.diags(np.power(degree,-0.5).flatten())
#對先度矩陣對角線的值取-0.5次方,再轉換為對角矩陣
147.
return
d_hat.dot(adjacency).dot(d_hat).tocoo()
#歸一化的拉普拉斯矩陣,稀疏存儲,節(jié)省空間
7.4.2圖卷積層定義根據(jù)GCN的定義來定義圖卷積層,代碼直接根據(jù)定義來實現(xiàn),需要特別注意的是,鄰接矩陣是稀疏矩陣,為了提高運算效率,使用了稀疏矩陣乘法。1.class
GraphConvolution(nn.Module):
2.
def
__init__(self,input_dim,output_dim,use_bias=True):
3.
"""圖卷積:L*X*\theta
4.
Args:
5.
----------
6.
input_dim:
int
7.
節(jié)點輸入特征的維度D
8.
output_dim:
int
9.
節(jié)點輸出特征的維度D'10.
use_bias
:
bool,optional
11.
是否使用偏置
12.
"""
13.
super(GraphConvolution,self).__init__()
14.
self.input_dim=input_dim
15.
self.output_dim=output_dim
7.4.2圖卷積層定義根據(jù)GCN的定義來定義圖卷積層,代碼直接根據(jù)定義來實現(xiàn),需要特別注意的是,鄰接矩陣是稀疏矩陣,為了提高運算效率,使用了稀疏矩陣乘法。16.
self.use_bias=use_bias
17.
#定義圖卷積層的權重矩陣
18.
self.weight=nn.Parameter(torch.Tensor(input_dim,output_dim))
19.
if
self.use_bias:
20.
self.bias=nn.Parameter(torch.Tensor(output_dim))
21.
else:
22.
self.register_parameter('bias',None)
23.
self.reset_parameters()
#使用自定義的參數(shù)初始化方式
24.
25.
def
reset_parameters(self):
26.
#自定義參數(shù)初始化方式
27.
#權重參數(shù)初始化方式
28.
init.kaiming_uniform_(self.weight)
29.
if
self.use_bias:
#偏置參數(shù)初始化為0
30.
init.zeros_(self.bias)
31.
32.
def
forward(self,adjacency,input_feature):
33.
"""鄰接矩陣是稀疏矩陣,因此在運算時使用稀疏矩陣乘法
34.
35.
Args:
7.4.2圖卷積層定義36.
-------
37.
adjacency:
torch.sparse.FloatTensor
38.
鄰接矩陣
39.
input_feature:
torch.Tensor
40.
輸入特征
41.
"""
42.
support=torch.mm(input_feature,self.weight)
#XW
(N,D');X
(N,D);W
(D,D')
43.
output=torch.sparse.mm(adjacency,support)
#(N,D')
44.
if
self.use_bias:
45.
output
+=
self.bias
46.
return
output
47.
48.
def
__repr__(self):
49.
return
self.__class__.__name__
+
'
('
\
50.
+
str(self.input_dim)
+
'
->
'
\
51.
+
str(self.output_dim)
+
')'
7.4.3模型定義對GCN模型結構進行修改和實驗。1.class
GcnNet(nn.Module):
2.
"""
3.
定義一個兩層GCN的模型
4.
"""
5.
def
__init__(self,input_dim=1433):
6.
super(GcnNet,self).__init__()
7.
self.gcn1=GraphConvolution(input_dim,16)
8.
self.gcn2=GraphConvolution(16,7)
9.
10.
def
forward(self,adjacency,feature):
11.
h=F.relu(self.gcn1(adjacency,feature))
#(N,1433)->(N,16)
12.
logits=self.gcn2(adjacency,h)
#(N,16)->(N,7)
13.
return
logits
7.4.4模型訓練對超參數(shù)進行定義。1.#
超參數(shù)定義
2.LEARNING_RATE=0.1
#學習率
3.WEIGHT_DACAY=5e-4
#正則化系數(shù)
4.EPOCHS=200
#完整遍歷訓練集的次數(shù)
5.DEVICE="cuda"
if
torch.cuda.is_available()
else
"cpu"
#設備7.4.4模型訓練加載數(shù)據(jù)集1.#
加載數(shù)據(jù),并轉換為torch.Tensor
2.dataset=CoraData().data
3.node_feature=dataset.x
/
dataset.x.sum(1,keepdims=True)
#
歸一化數(shù)據(jù),使得每一行之和為1
4.tensor_x=tensor_from_numpy(node_feature,DEVICE)
5.tensor_y=tensor_from_numpy(dataset.y,DEVICE)
6.tensor_train_mask=tensor_from_numpy(dataset.train_mask,DEVICE)
7.tensor_val_mask=tensor_from_numpy(dataset.val_mask,DEVICE)
8.tensor_test_mask=tensor_from_numpy(dataset.test_mask,DEVICE)
9.normalize_adjacency=CoraData.normalization(dataset.adjacency)
#
規(guī)范化鄰接矩陣
10.num_nodes,input_dim=node_feature.shape
#(N,D)
11.#轉換為稀疏表示,加速運算,節(jié)省空間12.indices=torch.from_numpy(np.asarray([normalize_adjacency.row,
13.
normalize_adjacency.col]).astype('int64')).long()
14.values=torch.from_numpy(normalize_adjacency.data.astype(np.float32))
15.tensor_adjacency=torch.sparse.FloatTensor(indices,values,
16.
(num_nodes,num_nodes)).to(DEVICE)
7.4.4模型訓練定義GCN模型。1.#
模型定義:Model,Loss,Optimizer
2.model=GcnNet(input_dim).to(DEVICE)3.criterion=nn.CrossEntropyLoss().to(DEVICE)
#多分類交叉熵損失
4.optimizer=optim.Adam(model.parameters(),
5.
lr=LEARNING_RATE,
6.
weight_decay=WEIGHT_DACAY)
#Adam優(yōu)化器
7.4.4模型訓練定義訓練函數(shù)。1.#
訓練主體函數(shù)
2.def
train():
3.
loss_history=[]
4.
val_acc_history=[]
5.
model.train()
#訓練模式
6.
train_y=tensor_y[tensor_train_mask]
#訓練節(jié)點的標記
7.
for
epoch
in
range(EPOCHS):
#完整遍歷一次訓練集,一個Epoch做一次更新
8.
logits=model(tensor_adjacency,tensor_x)
#
所有數(shù)據(jù)前向傳播
9.
train_mask_logits=logits[tensor_train_mask]
#
只選擇訓練節(jié)點進行監(jiān)督
10.
loss=criterion(train_mask_logits,train_y)
#
計算損失值
11.
optimizer.zero_grad()
#清空梯度
12.
loss.backward()
#
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 《蔬菜大棚雜草和害蟲識別方法研究》
- 《混凝土柱震致殘余側移和剩余抗震能力評價方法》
- 農學教育與農業(yè)可持續(xù)發(fā)展戰(zhàn)略培養(yǎng)計劃
- 家庭教育中的個性化教育探索與實踐
- 2024年貨物買賣補充協(xié)議
- 家長在提升孩子社交技能中的領導力與實踐
- 二零二五年工程車運輸及設備租賃服務合同3篇
- 2024年碎磚采購與再生資源利用合作協(xié)議3篇
- 2025年度環(huán)保商品配送服務合同范本3篇
- 2025年度生態(tài)養(yǎng)殖場產業(yè)鏈上下游合作框架協(xié)議3篇
- DL∕T 1100.1-2018 電力系統(tǒng)的時間同步系統(tǒng) 第1部分:技術規(guī)范
- CJ/T 158-2002 城市污水處理廠管道和設備色標
- NB-T35009-2013抽水蓄能電站選點規(guī)劃編制規(guī)范
- 曳引驅動電梯調試作業(yè)指導書
- 上海市中考英語試卷及答案
- 基礎會計課程思政教案設計
- 蘇教版科學小學五年級上冊期末測試卷及完整答案(奪冠系列)
- 監(jiān)控工程竣工驗收報告
- 經皮肝穿刺膽道引流(PTCD)導管的護理要點
- 國家開放大學《心理學》形考任務1-4參考答案
- 2024年社會工作者《社會工作實務(中級)》考試真題必考題
評論
0/150
提交評論