GCN原理回顧論文導讀

Cora_dataset description

Cora數據集是一個常用的學術文獻用網絡數據集,用于研究學術文獻分類和圖網絡分析等任務。
該數據集由機器學習領域的博士論文摘要組成,共計2708篇論文,涵蓋了7個不同的學科領域。每篇論文都有一個唯一的ID,并且被分為以下7個類別之一:Case_Based、Genetic_Algorithms、Neural_Networks、Probabilistic_Methods、Reinforcement_Learning、Rule_Learning和Theory。

除了論文之間的引用關系外,Cora數據集還包含了每篇論文的詞袋表示,即將每篇論文表示為一個詞頻向量(0-1嵌入,每行有多個1,非one-hot vector,feature of node)。這些詞頻向量表示了論文中出現的單詞及其在該論文中的出現頻率。

Cora數據集常用于圖神經網絡的研究和評估,可以用于學術文獻分類、引文網絡分析、節點嵌入等任務。

print cora

dataset = Planetoid("./tmp/Cora", name="Cora", transform=T.NormalizeFeatures())
num_nodes = dataset.data.num_nodes
# For num. edges see:
# - https://github.com/pyg-team/pytorch_geometric/issues/343
# - https://github.com/pyg-team/pytorch_geometric/issues/852num_edges = dataset.data.num_edges // 2
train_len = dataset[0].train_mask.sum()
val_len = dataset[0].val_mask.sum()
test_len = dataset[0].test_mask.sum()
other_len = num_nodes - train_len - val_len - test_len
print(f"Dataset: {dataset.name}")
print(f"Num. nodes: {num_nodes} (train={train_len}, val={val_len}, test={test_len}, other={other_len})")
print(f"Num. edges: {num_edges}")
print(f"Num. node features: {dataset.num_node_features}")
print(f"Num. classes: {dataset.num_classes}")
print(f"Dataset len.: {dataset.len()}")

在這里插入圖片描述

GCN原理與實現

卷積公式: f ? g = F ? 1 ( F ( f ) ? F ( g ) ) f*g=F^{-1}(F(f)·F(g)) f?g=F?1(F(f)?F(g))
給定一個圖信號x和一個卷積核, x ? g = U ( U T x ⊙ U T g ) = U ( U T x ⊙ g θ ) = D ~ ? 0.5 A ~ D ~ ? 0.5 X Θ x*g=U(U^Tx\odot U^Tg)=U(U^Tx\odot g_{\theta})=\widetilde D^{-0.5}\widetilde A\widetilde D^{-0.5}X\Theta x?g=U(UTxUTg)=U(UTxgθ?)=D ?0.5A D ?0.5XΘ
其中A為圖的鄰接矩陣,D為圖的度數矩陣,
D ~ = D + γ I , A ~ = A + γ I \widetilde D=D+\gamma I,\widetilde A=A+\gamma I D =D+γI,A =A+γI,添加自環以縮小 λ \lambda λ(Laplace matrix)

1.computation of D ~ ? 0.5 A ~ D ~ ? 0.5 \widetilde D^{-0.5}\widetilde A\widetilde D^{-0.5} D ?0.5A D ?0.5

def gcn_norm(edge_index, edge_weight=None, num_nodes=None,
add_self_loops=True, flow="source_to_target", dtype=None):
fill_value = 1.
num_nodes = maybe_num_nodes(edge_index, num_nodes)
if add_self_loops: #添加自環
edge_index, edge_weight = add_remaining_self_loops(
edge_index, edge_weight, fill_value, num_nodes)
edge_weight = torch.ones((edge_index.size(1), ), dtype=dtype,
device=edge_index.device)
row, col = edge_index[0], edge_index[1]
idx = col
deg = scatter(edge_weight, idx, dim=0, dim_size=num_nodes, reduce='sum')
deg_inv_sqrt = deg.pow_(-0.5)
deg_inv_sqrt.masked_fill_(deg_inv_sqrt == float('inf'), 0)
edge_weight = deg_inv_sqrt[row] * edge_weight * deg_inv_sqrt[col]
return edge_index, edge_weight

代碼解釋

edge_index, edge_weight = add_remaining_self_loops(edge_index, edge_weight,fill_value, num_nodes)
D ~ = D + γ I , A ~ = A + γ I \widetilde D=D+\gamma I,\widetilde A=A+\gamma I D =D+γI,A =A+γI;
deg = scatter(edge_weight, idx, dim=0, dim_size=num_nodes, reduce='sum')
根據edge_weight和idx=edge_index[1]得到度數矩陣,deg=D

  • explantation:edge_weight是要放入的對角陣,

