####好好好好好#####GraphSAGE:我尋思GCN也沒我牛逼

 

衆所周知,2017年ICLR出產的GCN現在是多麼地熱門,彷彿自己就是圖神經網絡的名片。然而,在GCN的風頭中,很多人忽略了GCN本身的巨大侷限——Transductive Learning——沒法快速表示新節點,這限制了它在生產環境中應用。同年NIPS來了一篇使用Inductive Learning的GraphSAGE,解決了這個問題。今天,讓我們來一起琢磨琢磨這個GraphSAGE是個什麼玩意兒。

一、回顧GCN及其問題

對GCN不熟悉的盆友,可以看看我的上一篇文章:
蟈蟈:何時能懂你的心——圖卷積神經網絡(GCN)

  • GCN的基本思想: 把一個節點在圖中的高緯度鄰接信息降維到一個低維的向量表示。
  • GCN的優點: 可以捕捉graph的全局信息,從而很好地表示node的特徵。
  • GCN的缺點: Transductive learning的方式,需要把所有節點都參與訓練才能得到node embedding,無法快速得到新node的embedding。

得到新節點的表示的難處:

要想得到新節點的表示,需要讓新的graph或者subgraph去和已經優化好的node embedding去“對齊”。然而每個節點的表示都是受到其他節點的影響,因此添加一個節點,意味着許許多多與之相關的節點的表示都應該調整。這會帶來極大的計算開銷,即使增加幾個節點,也要完全重新訓練所有的節點,這可太費勁了。

因此我們需要換一種思路:

既然新增的節點,一定會改變原有節點的表示,那麼我們幹嘛一定要得到每個節點的一個固定的表示呢?我們何不直接學習一種節點的表示方法。這樣不管graph怎麼改變,都可以很容易地得到新的表示。


二、GraphSAGE是怎麼做的

針對這種問題,GraphSAGE模型提出了一種算法框架,可以很方便地得到新node的表示。

基本思想:

去學習一個節點的信息是怎麼通過其鄰居節點的特徵聚合而來的。 學習到了這樣的“聚合函數”,而我們本身就已知各個節點的特徵和鄰居關係,我們就可以很方便地得到一個新節點的表示了。

GCN等transductive的方法,學到的是每個節點的一個唯一確定的embedding; 而GraphSAGE方法學到的node embedding,是根據node的鄰居關係的變化而變化的,也就是說,即使是舊的node,如果建立了一些新的link,那麼其對應的embedding也會變化,而且也很方便地學到。

1. Embedding generation

即GraphSAGE的前向傳播算法。

上面的算法的意思是:

假設我們要聚合K次,則需要有K個聚合函數(aggregator),可以認爲是N層。 每一次聚合,都是把上一層得到的各個node的特徵聚合一次,在假設該node自己在上一層的特徵,得到該層的特徵。如此反覆聚合K次,得到該node最後的特徵。 最下面一層的node特徵就是輸入的node features。

用作者的圖來表示就是這樣的:(雖然酷炫,但有點迷糊)

 

我來畫一個圖說明:(雖然樸素,但是明明白白)

這裏需要注意的是,每一層的node的表示都是由上一層生成的,跟本層的其他節點無關。

2.GraphSAGE的參數學習

在上面的過程中,我們需要學習各個聚合函數的參數,因此需要設計一個損失函數。 損失函數是設計是根據目標任務來的,可以是無監督的,也可以是有監督的。

對於無監督學習,我們設計的損失函數應該讓臨近的節點的擁有相似的表示,反之應該表示大不相同。所以損失函數是這樣的:

 

 

也沒什麼好解釋的。 對於有監督學習,可以直接使用cross-entropy。

3. 聚合函數的選擇

這裏作者提供了三種方式:

  • Mean aggregator
    直接取鄰居節點的平均,公式過於直白故不展示。
  • GCN aggregator: 這個跟mean aggregator十分類似,但有細微的不同,公式如下:

把這個公式,去替換前面給的Algorithm1中的第4,5行。 自己體會一下哪裏不同。想不明白的留言。實際上,這個幾乎就是GCN中的聚合方式,想一想爲啥。

  • LSTM aggregator
    使用LSTM來encode鄰居的特徵。 這裏忽略掉鄰居之間的順序,即隨機打亂,輸入到LSTM中。這裏突然冒出來一個LSTM我也是蠻驚訝,作者的想法是LSTM的表示能力比較強。但是這裏既然都沒有序列信息,那我不知道LSTM的優勢在何處。
  • Pooling aggregator
    把各個鄰居節點單獨經過一個MLP得到一個向量,最後把所有鄰居的向量做一個element-wise的max-pooling或者什麼其他的pooling。公式如下:

 

這就是GraphSAGE的主要內容了,其實思路還是十分簡潔的,理解起來也比GCN容易多了。

 

鄰居的定義:

前面一直都沒討論一個點,那就是如何選擇一個節點的鄰居以及多遠的鄰居。

這裏作者的做法是設置一個定值,每次選擇鄰居的時候就是從周圍的直接鄰居(一階鄰居)中均勻地採樣固定個數個鄰居。

那我就有一個疑問了?每次都只是從其一階鄰居聚合信息,爲何作者說:

隨着迭代,可以聚合越來越遠距離的信息呢?

後來我想了想,發現確實是這樣的。雖然在聚合時僅僅聚合了一個節點鄰居的信息,但該節點的鄰居,也聚合了其鄰居的信息,這樣,在下一次聚合時,該節點就會接收到其鄰居的鄰居的信息,也就是聚合到了二階鄰居的信息了。

