什么是圖形?

圖形是包含節(jié)點(diǎn)和邊的數(shù)據(jù)結(jié)構(gòu)類型。節(jié)點(diǎn)可以是人、地點(diǎn)或事物,邊定義節(jié)點(diǎn)之間的關(guān)系。邊可以基于方向依賴關(guān)系進(jìn)行定向和無向。

在下面的示例中,藍(lán)色圓圈是節(jié)點(diǎn),箭頭是邊。邊的方向定義了兩個(gè)節(jié)點(diǎn)之間的依賴關(guān)系。

讓我們來了解一下復(fù)雜的 Graph 數(shù)據(jù)集:Jazz Musicians Network。它包含 198 個(gè)節(jié)點(diǎn)和 2742 條邊。在下面的社區(qū)圖中,不同顏色的節(jié)點(diǎn)代表爵士音樂家的各種社區(qū)以及連接它們的邊緣。有一個(gè)合作網(wǎng)絡(luò),一個(gè)音樂家在社區(qū)內(nèi)外都有關(guān)系。

Jazz Musicians Network 的社區(qū)圖

圖形在處理關(guān)系和交互的復(fù)雜問題方面非常出色。它們用于模式識(shí)別、社交網(wǎng)絡(luò)分析、推薦系統(tǒng)和語義分析。創(chuàng)建基于圖形的解決方案是一個(gè)全新的領(lǐng)域,它提供了對(duì)復(fù)雜和相互關(guān)聯(lián)的數(shù)據(jù)集的豐富見解。

 使用 NetworkX 繪制圖形

在本節(jié)中,我們將學(xué)習(xí)如何使用 NetworkX 創(chuàng)建圖形。

下面的代碼受到 Daniel Holmberg 關(guān)于 Python 中的圖神經(jīng)網(wǎng)絡(luò)的博客的影響。

  1. 創(chuàng)建 networkx 的 DiGraph 對(duì)象 “H”
  2. 添加包含不同標(biāo)簽、顏色和大小的節(jié)點(diǎn)
  3. 添加邊以在兩個(gè)節(jié)點(diǎn)之間創(chuàng)建關(guān)系。例如,“(0,1)” 表示 0 對(duì) 1 具有方向依賴關(guān)系。我們將通過添加“(1,0)”來創(chuàng)建雙向關(guān)系
  4. 以列表的形式提取顏色和大小
  5. 使用 networkx 的 draw 函數(shù)繪制圖形
import networkx as nx
H = nx.DiGraph()

#adding nodes
H.add_nodes_from([
(0, {"color": "blue", "size": 250}),

(1, {"color": "yellow", "size": 400}),

(2, {"color": "orange", "size": 150}),

(3, {"color": "red", "size": 600})

])

#adding edges
H.add_edges_from([
(0, 1),

(1, 2),

(1, 0),

(1, 3),

(2, 3),

(3,0)

])

node_colors = nx.get_node_attributes(H, "color").values()
colors = list(node_colors)
node_sizes = nx.get_node_attributes(H, "size").values()
sizes = list(node_sizes)

#Plotting Graph
nx.draw(H, with_labels=True, node_color=colors, node_size=sizes)

在下一步中,我們將使用 to_undirected() 函數(shù)將數(shù)據(jù)結(jié)構(gòu)從定向圖轉(zhuǎn)換為無向圖。

#converting to undirected graph
G = H.to_undirected()
nx.draw(G, with_labels=True, node_color=colors, node_size=sizes)

為什么圖很難分析?

基于圖的數(shù)據(jù)結(jié)構(gòu)有缺點(diǎn),數(shù)據(jù)科學(xué)家在開發(fā)基于圖的解決方案之前必須了解這些缺點(diǎn)。

  1. 圖存在于非歐幾里得空間中。它不存在于 2D 或 3D 空間中,這使得解釋數(shù)據(jù)變得更加困難。要在 2D 空間中可視化結(jié)構(gòu),必須使用各種降維工具。
  2. 圖形是動(dòng)態(tài)的;他們沒有固定的形式。可以有兩個(gè)視覺上不同的圖,但它們可能具有相似的鄰接矩陣表示。這使得我們很難使用傳統(tǒng)的統(tǒng)計(jì)工具來分析數(shù)據(jù)。
  3. 大尺寸和大維將增加圖形對(duì)人類解釋的復(fù)雜性。具有多個(gè)節(jié)點(diǎn)和數(shù)千條邊的密集結(jié)構(gòu)更難理解和提取見解。

什么是圖神經(jīng)網(wǎng)絡(luò)(GNN)?