deg_inv_sqrt = deg.pow_(-0.5):require D ? 0.5 D^{-0.5} D?0.5
deg_inv_sqrt.masked_fill_(deg_inv_sqrt == float('inf'), 0)
由于D非對角元=0,其-0.5次冪=∞,需要轉化為0,
edge_weight = deg_inv_sqrt[row] * edge_weight * deg_inv_sqrt[col]
輸出歸一化后的edge_index

2. PairNorm

在這里插入圖片描述

3.GCNConv的實現如下(刪改自torch_geometric.nn.GCNConv)

class myGCNConv2(MessagePassing):def __init__(self, in_channels: int, out_channels: int,add_self_loops: bool = True,bias: bool = True):super().__init__()self.in_channels = in_channelsself.out_channels = out_channelsself.add_self_loops = add_self_loopsself.lin = Linear(in_channels, out_channels, bias=False,weight_initializer='glorot')if bias:self.bias = Parameter(torch.Tensor(out_channels))else:self.register_parameter('bias', None)self.reset_parameters()def reset_parameters(self):super().reset_parameters()self.lin.reset_parameters()         #卷積層zeros(self.bias)                    #偏置層def forward(self, x: Tensor, edge_index: Adj,edge_weight: OptTensor = None) -> Tensor:edge_index, edge_weight = gcn_norm(  # yapf: disableedge_index, edge_weight, x.size(self.node_dim),self.add_self_loops, self.flow, x.dtype)x = self.lin(x)# propagate_type: (x: Tensor, edge_weight: OptTensor)out = self.propagate(edge_index, x=x, edge_weight=edge_weight,size=None)if self.bias is not None:out = out + self.biasreturn outdef message(self, x_j: Tensor, edge_weight: OptTensor) -> Tensor:return x_j if edge_weight is None else edge_weight.view(-1, 1) * x_jdef message_and_aggregate(self, adj_t: SparseTensor, x: Tensor) -> Tensor:return spmm(adj_t, x, reduce=self.aggr)

代碼解釋

x = self.lin(x) X ′ = X Θ , X ∈ R n ? d 1 , Θ ∈ R d 1 ? d 2 X'=X\Theta,X\in R^{n*d1},\Theta \in R^{d1*d2} X=XΘXRn?d1ΘRd1?d2,對X降維
out = self.propagate(edge_index, x=x, edge_weight=edge_weight,size=None)
out= A ′ X ′ = D ~ ? 1 2 A ~ D ~ ? 1 2 X Θ A'X'=\widetilde D^{-\frac 1 2}\widetilde A \widetilde D^{-\frac 1 2 } X \Theta AX=D ?21?A D ?21?XΘ
Converge {x1’,…,xn’} ,each of which be a sampled vector,into target form.

message&message_and_aggregate為MessagePassing.propagate的相關函數,
經測試,刪除后,val acc下降,故予以保留

4.Net(GCN)的實現

class GCN(torch.nn.Module):
def __init__(
self,
num_node_features: int,
num_classes: int,
hidden_dim: int = 16,
dropout_rate: float = 0.5,
) -> None:
super().__init__()
self.dropout1 = torch.nn.Dropout(dropout_rate)
self.conv1 = myGCNConv2(num_node_features,
hidden_dim,add_self_loops=True)
self.relu = torch.nn.ReLU(inplace=True)
self.dropout2 = torch.nn.Dropout(dropout_rate)
self.conv2 = myGCNConv2(hidden_dim, num_classes,add_self_loops=True)
self.pn=PairNorm()
def forward(self, x: Tensor, edge_index: Tensor) -> torch.Tensor:
x = self.pn(x)
x = self.dropout1(x)
x = self.conv1(x, edge_index)
x = self.relu(x)
x = self.dropout2(x)
x = self.conv2(x, edge_index)
return x

代碼解釋

x = self.pn(x):對x作PairNorm處理,之后xi~N(0,s2),各節點特征范數大小平衡,作用不明顯;
采用2層GCN卷積層,中間用relu激活,dropout避免過擬合

DropEdge Realization的手動實現

  • idea
  1. 首先把有向圖的邊,轉化為無向圖的邊,保存在single_edge_index中,實現時先用single_edge字
    典存儲每條無向邊(key-value 任意)1次,再把single_edge轉化成無向圖的邊集索引(2-dim tensor
    array)
