???????????目錄
一.基礎1-[圖論、圖算法、CNN]
二.基礎2-[圖卷積神經網絡GCN]
三.torch-geometric.nn工具包安裝(包含各種算法和數據集)
四.GCN任務[節點分類-Cora 數據集]
五.圖注意力網絡(GAT)
六.圖自編碼器(GAE)
七.圖循環神經網絡 (GRNN)
八.門控圖神經網絡(GGNN)
九. 應用場景
????????圖神經網絡(GNN)的概念由 Franco Scarselli Bruna 等人于 2009 年首次提出。在他們名為“圖神經網絡模型”的論文中,提出了現有神經網絡的擴展,用于處理以圖結構表示的數據,這些數據往往是非歐幾里得結構數據,即節點間連接關系是任意的,無法用固定網格表示(如社交網絡中的朋友關系)。
? ? ? ? 李沐老師有一篇【2021GNN】論文解讀:??A Gentle Introduction to Graph Neural Networks
? ? ? ? 本文參考的B站課程鏈接:【圖神經網絡GNN/GCN教程】
? ? ? ??GNN中輸入也是特征,輸出也是特征,鄰接矩陣不變。多層GNN,可以使感受野越來越大,直至獲取全局特征。
?
????????GNN 模型可以處理非循環圖、循環圖、有向圖和無向圖。應用主要有:
- [節點分類]:通過考慮鄰居的標簽來預測節點的標簽。
- [鏈接預測]:預測圖中各個實體之間的關系。 例如,社交網絡的預測連接。
- [圖聚類]:將圖的節點劃分為簇。 基于邊權重或邊距離或通過將圖視為對象并將相似對象分組在一起來完成劃分。
- [圖分類]:將圖分類為類別。 這可以應用于社交網絡分析和自然語言處理中的文檔分類。 NLP 中的其他應用包括文本分類、提取文本之間的語義關系和序列標記。
- [計算機視覺]:在計算機視覺領域,GNN 可用于生成目標檢測的感興趣區域。 它們還可以用于圖像分類,從而生成場景圖。 然后場景生成模型識別圖像中的對象以及它們之間的語義關系。 該領域的其他應用包括交互檢測和區域分類。
? ? ? ? GNN 的核心思想是通過迭代地聚合每個節點鄰居的信息來更新節點的表示。這種聚合操作可以概括為以下步驟:
- 消息傳遞(Message Passing):每個節點從其鄰居接收信息。
- 特征更新:使用某種函數(通常是神經網絡)來更新節點特征。
- 迭代更新:多次迭代上述步驟,直到節點特征達到穩定狀態。
? ??????節點特征更新公式:
????????研究方向可能包括:
- 提高圖神經網絡的計算效率,以便處理更大規模的圖數據。
- 提高圖神經網絡的泛化能力,以便在更多的應用場景中取得更好的性能。
- 研究如何處理非靜態圖數據,以便更好地處理實際應用中的圖數據。
一.基礎1-[圖論、圖算法、CNN]
? ? ? ? 基本概念:(1)Level Graph;(2)S-T cut;(3)Bipartite Graph;(4)Hungarian Algorithm;(5)Shapley Algorithm;(6)蒙特卡洛算法(Monte carlo Algorithm),隨機梯度下降采用的是該算法。主要是依據大數定律驗證正確性。?課程可學習:Monte Carlo Algorithms_嗶哩嗶哩_bilibili
- 鄰接矩陣(Adjacency Matrix):一個用于表示圖中節點之間關系的矩陣。
- 特征矩陣(Feature Matrix):一個用于表示節點特征的矩陣。
- 卷積核矩陣(Kernel Matrix):一個用于表示卷積操作的矩陣。
二.基礎2-[圖卷積神經網絡GCN]
?????????只要知道每一個節點和每個節點間的關系,就可以往圖上套用。但是計算機視覺(CV)和自然語言處理(NLP)不常用,因為圖像和文本數據的格式是固定的。比如,將圖像resize成固定大小,進行卷積操作即可得到特征。
? ? ? ? 傳統NN中,一定要求格式是固定的。GNN用于輸入是不同長度的情形。GNN目的就是重構(更新)特征。采用的方法叫嵌入(embedding),在自然語言處理(NLP)中詞嵌入中也用到了。
????????GCN思路是:針對一個節點計算特征后,平均其鄰居特征和自身特征后傳入NN。涉及到鄰接矩陣、度矩陣、特征矩陣。????????
?
? ? ? ? [歸一化處理]??:對聚合結果進行歸一化,避免節點度數不同帶來的偏差。????????????????
????????具體來說,(省略了矩陣頭上的~)
????????1.把對角均為1的對角矩陣(自己的特征)加入鄰接矩陣,x特征矩陣
,
。
? ? ? ? 2.度矩陣,和倒數
,為了求它的平均
。
??????????(相當于 行歸一化)。同理對列做歸一化,。
? ? ? ? 3.--->
。
? ? ? ? ? ? ? ? ?為什么度要1--->1/2,有些點度很大,有些點度很小。而度很小的點,計算不一定準確。
? ? ? ?GCN通過?將權重重新更新。
???????GCN 的單層傳播規則如下:
? ? ? ? 其中可以看成是歸一化后的鄰接矩陣,
相當于給
層所有節點的embedding做了一次線性變換,左乘鄰接矩陣表示對于每個節點來說,該節點的特征變為鄰居節點特征相加后的結果。?
? ? ? ? 兩個GCN層輸出embedding計算為:
?
?
?
?????????
?
? ? ? ? [卷積層數]:根據六度分離原理,卷積層數不會很大。?
?
????????GCN 主要有兩種類型:
- 空間卷積網絡:?相鄰節點的特征被組合成中心節點, 特征的求和類似于普通的卷積運算。
- 譜卷積網絡:在譜網絡中,卷積運算是通過計算在傅里葉域中定義的拉普拉斯特征分解完成。
三.torch-geometric.nn工具包安裝(包含各種算法和數據集)
????????依賴的下載地址: https://pytorch-geometric.com/whl/ ,選對應版本復制鏈接或下載本地,安裝即可。
? ? ? ? cp是指python的版本,cp39-mac。
?????????官方介紹:?如數據集:torch_geometric.datasets — pytorch_geometric documentation
pip install torch-cluster https://data.pyg.org/whl/torch-2.7.0%2Bcpu/torch_cluster-1.6.3-cp39-cp39-macosx_10_9_universal2.whlpip install torch-scatter https://data.pyg.org/whl/torch-2.7.0%2Bcpu/torch_scatter-2.1.2-cp39-cp39-macosx_10_9_universal2.whlpip install torch-sparse https://data.pyg.org/whl/torch-2.7.0%2Bcpu/torch_sparse-0.6.18-cp39-cp39-macosx_11_0_universal2.whl#torch-spline-conv下載后本地安裝
pip install torch-spline-conv torch_spline_conv-1.2.2-cp39-cp39-macosx_10_9_universal2.whlpip install torch-geometric
四.GCN任務[節點分類-Cora 數據集]
??????????[GCN的論文出處]:Kipf T, Welling M. Semi-supervised classification with graph convolutional networks[C]. The fifth International Conference on Learning Representations, Toulon, France, 2017.
? ? ? ? 有一篇博主的解讀備閱:GNN教程:圖神經網絡“開山之作”! ? ?
????????圖卷積操作的基本思想是將圖數據映射到特定的特征空間,以便更好地捕捉圖數據中的模式和關系。具體來說,圖卷積操作可以看作是一種線性操作,它可以將圖數據表示為一種特定的矩陣形式,然后通過矩陣乘法和線性變換來實現映射。? ?
????????圖神經網絡的具體操作步驟如下;
????????(原博主鏈接:https://juejin.cn/post/7325131333964120101)
-
(1)將圖數據轉換為矩陣形式,以便進行圖卷積操作。具體來說,將鄰接矩陣、特征矩陣和卷積核矩陣構成一個矩陣形式的圖數據。
-
(2)對圖數據進行卷積操作,以便將節點特征映射到特定的特征空間。具體來說,使用卷積核矩陣對圖數據進行線性變換,以實現節點特征的映射。
-
(3)對映射后的節點特征進行激活函數處理,以引入非線性性。具體來說,我們可以使用常見的激活函數,如ReLU、Sigmoid等,對映射后的節點特征進行處理。
? ? ? ? 舉個例子:使用 PyTorch Geometric 加載?Cora 數據集,并實現了一個簡單的兩層 GCN 模型。第一層將節點特征映射到16維空間,第二層將其映射到類別數,并使用 ReLU 激活函數進行非線性變換。
? ? ? ? 若加載數據集報錯,那可能是Github訪問問題,先解決一下:
#找到并打開終端,可用【Command + 空格】聚焦搜索"終端" 回車打開。#修改hosts文件,Mac的hosts文件路徑: /etc/hostssudo vi /etc/hosts#編輯hosts文件,在最后加上:20.27.177.113 github.com# 輸入:wq命令保存#訪問下Github.com 試試
import torch
import torch.nn.functional as F
from torch_geometric.nn import GCNConv
from torch_geometric.datasets import Planetoid
import matplotlib.pyplot as plt
import networkx as nx
from sklearn.manifold import TSNE# 加載Cora數據集
dataset = Planetoid(root='datadownload', name='Cora')data = dataset[0]class GCN(torch.nn.Module):def __init__(self):super(GCN, self).__init__()self.conv1 = GCNConv(dataset.num_node_features, 16)self.conv2 = GCNConv(16, dataset.num_classes)def forward(self, data):x, edge_index = data.x, data.edge_indexx = self.conv1(x, edge_index)x = F.relu(x)x = F.dropout(x, p=0.2, training=self.training) # Dropout操作,減少過擬合風險x = self.conv2(x, edge_index)#x = F.log_softmax(x, dim=1)return x#return # 創建模型并訓練
print(f'dataset.num_node_features:{dataset.num_node_features}')
model = GCN()
print(model)
device = torch.device('mps')
model = model.to(device)
data = data.to(device)
loss_function = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)# 訓練函數
def train():model.train()optimizer.zero_grad()out = model(data)loss = loss_function(out[data.train_mask], data.y[data.train_mask])loss.backward()optimizer.step()return loss.item(),out# 測試函數
def test():model.eval()with torch.no_grad():logits = model(data)accs = []for mask in [data.train_mask, data.val_mask, data.test_mask]:pred = logits[mask].max(1)[1]acc = pred.eq(data.y[mask]).sum().item() / mask.sum().item()accs.append(acc)return accs# 訓練過程
train_losses = []
train_accs = []
val_accs = []
test_accs = []for epoch in range(200):loss,out = train()train_acc, val_acc, test_acc = test()train_losses.append(loss)train_accs.append(train_acc)val_accs.append(val_acc)test_accs.append(test_acc)if epoch % 10 == 0:print(f'Epoch: {epoch:03d}, Loss: {loss:.4f}, 'f'Train: {train_acc:.4f}, Val: {val_acc:.4f}, Test: {test_acc:.4f}')# 可視化圖結構
def visulize_graph(h, color):z = TSNE(n_components=2).fit_transform(h.detach().cpu().numpy())plt.figure(figsize=(10, 10))plt.xticks([])plt.yticks([])plt.scatter(z[:, 0], z[:, 1], s=70, c=color.cpu().numpy(), cmap='Set2')plt.axis('off')plt.savefig('datadownload/cora-graph.png', dpi=300, bbox_inches='tight')plt.close()visulize_graph(out, data.y)
? ? ? ?節點分類結果: Train Accuracy: 1.0000,Validation Accuracy: 0.7720, Test Accuracy: 0.8030?
五.圖注意力網絡(GAT)
? ? ? ? [論文出處]:Veli?kovi?, P., et al. (2018). Graph Attention Networks. ICLR.
????????圖注意力網絡(Graph Attention Network, GAT)通過引入注意力機制來聚合鄰居節點的特征。GAT 使用注意力系數來衡量鄰居節點的重要性。
????????GAT使用 GATConv 代替了 GCNConv。
from torch_geometric.nn import GATConvclass GAT(torch.nn.Module):def __init__(self):super(GAT, self).__init__()self.gat1 = GATConv(dataset.num_node_features, 8, heads=8, concat=True)self.gat2 = GATConv(8 * 8, dataset.num_classes, heads=1, concat=False)def forward(self, data):x, edge_index = data.x, data.edge_indexx = self.gat1(x, edge_index)x = F.elu(x)x = self.gat2(x, edge_index)return F.log_softmax(x, dim=1)# 創建并訓練GAT模型
model = GAT()
optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)model.train()
for epoch in range(200):optimizer.zero_grad()out = model(data)loss = F.nll_loss(out[data.train_mask], data.y[data.train_mask])loss.backward()optimizer.step()print(f'Epoch {epoch}, Loss: {loss.item()}')
? ? ? ? 結果:Train Accuracy: 1.0000,Validation Accuracy: 0.7320, Test Accuracy: 0.7730
六.圖自編碼器(GAE)
????????圖自編碼器(Graph Autoencoder, GAE)是一種用于無監督學習圖嵌入的方法。GAE 通過編碼器和解碼器來學習節點的低維表示。
????????使用了 Variational Graph Autoencoder (VGAE) 來進行圖的無監督學習。GAE 可以有效地學習圖的潛在結構,特別適合于節點嵌入和鏈接預測任務。
from torch_geometric.nn import GCNConv, VGAEclass Encoder(torch.nn.Module):def __init__(self, in_channels, out_channels):super(Encoder, self).__init__()self.conv1 = GCNConv(in_channels, 2 * out_channels, cached=True)self.conv2 = GCNConv(2 * out_channels, out_channels, cached=True)def forward(self, data):x, edge_index = data.x, data.edge_indexx = F.relu(self.conv1(x, edge_index))return self.conv2(x, edge_index) # 定義模型和優化器
encoder = Encoder(dataset.num_node_features, 16)
model = VGAE(encoder)
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)model.train()
for epoch in range(200):optimizer.zero_grad()z = model.encode(data.x, data.edge_index)loss = model.recon_loss(z, data.edge_index)loss.backward()optimizer.step()print(f'Epoch {epoch}, Loss: {loss.item()}')
? ? ? ? 結果:Train Accuracy: 1.0000,Validation Accuracy: 0.7900, Test Accuracy: 0.7990?
七.圖循環神經網絡 (GRNN)
????????圖循環神經網絡 (GRNN:Graph Recurrent Neural Network) 利用多關系圖并使用基于圖的正則化器來提高平滑度并減輕過度參數化。 由于鄰域的確切大小并不總是已知,因此使用循環 GNN 層使網絡更加靈活。 GRNN 可以學習適合數據的最佳擴散模式。 它還能夠處理節點涉及多個關系的情況。 該網絡的計算成本也很低,因為操作數量根據圖邊的數量線性縮放。
八.門控圖神經網絡(GGNN)
????????在具有長期依賴性的問題上,門控圖神經網絡(GGNN:Gated Graph Neural Network)比循環圖神經網絡表現更好。 長期依賴關系由節點和邊緣門編碼。 長期時間依賴性由時間門編碼。 因此,門控圖神經網絡通過添加門控機制來改進循環圖神經網絡。 這些門負責不同狀態下的信息記憶和遺忘。
class GCN_GRU(torch.nn.Module):def __init__(self):super(GCN_GRU, self).__init__()self.gru = nn.GRU(input_size=dataset.num_node_features, hidden_size=16)self.gcn = GCN()def forward(self, data):x, edge_index = data.x, data.edge_indexx = self.gru(x)x = self.gcn(data)return x
結果:Train Accuracy: 1.0000,Validation Accuracy: 0.7680, Test Accuracy: 0.7880
九. 應用場景
(1)社交網絡分析
在社交網絡中,GNN 可以用于節點分類(如用戶興趣預測)、邊預測(如好友推薦)以及社區發現等任務。GCN 和 GAT 等模型能夠有效地捕獲社交網絡中的復雜關系。
(2)推薦系統
在推薦系統中,用戶和商品可以看作是圖中的節點,用戶與商品之間的交互(如評分、點擊)可以作為圖的邊。通過 GNN,我們可以構建用戶和商品的嵌入,用于預測用戶對某商品的興趣。
(3)生物信息學
在生物信息學中,GNN 被廣泛用于蛋白質結構預測、藥物發現和基因相互作用網絡的分析。通過 GNN,可以有效地學習分子結構的表示,從而加速藥物的篩選和發現。