Python機器學習與項目實踐- 課件 chap7-圖神經網絡_第1頁
Python機器學習與項目實踐- 課件 chap7-圖神經網絡_第2頁
Python機器學習與項目實踐- 課件 chap7-圖神經網絡_第3頁
Python機器學習與項目實踐- 課件 chap7-圖神經網絡_第4頁
Python機器學習與項目實踐- 課件 chap7-圖神經網絡_第5頁
已閱讀5頁,還剩31頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

圖神經網絡《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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論