網(wǎng)絡(luò)GNN入門:從非歐式數(shù)據(jù)到聚合更新機(jī)制)
簡(jiǎn)介這是一份面向深度學(xué)習(xí)入門者與進(jìn)階研究者的圖神經(jīng)網(wǎng)絡(luò)系統(tǒng)講解PPT共100頁(yè)圍繞GNN基礎(chǔ)與多個(gè)變體展開幫助讀者建立從非歐式數(shù)據(jù)建模到圖卷積、注意力、自編碼器等完整知識(shí)框架。內(nèi)容按四部分組織為什么需要GNN、圖與GNN基本操作、GNN三大變體含DCNN、NN4G、MPNN、GAT、GAE、VGAE等具體模型以及在自然語(yǔ)言處理、計(jì)算機(jī)視覺(jué)、推薦系統(tǒng)和預(yù)測(cè)問(wèn)題中的應(yīng)用并討論了圖表示與計(jì)算效率等挑戰(zhàn)。資源包為1個(gè)pptx文件大小約12.69MB結(jié)構(gòu)清晰、圖文并茂適合課堂講授或自學(xué)參考。目前已有1581人學(xué)習(xí)可作為理解圖神經(jīng)網(wǎng)絡(luò)原理、梳理模型脈絡(luò)與準(zhǔn)備相關(guān)課題的參考資料。1. 圖神經(jīng)網(wǎng)絡(luò)為什么 CNN 的卷積核到了圖數(shù)據(jù)上就失效了把一張圖片旋轉(zhuǎn) 90 度CNN 照樣能認(rèn)出里面的貓但把社交網(wǎng)絡(luò)里節(jié)點(diǎn)的編號(hào)隨機(jī)打亂很多模型直接翻車。這個(gè)反直覺(jué)的差異正是圖神經(jīng)網(wǎng)絡(luò)GNN要解決的核心問(wèn)題。圖像、文本、音頻這類歐式數(shù)據(jù)節(jié)點(diǎn)排列有固定順序鄰居數(shù)量恒定所以一個(gè)全局共享的卷積核就能橫掃整張圖??涩F(xiàn)實(shí)里越來(lái)越多的數(shù)據(jù)——社交關(guān)系、分子結(jié)構(gòu)、知識(shí)圖譜——屬于非歐式數(shù)據(jù)節(jié)點(diǎn)沒(méi)有固定順序每個(gè)節(jié)點(diǎn)的鄰居數(shù)量可能從 1 個(gè)到幾千個(gè)不等連接關(guān)系還是動(dòng)態(tài)多模態(tài)的。你沒(méi)法再用一個(gè)固定大小的卷積核去滑動(dòng)因?yàn)椤盎瑒?dòng)”這個(gè)動(dòng)作本身就依賴順序。GNN 的價(jià)值就在于它把深度學(xué)習(xí)從網(wǎng)格世界拽進(jìn)了關(guān)系世界讓神經(jīng)網(wǎng)絡(luò)第一次能直接在“誰(shuí)連著誰(shuí)”這種結(jié)構(gòu)上做端到端學(xué)習(xí)。搞懂它等于搞懂了非歐式數(shù)據(jù)建模的底層語(yǔ)言。2. 從歐式到非歐式平移不變性為什么是 CNN 的命門2.1 平移不變性到底在保證什么拿圖像識(shí)別舉例一張照片里貓?jiān)谧笊辖沁€是右下角CNN 都應(yīng)該認(rèn)出它是貓。這種性質(zhì)叫平移不變性。CNN 能天然具備它是因?yàn)榫矸e核在圖像上滑動(dòng)時(shí)無(wú)論滑到哪個(gè)位置權(quán)重共享的機(jī)制都會(huì)對(duì)局部區(qū)域做同樣的特征提取再通過(guò)池化層把空間信息壓縮成全局判斷。換句話說(shuō)CNN 的卷積操作假設(shè)了數(shù)據(jù)存在于一個(gè)規(guī)則的網(wǎng)格上每個(gè)像素的鄰居數(shù)量和排列方式完全一致。這個(gè)假設(shè)在圖像、文本序列、音頻頻譜上成立所以 CNN 在這些任務(wù)上如魚得水。2.2 非歐式數(shù)據(jù)打破了什么假設(shè)非歐式數(shù)據(jù)不具備平移不變性。以社交網(wǎng)絡(luò)為例節(jié)點(diǎn)是用戶邊是關(guān)注關(guān)系。用戶 A 可能有 5 個(gè)鄰居用戶 B 可能有 500 個(gè)鄰居而且鄰居之間沒(méi)有任何固定排列順序。你沒(méi)法定義一個(gè) 3x3 的卷積核去“掃”用戶 A 的鄰居因?yàn)猷従訑?shù)量不固定順序也不固定。更麻煩的是如果把鄰接矩陣的行列順序交換一下圖本身表達(dá)的關(guān)系完全沒(méi)變但矩陣數(shù)值全變了。這意味著任何依賴固定輸入順序的神經(jīng)網(wǎng)絡(luò)都會(huì)因?yàn)楣?jié)點(diǎn)編號(hào)的隨機(jī)性而得到不一致的輸出。這就是為什么直接把 CNN 遷移到圖數(shù)據(jù)上會(huì)失效——不是模型不夠深而是底層假設(shè)根本不兼容。2.3 圖結(jié)構(gòu)如何與神經(jīng)網(wǎng)絡(luò)兼容要讓神經(jīng)網(wǎng)絡(luò)處理圖首先得解決表示問(wèn)題。圖有四個(gè)核心屬性節(jié)點(diǎn)、邊、全局信息和連接性。前三者可以用特征向量表示直接喂給神經(jīng)網(wǎng)絡(luò)沒(méi)問(wèn)題。但連接性——也就是“哪兩個(gè)節(jié)點(diǎn)之間有邊”——用向量很難表達(dá)。最直覺(jué)的方案是鄰接矩陣一個(gè) N×N 的方陣N 是節(jié)點(diǎn)數(shù)。可現(xiàn)實(shí)中的圖往往有百萬(wàn)級(jí)節(jié)點(diǎn)鄰接矩陣會(huì)大到無(wú)法存儲(chǔ)而且絕大多數(shù)位置是零屬于極度稀疏矩陣。更致命的是鄰接矩陣對(duì)節(jié)點(diǎn)順序敏感交換兩行兩列后矩陣變了但圖還是同一個(gè)圖。所以 GNN 的實(shí)際實(shí)現(xiàn)里通常采用鄰接列表只存邊和節(jié)點(diǎn)屬性長(zhǎng)度等于邊數(shù)順序可以任意打亂而不影響語(yǔ)義。這種存儲(chǔ)既高效又對(duì)順序不敏感是后續(xù)所有 GNN 計(jì)算的基礎(chǔ)。3. GNN 的核心機(jī)制聚合、更新、迭代到底在做什么3.1 從節(jié)點(diǎn)隱藏狀態(tài)到消息傳遞GNN 最早由 Marco Gori、Franco Scarselli 等人提出核心思想是把神經(jīng)網(wǎng)絡(luò)方法拓展到圖數(shù)據(jù)計(jì)算領(lǐng)域。假設(shè)我們關(guān)注節(jié)點(diǎn) 5它的隱藏狀態(tài)更新依賴于自身特征和鄰居節(jié)點(diǎn)傳來(lái)的信息。用公式表達(dá)就是節(jié)點(diǎn) 5 的新狀態(tài) 更新函數(shù)節(jié)點(diǎn) 5 的舊狀態(tài)聚合函數(shù)鄰居節(jié)點(diǎn)狀態(tài)。這個(gè)流程可以拆成三步聚合、更新、迭代。聚合是把鄰居的信息收集起來(lái)作為自身特征的補(bǔ)充更新是把聚合結(jié)果和自身舊狀態(tài)融合生成新的隱藏狀態(tài)迭代是重復(fù)這個(gè)過(guò)程多層讓信息在圖中傳播得更遠(yuǎn)。3.2 聚合操作的數(shù)學(xué)本質(zhì)聚合操作的本質(zhì)是加權(quán)求和。假設(shè)節(jié)點(diǎn) A 有三個(gè)鄰居特征分別是 (2,2,2,2,2)、(3,3,3,3,3)、(4,4,4,4,4)權(quán)重分別是 a、b、c。聚合后的鄰居信息 N a*(2,2,2,2,2) b*(3,3,3,3,3) c*(4,4,4,4,4)。這里的權(quán)重可以是固定的比如取平均也可以是學(xué)習(xí)出來(lái)的比如注意力機(jī)制。聚合函數(shù)必須滿足一個(gè)關(guān)鍵性質(zhì)對(duì)鄰居順序不敏感。因?yàn)閳D的節(jié)點(diǎn)沒(méi)有固定順序如果聚合結(jié)果依賴鄰居的排列順序那模型就會(huì)因?yàn)楣?jié)點(diǎn)編號(hào)不同而輸出不同結(jié)果。所以常見的聚合函數(shù)是求和、求平均、求最大值這些操作都天然對(duì)順序不敏感。3.3 更新與迭代信息如何傳播到遠(yuǎn)方聚合得到鄰居信息后更新函數(shù)負(fù)責(zé)把它和節(jié)點(diǎn)自身舊狀態(tài)融合。最簡(jiǎn)單的更新是直接相加或拼接后過(guò)一層全連接。迭代則是把聚合和更新重復(fù)多層。第一層時(shí)每個(gè)節(jié)點(diǎn)只看到直接鄰居第二層時(shí)由于鄰居已經(jīng)聚合了它們的鄰居所以節(jié)點(diǎn)能看到兩跳范圍內(nèi)的信息以此類推K 層 GNN 能讓每個(gè)節(jié)點(diǎn)看到 K 跳鄰居。這類似于 CNN 通過(guò)堆疊卷積層擴(kuò)大感受野但 GNN 的感受野是由圖的連接結(jié)構(gòu)決定的而不是固定的空間范圍。這也帶來(lái)一個(gè)問(wèn)題層數(shù)太深會(huì)導(dǎo)致過(guò)平滑所有節(jié)點(diǎn)的表示趨于一致反而丟失區(qū)分度。常見的做法是控制在 2 到 4 層。import torch import torch.nn as nn class SimpleGNNLayer(nn.Module): def __init__(self, in_dim, out_dim): super().__init__() self.linear nn.Linear(in_dim, out_dim) def forward(self, node_feats, adj_list): # node_feats: [N, in_dim] 節(jié)點(diǎn)特征矩陣 # adj_list: 鄰接列表每個(gè)元素是 (src, dst) 邊對(duì) # 聚合對(duì)每個(gè)節(jié)點(diǎn)收集所有鄰居特征并求平均 agg torch.zeros_like(node_feats) count torch.zeros(node_feats.size(0), 1) for src, dst in adj_list: agg[dst] node_feats[src] # 把源節(jié)點(diǎn)特征加到目標(biāo)節(jié)點(diǎn) count[dst] 1 agg agg / (count 1e-6) # 避免除零 # 更新拼接自身特征和聚合特征過(guò)線性層 out self.linear(torch.cat([node_feats, agg], dim-1)) return torch.relu(out)這段代碼展示了一個(gè)最簡(jiǎn) GNN 層的實(shí)現(xiàn)。node_feats是節(jié)點(diǎn)特征矩陣adj_list是鄰接列表。聚合階段遍歷所有邊把源節(jié)點(diǎn)特征累加到目標(biāo)節(jié)點(diǎn)上再除以鄰居數(shù)量得到平均。更新階段把自身特征和聚合特征拼接后過(guò)線性層最后加 ReLU 激活。關(guān)鍵點(diǎn)在于聚合操作只依賴邊的存在性不依賴邊的順序所以對(duì)節(jié)點(diǎn)編號(hào)不敏感。實(shí)際工程中會(huì)用稀疏矩陣乘法替代循環(huán)但底層邏輯完全一致。4. GNN 變體GCN、GAT、GAE 各自解決了什么問(wèn)題4.1 圖卷積神經(jīng)網(wǎng)絡(luò)從空間域到頻域GCN 是 GNN 最重要的分支分為基于空間域和基于頻域兩種??臻g域 GCN 直接在鄰接矩陣上做卷積思路和上面代碼類似每個(gè)節(jié)點(diǎn)聚合鄰居特征再更新自身。頻域 GCN 則借助圖拉普拉斯變換把圖信號(hào)轉(zhuǎn)換到頻域再做濾波最后轉(zhuǎn)回空間域。頻域方法的數(shù)學(xué)更優(yōu)雅但計(jì)算復(fù)雜度高需要特征分解。實(shí)際應(yīng)用中空間域方法因?yàn)閷?shí)現(xiàn)簡(jiǎn)單、擴(kuò)展性好更受工程界青睞。常見的變體包括 DCNNDiffusion-Convolution Neural Network和 NN4GNeural Networks for Graph。DCNN 用擴(kuò)散過(guò)程定義鄰居聚合NN4G 則是最早的增量式圖神經(jīng)網(wǎng)絡(luò)之一逐層擴(kuò)展感受野。4.2 基于注意力的 GAT讓鄰居權(quán)重自己學(xué)GATGraph Attention Network引入了注意力機(jī)制給不同鄰居分配不同權(quán)重。在普通 GCN 里所有鄰居的權(quán)重是固定的比如平均但現(xiàn)實(shí)中有些鄰居更重要。GAT 通過(guò)一個(gè)注意力函數(shù)計(jì)算節(jié)點(diǎn)對(duì)鄰居的關(guān)注度再歸一化后加權(quán)求和。這樣模型能自動(dòng)學(xué)習(xí)哪些鄰居對(duì)當(dāng)前節(jié)點(diǎn)影響更大。注意力機(jī)制還帶來(lái)一個(gè)好處它天然支持歸納學(xué)習(xí)也就是能處理訓(xùn)練時(shí)沒(méi)見過(guò)的節(jié)點(diǎn)因?yàn)樽⒁饬?quán)重是根據(jù)節(jié)點(diǎn)特征動(dòng)態(tài)計(jì)算的不依賴固定的圖結(jié)構(gòu)。4.3 圖自編碼器 GAE 與 VGAE無(wú)監(jiān)督的圖表示學(xué)習(xí)GAEGraph Autoencoder和 VGAEVariational Graph Autoencoder走的是無(wú)監(jiān)督路線。GAE 用編碼器把圖結(jié)構(gòu)映射到低維嵌入再用解碼器重構(gòu)鄰接矩陣。訓(xùn)練目標(biāo)是讓重構(gòu)誤差最小化這樣學(xué)到的嵌入就能保留圖的拓?fù)湫畔?。VGAE 在 GAE 基礎(chǔ)上引入變分推斷假設(shè)嵌入服從高斯分布通過(guò) KL 散度約束隱空間。兩者常用于鏈路預(yù)測(cè)和節(jié)點(diǎn)聚類因?yàn)椴恍枰獦?biāo)簽就能學(xué)習(xí)節(jié)點(diǎn)表示。MPNNMessage Passing Neural Network則是一個(gè)統(tǒng)一框架把很多 GNN 變體歸納為消息傳遞的不同實(shí)例聚合和更新函數(shù)可以靈活替換。5. 避坑指南GNN 落地時(shí)最容易翻車的五個(gè)地方5.1 鄰接矩陣太大導(dǎo)致內(nèi)存爆炸現(xiàn)象跑一個(gè)中等規(guī)模的社交網(wǎng)絡(luò)圖程序直接 OOM。原因用了稠密鄰接矩陣N100 萬(wàn)時(shí)矩陣有 10^12 個(gè)元素內(nèi)存根本扛不住。解決改用稀疏矩陣存儲(chǔ)或者直接用鄰接列表加稀疏矩陣乘法。PyTorch 的torch.sparse和 DGL、PyG 這些圖神經(jīng)網(wǎng)絡(luò)庫(kù)都原生支持稀疏表示別自己用 numpy 稠密矩陣硬扛。5.2 層數(shù)太深導(dǎo)致過(guò)平滑現(xiàn)象GNN 堆到 8 層以上所有節(jié)點(diǎn)的嵌入幾乎一模一樣分類準(zhǔn)確率暴跌。原因每層聚合都會(huì)讓鄰居特征趨同層數(shù)多了之后整個(gè)圖的節(jié)點(diǎn)表示被“抹平”。解決控制在 2 到 4 層或者引入殘差連接、跳躍連接讓淺層信息能傳到深層。也可以加 DropEdge 隨機(jī)丟邊減緩平滑速度。5.3 節(jié)點(diǎn)順序敏感導(dǎo)致結(jié)果不可復(fù)現(xiàn)現(xiàn)象同樣的圖只是把節(jié)點(diǎn)編號(hào)重新排了一下模型輸出完全不同。原因聚合函數(shù)沒(méi)有做到對(duì)鄰居順序不敏感比如用了 LSTM 聚合而 LSTM 對(duì)輸入順序敏感。解決聚合函數(shù)必須用求和、平均、最大值這類置換不變的操作。如果非要用復(fù)雜聚合至少保證鄰居輸入順序隨機(jī)化并在多個(gè) epoch 上平均結(jié)果。5.4 訓(xùn)練集和測(cè)試集圖結(jié)構(gòu)泄漏現(xiàn)象模型在驗(yàn)證集上表現(xiàn)很好一到真實(shí)場(chǎng)景就崩。原因構(gòu)建訓(xùn)練集和測(cè)試集時(shí)邊被隨機(jī)劃分導(dǎo)致測(cè)試集的邊在訓(xùn)練時(shí)已經(jīng)被模型見過(guò)。解決按時(shí)間劃分邊或者用歸納式劃分確保測(cè)試階段的圖結(jié)構(gòu)在訓(xùn)練時(shí)完全不可見。鏈路預(yù)測(cè)任務(wù)尤其要注意這點(diǎn)。5.5 特征歸一化沒(méi)做導(dǎo)致梯度爆炸現(xiàn)象訓(xùn)練 loss 直接 NaN。原因節(jié)點(diǎn)特征數(shù)值范圍差異大聚合后數(shù)值累積梯度爆炸。解決對(duì)節(jié)點(diǎn)特征做標(biāo)準(zhǔn)化聚合后加 LayerNorm 或 BatchNorm。另外學(xué)習(xí)率別設(shè)太大GNN 對(duì)學(xué)習(xí)率比 CNN 敏感。6. 設(shè)計(jì)取舍GNN 的邊界在哪里什么時(shí)候不該用它GNN 不是萬(wàn)能藥。它的核心優(yōu)勢(shì)在于處理關(guān)系型數(shù)據(jù)但代價(jià)是計(jì)算復(fù)雜度和工程復(fù)雜度都遠(yuǎn)高于傳統(tǒng)神經(jīng)網(wǎng)絡(luò)。如果你的數(shù)據(jù)本身就有固定網(wǎng)格結(jié)構(gòu)比如圖像、時(shí)序信號(hào)CNN 或 RNN 仍然是更高效的選擇。GNN 真正不可替代的場(chǎng)景是那些關(guān)系本身攜帶關(guān)鍵信息的任務(wù)分子屬性預(yù)測(cè)、社交推薦、知識(shí)圖譜推理、交通流量預(yù)測(cè)。這些任務(wù)里節(jié)點(diǎn)之間的連接模式直接決定了輸出忽略關(guān)系就等于丟掉了最重要的特征。另一個(gè)取舍點(diǎn)是聚合函數(shù)的選擇。求和聚合保留鄰居數(shù)量信息適合節(jié)點(diǎn)度重要的場(chǎng)景平均聚合消除度的影響適合度分布不均的圖注意力聚合最靈活但參數(shù)最多小數(shù)據(jù)集上容易過(guò)擬合。我一般會(huì)從平均聚合開始試如果效果不夠再加注意力。層數(shù)也是同理先跑 2 層看 baseline再逐步加深同時(shí)監(jiān)控過(guò)平滑指標(biāo)。驗(yàn)證 GNN 是否真的學(xué)到了東西不能只看準(zhǔn)確率。一個(gè)實(shí)用的方法是把圖結(jié)構(gòu)隨機(jī)打亂如果模型性能大幅下降說(shuō)明它確實(shí)在利用連接信息如果幾乎不變那它可能只是在擬合節(jié)點(diǎn)特征圖結(jié)構(gòu)沒(méi)起作用。另一個(gè)方法是可視化節(jié)點(diǎn)嵌入用 t-SNE 降維后看同類節(jié)點(diǎn)是否聚在一起。如果所有節(jié)點(diǎn)混成一團(tuán)大概率是過(guò)平滑或者聚合函數(shù)有問(wèn)題。從那以后我每次搭 GNN 模型都強(qiáng)制走一遍“打亂圖結(jié)構(gòu)”的對(duì)照實(shí)驗(yàn)確認(rèn)模型真的在學(xué)關(guān)系而不是在偷懶。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取