鍵.png)
使用這些基本 REST API 最佳實(shí)踐構(gòu)建出色的 API
圖形是包含節(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ù)集的豐富見解。
在本節(jié)中,我們將學(xué)習(xí)如何使用 NetworkX 創(chuàng)建圖形。
下面的代碼受到 Daniel Holmberg 關(guān)于 Python 中的圖神經(jīng)網(wǎng)絡(luò)的博客的影響。
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)。
圖神經(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ò),其中大多數(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)用程序。
下面,我們通過示例概述了一些類型的 GNN 任務(wù):
圖片由作者提供
了解它們將有助于我們確定何時(shí)使用 GNNa 以及如何優(yōu)化機(jī)器學(xué)習(xí)模型的性能。
大多數(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:
我們將為節(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、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])
我們將創(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)
)
讓我們使用 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)
我們將使用 Adam 優(yōu)化和交叉熵?fù)p失函數(shù)在 100 個(gè) Epoch 上訓(xùn)練我們的模型。
在 train 函數(shù)中,我們有:
在測(cè)試函數(shù)中,我們有:
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
現(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)生成了更好的聚類。
在第二種情況下,我們將用 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)估部分,我們使用 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人工智能前沿
對(duì)比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力
一鍵對(duì)比試用API 限時(shí)免費(fèi)