#single_edge_index
single_edge={}
for i in range(len(dataset.data.edge_index[0])):if(((dataset.data.edge_index[0][i],dataset.data.edge_index[1][i]) not in single_edge.items()) and ((dataset.data.edge_index[1][i],dataset.data.edge_index[0][i]) not in single_edge.items())):single_edge[dataset.data.edge_index[0][i]]=dataset.data.edge_index[1][i]single_edge_index=[[],[]]for key,value in single_edge.items():single_edge_index[0].append(key)single_edge_index[1].append(value)        single_edge_index=torch.tensor(single_edge_index)
  1. 再把無向邊集舍去dropout_rate比例的部分,之后轉成有向邊集索引
def drop_edge(single_edge_index, dropout_rate):# 計算需要丟棄的邊數num_edges = single_edge_index.shape[1]num_drop = int(num_edges * dropout_rate)# 隨機選擇要丟棄的邊remain_indices = torch.randperm(num_edges)[num_drop:]remain_single_edges = single_edge_index[:, remain_indices]reverse_edges = torch.stack([remain_single_edges[1],remain_single_edges[0]],dim=0)remain_edges=torch.cat([remain_single_edges,reverse_edges],dim=1)return remain_edges

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/717174.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/717174.shtml
英文地址,請注明出處:http://en.pswp.cn/news/717174.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Linux】linux內核模塊編譯makefile

1、編譯進內核的模塊 如果需要將foo.ko編譯進內核,需要在makefile中進行配置: obj-y foo.o2、編譯可加載的模塊 如果需要將foo.ko編譯成可加載模塊,需要在makefile中進行配置: obj-m foo.oobj-m表示編譯生成可加載模塊。相對…

jQuery詳細介紹

一、引言 在Web開發的歷史長河中,JavaScript一直扮演著至關重要的角色。然而,原生的JavaScript在某些方面存在不足,如瀏覽器兼容性、DOM操作繁瑣等。為了簡化這些問題,jQuery應運而生。jQuery是一個輕量級的、功能豐富的JavaScri…

李沐動手學習深度學習——3.5練習

減少batch_size(如減少到1)是否會影響讀取性能? 肯定會影響,計算機io性能而言,隨著batch_size增大,讀取越來越快,需要的時間越少。這里會涉及到計算機操作系統的知識點,內存與硬盤之…

AmzTrends x TiDB Serverless:通過云原生改造實現全局成本降低 80%

本文介紹了廈門笛卡爾數據(AmzTrends)在面臨數據存儲挑戰時,選擇將其數據分析服務遷移到 TiDB Serverless 的思路和實踐。通過全托管的數據庫服務,AmzTrends 實現了全局成本降低 80% 的效果,同時也充分展示了 TiDB Ser…

redis一些概念知識

一、redis是什么 Redis是一種非關系型數據庫(NoSQL),它主要以鍵值對存儲數據。與傳統的關系型數據庫相比,Redis更注重內存操作和高性能,常被用作緩存系統或分布式存儲系統。 以簡單的比喻來解釋Redis,可以…

kafka進階(二)

文章目錄 前言一、Ack機制二、ISR集合總結 前言 本篇主要介紹kafka 的 Ack機制 和 ISR集合 一、Ack機制 Kafka提供了三種不同的應答機制(ACK): acks0:這是最不可靠的模式。在這種模式下,生產者不會等待來自服務器的…

三、軟考-系統架構設計師筆記-計算機系統基礎知識

計算機系統概述 計算機系統是指用于數據管理的計算機硬件、軟件及網絡組成的系統。 它是按人的要求接收和存儲信息,自動進行數據處理和計算,并輸出結果信息的機器系統。 馮諾依曼體系計算機結構: 1、計算機硬件組成 馮諾依曼計算機結構將…

正向代理的反爬蟲與防DDoS攻擊:保護網站免受惡意行為

目錄 前言 一、正向代理的原理 二、正向代理的反爬蟲功能 1. IP地址隱藏 2. 請求多樣化 三、正向代理的防DDoS攻擊功能 1. 均衡負載 2. IP過濾 結論 前言 在當前互聯網環境下,網站常常受到各種惡意行為的侵襲,其中包括爬蟲和DDoS攻擊。這些行為…

#WEB前端(DIV、SPAN)

1.實驗&#xff1a;DIV、SPAN 2.IDE&#xff1a;VSCODE 3.記錄&#xff1a; 類? 4.代碼&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdev…

《中國計算機學會通訊》2022年第10期讀書筆記