圖神經(jīng)網(wǎng)絡(luò)是能夠處理圖數(shù)據(jù)結(jié)構(gòu)的特殊類型的神經(jīng)網(wǎng)絡(luò)。它們受到卷積神經(jīng)網(wǎng)絡(luò) (CNN) 和圖嵌入的高度影響。GNN 用于預(yù)測(cè)節(jié)點(diǎn)、邊和基于圖的任務(wù)。

當(dāng)卷積神經(jīng)網(wǎng)絡(luò)由于圖的任意大小和復(fù)雜的結(jié)構(gòu)而未能達(dá)到最佳結(jié)果時(shí),引入了GNN。

 圖片由 Purvanshi Mehta 提供

輸入圖通過一系列神經(jīng)網(wǎng)絡(luò)傳遞。輸入圖結(jié)構(gòu)被轉(zhuǎn)換為圖嵌入,使我們能夠維護(hù)有關(guān)節(jié)點(diǎn)、邊緣和全局上下文的信息。

然后,節(jié)點(diǎn) A 和 C 的特征向量通過神經(jīng)網(wǎng)絡(luò)層。它聚合這些特征并將它們傳遞到下一層 – neptune.ai。

閱讀我們的深度學(xué)習(xí)教程或參加我們的深度學(xué)習(xí)入門課程,了解有關(guān)深度學(xué)習(xí)算法和應(yīng)用的更多信息。

圖神經(jīng)網(wǎng)絡(luò)的類型

有幾種類型的神經(jīng)網(wǎng)絡(luò),其中大多數(shù)都有一些卷積神經(jīng)網(wǎng)絡(luò)的變體。在本節(jié)中,我們將了解最流行的 GNN。

如果您有興趣了解有關(guān)遞歸神經(jīng)網(wǎng)絡(luò) (RNN) 的更多信息,請(qǐng)查看 DataCamp 的課程。它將向您介紹各種 RNN 模型架構(gòu)、Keras 框架和 RNN 應(yīng)用程序。

圖神經(jīng)網(wǎng)絡(luò)任務(wù)的類型

下面,我們通過示例概述了一些類型的 GNN 任務(wù):

 圖片由作者提供

圖神經(jīng)網(wǎng)絡(luò)的缺點(diǎn)

了解它們將有助于我們確定何時(shí)使用 GNNa 以及如何優(yōu)化機(jī)器學(xué)習(xí)模型的性能。

  1. 大多數(shù)神經(jīng)網(wǎng)絡(luò)可以深入以獲得更好的性能,而 GNN 是淺層網(wǎng)絡(luò),主要有三層。它限制了我們?cè)诖笮蛿?shù)據(jù)集上實(shí)現(xiàn)最先進(jìn)的性能。
  2. 圖形結(jié)構(gòu)在不斷變化,這使得在其上訓(xùn)練模型變得更加困難。
  3. 將模型部署到生產(chǎn)環(huán)境面臨可伸縮性問題,因?yàn)檫@些網(wǎng)絡(luò)的計(jì)算成本很高。如果你有一個(gè)龐大而復(fù)雜的圖結(jié)構(gòu),你將很難在生產(chǎn)環(huán)境中擴(kuò)展 GNN。

什么是圖卷積網(wǎng)絡(luò)(GCN)?

大多數(shù) GNN 都是圖卷積網(wǎng)絡(luò),在進(jìn)入節(jié)點(diǎn)分類教程之前了解它們很重要。

GCN 中的卷積與卷積神經(jīng)網(wǎng)絡(luò)中的卷積相同。它用權(quán)重(過濾器)將神經(jīng)元相乘,以從數(shù)據(jù)特征中學(xué)習(xí)。

它充當(dāng)整個(gè)圖像的滑動(dòng)窗口,以從相鄰單元格中學(xué)習(xí)特征。該過濾器使用權(quán)重共享來學(xué)習(xí)圖像識(shí)別系統(tǒng)中的各種面部特征 – 邁向數(shù)據(jù)科學(xué)。

現(xiàn)在將相同的功能轉(zhuǎn)移到圖卷積網(wǎng)絡(luò),其中模型從相鄰節(jié)點(diǎn)學(xué)習(xí)特征。GCN 和 CNN 之間的主要區(qū)別在于,它是為處理節(jié)點(diǎn)和邊的順序可能變化的非歐幾里得數(shù)據(jù)結(jié)構(gòu)而開發(fā)的。

CNN 與 GCN |圖片來源