還是拿出我的看家本領——用圖說話:

 

 

我的天,這個圖簡直畫的太好了吧。

圖中(爲了圖的簡潔,這裏假設只隨機聚合兩個鄰居)可以看出,層與層之間,確實都是一階鄰居的信息在聚合。在圖中的“1層”,節點v聚合了“0層”的兩個鄰居的信息,v的鄰居u也是聚合了“0層”的兩個鄰居的信息。到了“2層”,可以看到節點v通過“1層”的節點u,擴展到了“0層”的二階鄰居節點。因此,在聚合時,聚合K次,就可以擴展到K階鄰居。

在GraphSAGE的實踐中,作者發現,K不必取很大的值,當K=2時,效果就灰常好了,也就是隻用擴展到2階鄰居即可。至於鄰居的個數,文中提到S1×S2<=500,即兩次擴展的鄰居數之際小於500,大約每次只需要擴展20來個鄰居即可。這也是合情合理,例如在現實生活中,對你影響最大就是親朋好友,這些屬於一階鄰居,然後可能你偶爾從他們口中聽說一些他們的同事、朋友的一些故事,這些會對你產生一定的影響,這些人就屬於二階鄰居。但是到了三階,可能基本對你不會產生什麼影響了,例如你聽你同學說他同學聽說她同學的什麼事蹟,是不是很繞口,繞口就對了,因爲你基本不會聽到這樣的故事,你所接觸到的、聽到的、看到的,基本都在“二階”的範圍之內


三、效果與性能分析:

這個部分是最沒意思的,畢竟誰發paper不是說自己的模型最牛逼?

 

這個部分我不想多說,三個圖都很好理解。


(彩蛋)思考 & GCN的反芻:

在看完GraphSAGE之後,我又回頭把GCN思考了一遍。從直觀上去看,我一開始覺得GraphSAGE和GCN截然不同,後來發現只是論文作者的介紹的角度不同,實際上兩者的本質上沒有很大差別。或者說,懂了GraphSAGE的原理之後,再去看GCN,會發GCN沒那麼難以理解了。

來人啊,GCN公式搬上來:

 

 

額,,,這個是版本的公式,還是上版本的吧:

 

 

中間這個A帽子,就是上面醜公式中的那一大串東西。對A帽子的理解,其實它就是鄰接矩陣A做的一個歸一化下面爲了表達的方便,我直接當做鄰接矩陣來分析吧!H是節點的每一層的特徵矩陣。

這個公式的內部,畫成矩陣相乘的形式是這樣的:

 

其中,A是n×n維,H是n×m維,W則是m×u維。n就是節點個數,m則是節點特徵的維度,u就是神經網絡層的單元數。

我們先看看A乘以H是個啥意思:

 

 

A帽子矩陣的第i行和H矩陣的第j列對應元素相乘在求和就得到Q矩陣的(i,j)個元素。 這都是最基本的線性代數了,但我們不妨再仔細看看我圖中高亮的那幾個向量的內部:

 

 

這個圖說的明明白白,所以我們發現,GCN的這一步,跟GraphSAGE是一樣的思想,都是把鄰居的特徵做一個聚合(aggregation)

 

所以,都是一個詞——AggregateAggregate就完事兒了

這也是爲什麼GraphSAGE的作者說,他們的mean-aggregator跟GCN十分類似。在GCN中,是直接把鄰居的特徵進行求和,而實際不是A跟H相乘,而是A帽子,A帽子是歸一化的A,所以實際上我畫的圖中的鄰居關係向量不應該是0,1構成的序列,而是歸一化之後的結果,所以跟H的向量相乘之後,相當於是“求平均”。GraphSAGE進一步拓展了“聚合”的方法,提出了LSTM、Pooling等聚合方式,不是簡單地求平均,而是更加複雜的組合方式,所以有一些效果的提升也是在情理之內的。

至於說爲什麼GCN是transductive,爲啥要把所有節點放在一起訓練? 我感覺不一定要把所有節點放在一起訓練,一個個節點放進去訓練也是可以的。無非是你如果想得到所有節點的embedding,那麼GCN可以讓你一口氣把整個graph丟進去,直接得到embedding,還可以直接進行節點分類、邊的預測等任務。

其實,通過GraphSAGE得到的節點的embedding,在增加了新的節點之後,舊的節點也需要更新,這個是無法避免的,因爲,新增加點意味着環境變了,那之前的節點的表示自然也應該有所調整。只不過,對於老節點,可能新增一個節點對其影響微乎其微,所以可以暫且使用原來的embedding,但如果新增了很多,極大地改變的原有的graph結構,那麼就只能全部更新一次了。從這個角度去想的話,似乎GraphSAGE也不是什麼“神仙”方法,只不過生成新節點embedding的過程,實施起來相比於GCN更加靈活方便了。我們學習到了各種的聚合函數之後,其實就不用去計算所有節點的embedding,而是我們需要去考察哪些節點,就現場去計算,這種方法的遷移能力也很強,在一個graph上學得了節點的聚合方法,到另一個新的類似的graph上就可以直接使用了。

好啦,關於GraphSAGE的介紹就到這裏,我個人在讀了這篇文章後還是收穫頗豐的,尤其是和GCN對比的過程,讓我對二者都有了更加深刻的認識。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章