試看&#xff1a;https://dl.ccf.org.cn/reading.html?_ack1&id6177027364096000 為計算機科學技術的大變局立言 重要的不是找答案&#xff0c;而是提出別人沒有想到或者還不重視的科學問題和技術方向。 幾乎沒有人愿意去去急需研發人才的中小企業。 CCCF應當關心作為…

數據庫系統架構與DBMS功能探微:現代信息時代數據管理的關鍵

?? 歡迎大家來訪Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭?&#xff5e;?? &#x1f31f;&#x1f31f; 歡迎各位親愛的讀者&#xff0c;感謝你們抽出寶貴的時間來閱讀我的文章。 我是Srlua&#xff0c;在這里我會分享我的知識和經驗。&#x…

現代化數據架構升級:毫末智行自動駕駛如何應對年增20PB的數據規模挑戰?-OceanBase案例

毫末智行是一家致力于自動駕駛的人工智能技術公司&#xff0c;其前身是長城汽車智能駕駛前瞻分部&#xff0c;以零事故、零擁堵、自由出行和高效物流為目標&#xff0c;助力合作伙伴重塑和全面升級整個社會的出行及物流方式。 在自動駕駛領域中&#xff0c;是什么原因讓毫末智行…

Linux——基本指令

系列文章目錄 文章目錄 系列文章目錄一、Linux基本常識二、Linux基本指令2.1 mkdir指令&#xff08;重要&#xff09;2.2 rmdir指令2.3 rm指令&#xff08;重要&#xff09;2.4 touch指令2.5 ls指令2.6 pwd指令2.7 cd指令2.7.1 Linux中的目錄結構2.7.2 絕對路徑和相對路徑2.7.3…

對程序、進程、線程、并發、并行、高并發概念的講解

一、概述 程序、進程、線程、并發、并行和高并發是計算機科學領域中非常重要的概念。 了解進程、線程、并發和并行的概念&#xff0c;可以更好地利用計算機的多核處理器和并行計算能力&#xff0c;提高計算機性能。 了解進程和線程為操作系統中的資源管理提供了基礎&#xff…

【風格遷移】對比度保持連貫性損失 CCPL:解決圖像局部失真、視頻幀間的連貫性和閃爍

對比度保持連貫性損失 CCPL&#xff1a;解決圖像局部失真、視頻幀間的連貫性和閃爍 提出背景解法&#xff1a;對比度保持連貫性損失&#xff08;CCPL&#xff09; 局部一致性假設 對比學習機制 鄰域調節策略 互信息最大化對比學習&#xff1a;在無需標簽的情況下有效學習區分…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的教室人員檢測與計數(Python+PySide6界面+訓練代碼)

摘要&#xff1a;開發教室人員檢測與計數系統對于優化教學資源和提升教學效率具有重要意義。本篇博客詳細介紹了如何利用深度學習構建此系統&#xff0c;并提供了完整的實現代碼。該系統基于強大的YOLOv8算法&#xff0c;并對比了YOLOv7、YOLOv6、YOLOv5的性能&#xff0c;展示…

藍橋杯第2章:基礎算法_3

1.聰明的小羊肖恩 - 藍橋云課 (lanqiao.cn) #include <bits/stdc.h> using namespace std; typedef long long LL; const int mod100000007; const int N200010; int n,L,R; int a[N]; LL calc(int v){//計算數組a中兩個數之和小于等于v的數對數量int l1,rn;LL ans0;whi…

[vue error] TypeError: AutoImportis not a function

問題詳情 問題描述: element plus按需導入后&#xff0c;啟動項目報錯&#xff1a; 問題解決 將unplugin-auto-import 回退到0.16.1 npm install unplugin-auto-import0.16.1 安裝完后再次運行就好了

差分題練習(區間更新)

一、差分的特點和原理 對于一個數組a[]&#xff0c;差分數組diff[]的定義是: 對差分數組做前綴和可以還原為原數組: 利用差分數組可以實現快速的區間修改&#xff0c;下面是將區間[l, r]都加上x的方法: diff[l] x; diff[r 1] - x;在修改完成后&#xff0c;需要做前綴和恢復…

PYTHON 自動化辦公:壓縮圖片(PIL)

1、介紹 在辦公還是學習過程中&#xff0c;難免會遇到上傳照片的問題。然而照片的大小限制一直都是個問題&#xff0c;例如照片限制在200Kb之內&#xff0c;雖然有很多圖像壓縮技術可以實現&#xff0c;但從圖像處理的專業來說&#xff0c;可以利用代碼實現 這里使用的庫函數是…