通過閱讀卷積神經(jīng)網(wǎng)絡(luò) (CNN) 和 TensorFlow 教程,了解有關(guān)基本 CNN 的更多信息。

有兩種類型的 GCN:

GNN 如何工作?使用 Pytorch 構(gòu)建圖神經(jīng)網(wǎng)絡(luò)

我們將為節(jié)點(diǎn)分類模型構(gòu)建和訓(xùn)練 Spectral Graph Convolution。Workspace 上提供了代碼源,供你體驗(yàn)和運(yùn)行第一個(gè)基于圖形的機(jī)器學(xué)習(xí)模型。

編碼示例受 Pytorch 幾何文檔的影響。

 開始

我們將安裝 Pytorch 包,因?yàn)?pytorch_geometric 是建立在它之上的。

!pip install -q torch

然后我們將安裝 torch-scatter 和 torch-sparse。之后,我們將從 GitHub 安裝 pytorch_geometric 的最新版本。

%%capture
import os
import torch
os.environ['TORCH'] = torch.__version__
os.environ['PYTHONWARNINGS'] = "ignore"
!pip install torch-scatter -f https://data.pyg.org/whl/torch-${TORCH}.html
!pip install torch-sparse -f https://data.pyg.org/whl/torch-${TORCH}.html
!pip install git+https://github.com/pyg-team/pytorch_geometric.git

Planetoid Cora 數(shù)據(jù)集

Planetoid 是來自 Cora、CiteSeer 和 PubMed 的引文網(wǎng)絡(luò)數(shù)據(jù)集。節(jié)點(diǎn)是具有 1433 維詞袋特征向量的文檔,邊緣是研究論文之間的引文鏈接。有 7 個(gè)類,我們將訓(xùn)練模型來預(yù)測(cè)缺失的標(biāo)簽。

我們將引入 Planetoid Cora 數(shù)據(jù)集,并對(duì)詞袋輸入要素進(jìn)行行規(guī)范化。之后,我們將分析數(shù)據(jù)集和第一個(gè)圖形對(duì)象。

from torch_geometric.datasets import Planetoid
from torch_geometric.transforms import NormalizeFeatures

dataset = Planetoid(root='data/Planetoid', name='Cora', transform=NormalizeFeatures())

print(f'Dataset: {dataset}:')
print('======================')
print(f'Number of graphs: {len(dataset)}')
print(f'Number of features: {dataset.num_features}')
print(f'Number of classes: {dataset.num_classes}')

data = dataset[0] # Get the first graph object.
print(data)

Cora 數(shù)據(jù)集有 2708 個(gè)節(jié)點(diǎn)、10,556 條邊、1433 個(gè)要素和 7 個(gè)類。第一個(gè)對(duì)象有 2708 個(gè)訓(xùn)練掩碼、驗(yàn)證掩碼和測(cè)試掩碼。我們將使用這些掩碼來訓(xùn)練和評(píng)估模型。

Dataset: Cora():
======================
Number of graphs: 1
Number of features: 1433
Number of classes: 7
Data(x=[2708, 1433], edge_index=[2, 10556], y=[2708], train_mask=[2708], val_mask=[2708], test_mask=[2708])

使用 GNN 進(jìn)行節(jié)點(diǎn)分類

我們將創(chuàng)建一個(gè) GCN 模型結(jié)構(gòu),其中包含兩個(gè) GCNConv 層、relu 激活和 0.5 的輟學(xué)率。該模型由 16 個(gè)隱藏通道組成。

 GCN層:

W(l+1) 是上式中的可移動(dòng)權(quán)重矩陣,Cw,v 對(duì)每條邊都具有固定的歸一化系數(shù)。

from torch_geometric.nn import GCNConv
import torch.nn.functional as F

class GCN(torch.nn.Module):
def __init__(self, hidden_channels):
super().__init__()
torch.manual_seed(1234567)
self.conv1 = GCNConv(dataset.num_features, hidden_channels)
self.conv2 = GCNConv(hidden_channels, dataset.num_classes)

def forward(self, x, edge_index):
x = self.conv1(x, edge_index)
x = x.relu()
x = F.dropout(x, p=0.5, training=self.training)
x = self.conv2(x, edge_index)
return x

model = GCN(hidden_channels=16)
print(model)

>>> GCN(
(conv1): GCNConv(1433, 16)
(conv2): GCNConv(16, 7)
)

可視化未經(jīng)訓(xùn)練的 GCN 網(wǎng)絡(luò)

讓我們使用 sklearn.manifold.TSNE 和 matplotlib.pyplot 可視化未經(jīng)訓(xùn)練的 GCN 網(wǎng)絡(luò)的節(jié)點(diǎn)嵌入。它將繪制一個(gè)嵌入 2D 散點(diǎn)圖的 7 維節(jié)點(diǎn)。

%matplotlib inline
import matplotlib.pyplot as plt
from sklearn.manifold import TSNE

def visualize(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, cmap="Set2")
plt.show()

我們將評(píng)估模型,然后將訓(xùn)練數(shù)據(jù)添加到未訓(xùn)練的模型中,以可視化各種節(jié)點(diǎn)和類別。

model.eval()

out = model(data.x, data.edge_index)
visualize(out, color=data.y)

訓(xùn)練 GNN

我們將使用 Adam 優(yōu)化和交叉熵?fù)p失函數(shù)在 100 個(gè) Epoch 上訓(xùn)練我們的模型

在 train 函數(shù)中,我們有:

  1.  清除漸變
  2. 執(zhí)行了一次前向傳遞
  3. 使用訓(xùn)練節(jié)點(diǎn)計(jì)算損失
  4. 計(jì)算梯度并更新參數(shù)

在測(cè)試函數(shù)中,我們有:

  1.  預(yù)測(cè)的節(jié)點(diǎn)類
  2. 概率最高的提取類標(biāo)簽
  3. 已檢查正確預(yù)測(cè)的值數(shù)
  4. 使用正確預(yù)測(cè)的總和除以節(jié)點(diǎn)總數(shù)來創(chuàng)建準(zhǔn)確率。
model = GCN(hidden_channels=16)
optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)
criterion = torch.nn.CrossEntropyLoss()

def train():
model.train()
optimizer.zero_grad()
out = model(data.x, data.edge_index)
loss = criterion(out[data.train_mask], data.y[data.train_mask])
loss.backward()
optimizer.step()
return loss

def test():
model.eval()
out = model(data.x, data.edge_index)
pred = out.argmax(dim=1)
test_correct = pred[data.test_mask] == data.y[data.test_mask]
test_acc = int(test_correct.sum()) / int(data.test_mask.sum())
return test_acc

for epoch in range(1, 101):
loss = train()
print(f'Epoch: {epoch:03d}, Loss: {loss:.4f}')
GAT(
(conv1): GATConv(1433, 8, heads=8)
(conv2): GATConv(64, 7, heads=8)
)

.. .. .. ..
.. .. .. ..
Epoch: 098, Loss: 0.5989
Epoch: 099, Loss: 0.6021
Epoch: 100, Loss: 0.5799

 模型評(píng)估

現(xiàn)在,我們將使用測(cè)試函數(shù)在看不見的數(shù)據(jù)集上評(píng)估模型,正如您所看到的,我們以 81.5% 的準(zhǔn)確率獲得了相當(dāng)不錯(cuò)的結(jié)果。

test_acc = test()
print(f'Test Accuracy: {test_acc:.4f}')

>>> Test Accuracy: 0.8150

現(xiàn)在,我們將可視化經(jīng)過訓(xùn)練的模型的輸出嵌入以驗(yàn)證結(jié)果。

model.eval()
out = model(data.x, data.edge_index)
visualize(out, color=data.y)

正如我們所看到的,經(jīng)過訓(xùn)練的模型為同一類別的節(jié)點(diǎn)生成了更好的聚類。

 訓(xùn)練 GATConv 模型

在第二種情況下,我們將用 GATConv 層替換 GCNConv。圖注意力網(wǎng)絡(luò)使用屏蔽的自我注意力層來解決 GCNConv 的缺點(diǎn)并實(shí)現(xiàn)最先進(jìn)的結(jié)果。

您還可以嘗試其他 GNN 層,并嘗試優(yōu)化、丟棄和一些隱藏通道,以實(shí)現(xiàn)更好的性能。

在下面的代碼中,我們剛剛將 GCNConv 替換為 GATConv,第一層有 8 個(gè)注意力頭,第二層有 1 個(gè)注意力頭。

 我們還將設(shè)置:

我們修改了測(cè)試函數(shù),以查找特定掩碼的準(zhǔn)確性(有效,測(cè)試)。它將幫助我們?cè)?a href="http://www.dlbhg.com/wiki/what-is-a-large-model-understand-the-basic-concepts-of-ai/">模型訓(xùn)練期間打印出驗(yàn)證和測(cè)試分?jǐn)?shù)。稍后,我們還會(huì)將驗(yàn)證和測(cè)試結(jié)果存儲(chǔ)到繪圖折線圖中。

from torch_geometric.nn import GATConv

class GAT(torch.nn.Module):
def __init__(self, hidden_channels, heads):
super().__init__()
torch.manual_seed(1234567)
self.conv1 = GATConv(dataset.num_features, hidden_channels,heads)
self.conv2 = GATConv(heads*hidden_channels, dataset.num_classes,heads)

def forward(self, x, edge_index):
x = F.dropout(x, p=0.6, training=self.training)
x = self.conv1(x, edge_index)
x = F.elu(x)
x = F.dropout(x, p=0.6, training=self.training)
x = self.conv2(x, edge_index)
return x

model = GAT(hidden_channels=8, heads=8)
print(model)

optimizer = torch.optim.Adam(model.parameters(), lr=0.005, weight_decay=5e-4)
criterion = torch.nn.CrossEntropyLoss()

def train():
model.train()
optimizer.zero_grad()
out = model(data.x, data.edge_index)
loss = criterion(out[data.train_mask], data.y[data.train_mask])
loss.backward()
optimizer.step()
return loss

def test(mask):
model.eval()
out = model(data.x, data.edge_index)
pred = out.argmax(dim=1)
correct = pred[mask] == data.y[mask]
acc = int(correct.sum()) / int(mask.sum())
return acc

val_acc_all = []
test_acc_all = []

for epoch in range(1, 101):
loss = train()
val_acc = test(data.val_mask)
test_acc = test(data.test_mask)
val_acc_all.append(val_acc)
test_acc_all.append(test_acc)
print(f'Epoch: {epoch:03d}, Loss: {loss:.4f}, Val: {val_acc:.4f}, Test: {test_acc:.4f}')

.. .. .. ..
.. .. .. ..
Epoch: 098, Loss: 1.1283, Val: 0.7960, Test: 0.8030

Epoch: 099, Loss: 1.1352, Val: 0.7940, Test: 0.8050

Epoch: 100, Loss: 1.1053, Val: 0.7960, Test: 0.8040

正如我們所觀察到的,我們的模型并不比 GCNConv 表現(xiàn)得更好。它需要超參數(shù)優(yōu)化或更多的 Epoch 才能獲得最先進(jìn)的結(jié)果。

 模型評(píng)估

在評(píng)估部分,我們使用 matplotlib.pyplot 的折線圖可視化驗(yàn)證和測(cè)試分?jǐn)?shù)。

import numpy as np

plt.figure(figsize=(12,8))
plt.plot(np.arange(1, len(val_acc_all) + 1), val_acc_all, label='Validation accuracy', c='blue')
plt.plot(np.arange(1, len(test_acc_all) + 1), test_acc_all, label='Testing accuracy', c='red')
plt.xlabel('Epochs')
plt.ylabel('Accurarcy')
plt.title('GATConv')
plt.legend(loc='lower right', fontsize='x-large')
plt.savefig('gat_loss.png')
plt.show()

在60個(gè)周期后,驗(yàn)證和測(cè)試精度達(dá)到了0.8+/-0.02的穩(wěn)定值。

同樣,讓我們可視化 GATConv 模型的節(jié)點(diǎn)聚類。

model.eval()

out = model(data.x, data.edge_index)
visualize(out, color=data.y)

正如我們所看到的,GATConv 層在同一類別的節(jié)點(diǎn)上聚類時(shí)產(chǎn)生了相同的結(jié)果。

我們可以通過添加驗(yàn)證數(shù)據(jù)集來減少過擬合,并通過試驗(yàn)pytoch_geometric中的各種 GCN 層來提高模型性能。

本文章轉(zhuǎn)載微信公眾號(hào)@Python人工智能前沿

上一篇:

最全總結(jié)!機(jī)器學(xué)習(xí)優(yōu)化算法!

下一篇:

超詳細(xì)!聚類算法總結(jié)及對(duì)比!
#你可能也喜歡這些API文章!

我們有何不同?

API服務(wù)商零注冊(cè)

多API并行試用

數(shù)據(jù)驅(qū)動(dòng)選型,提升決策效率

查看全部API→
??

熱門場(chǎng)景實(shí)測(cè),選對(duì)API

#AI文本生成大模型API

對(duì)比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力

25個(gè)渠道
一鍵對(duì)比試用API 限時(shí)免費(fèi)

#AI深度推理大模型API

對(duì)比大模型API的邏輯推理準(zhǔn)確性、分析深度、可視化建議合理性

10個(gè)渠道
一鍵對(duì)比試用API 限時(shí)免費(fèi)