【PyG進階學習】一:AGNN算法

一:簡介

算法全名:Attention-based Graph Neural Network for Semi-supervised Learning
論文鏈接:https://arxiv.org/abs/1803.03735

如題目所說,本論文提出的模型是針對於半監督學習領域的一種算法,是一種基於注意力機制的圖神經網絡。該算法簡稱爲AGNN,在提出AGNN之前,作者介紹了三個算法的大致思路,分別是GNNGCNGLN,本文經過個人閱讀,作者其大致方向可以概括爲:

原本的圖神經網絡也好,圖卷積神經網絡也好,本質就是兩種網絡的組合方式,不斷地Stacking,這兩種網絡分別爲聚合層和全連接層,論文稱之爲 propagation layersingle layer perceptron,翻譯過來就是傳播層和單層感知機,後文按照聚合層和全連接層的表達習慣進行講解。簡單的說,聚合層就是節點與鄰域節點的特徵融合,是屬於節點級別的處理方式,而全連接層是每個節點單獨地將內部特徵重新映射到一個新維度的特徵向量上,是屬於節點內部級別的處理方式。經過作者的實驗和分析,圖神經網絡關鍵在於聚合層,使其達到了令人矚目的效果,而這個全連接層並無太大意義,故將這個結構去除,在很大程度上降低了模型的參數量,而本身半監督學習問題大部分都是標註樣本不足的,更少的參數量在小規模數據問題上可以更有效地收斂。

下面分別給出GNNGCNGLN的簡要流程:
1.GNN
首先GNN公式分兩步:
在這裏插入圖片描述
在這裏插入圖片描述
H表示第t層的節點的特徵矩陣,也可以叫做隱藏層狀態,P表示的是一種聚合方式,比如求和,無非用的是矩陣形式。第一個公式表示聚合層,對H進行左乘可以理解爲:

每一個節點的聚合方式表現爲P矩陣的一個行向量,對所有的節點特徵(H)進行加權聚合,每一個節點的加權向量不一樣,而且對節點特徵聚合時,是逐特徵聚合,特徵與特徵之間不會混合。

第二個公式爲全連接層,對H進行右乘,節點之間不會干擾,但是單個節點的特徵會混合,而且權重W是共享的,這裏作者解釋了下,就是說之所以共享相同的權重矩陣W,是因爲即可以降低模型複雜度而且保持Graph的不變性(invariance property),此處我用一個例子來具體說一下,對於圖中的兩個局部區域,假設其圖的拓撲結構是類似的,對於聚合層而言,這兩個區域的聚合情況也是類似的,所以爲了保證這兩個局域在算法中具有類似的預測情景,就要保持全連接層的一致,所以採用共享權重的方式對每一個節點加權。
2.GCN
GCN是圖卷積神經網絡,堆疊了兩層,每一層包含一組聚合層和全連接層,如下公式:
在這裏插入圖片描述
GNN的區別主要在於矩陣P的構造,詳情見GCN論文(以後的文章中我會涉及到這個GCN的具體機制)。
3.GLN
GLN稱爲Graph Linear Network,關鍵在於Linear,公式如下:
在這裏插入圖片描述
GCN基礎上,移除非線性部分也就是Relu函數,然後化簡到一個公式內。根據作者實驗,GLN性能不亞於GNN算法。於是作者在GLN基礎上,依然是移除全連接層,並且將聚合層修改爲注意力機制。
4.AGNN
上述模型的聚合方式都是靜態而且無自適應的方式,就比如說GCN中的聚合方式,其聚合所用矩陣P是通過鄰接矩陣和度矩陣構造所得,而其GCN本意是在加法聚合的方式上增加了一個拉普拉斯正則係數,該係數是有一條邊上雙方節點的鄰域大小決定的,這對於固定結構的圖而言,是一種固定的聚合邏輯。下面直接給出AGNN公式再分析:
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

在這裏插入圖片描述
在這裏插入圖片描述
上面給出了四個公式,第一個公式爲AGNN第一層,給所有節點的原始特徵信息先做一個預處理,乘以一個權重矩陣W0,第二個公式表示了中間層的傳播方式,不同於GCN的兩層結構,AGNN此處可以設置爲L層,而且在中間層不進行全連接過程。第三個公式表示爲矩陣P的構造方式,其實矩陣P可以看做是近似於鄰接矩陣A的格式,邊不存在的地方,元素爲0,對於存在邊的元素,鄰接矩陣中是1,P矩陣的非0元素是一個權重值,這個權重是通過一條邊上的兩個節點的特徵向量的餘弦相似度計算後乘以一個自適應係數β\beta後得到的,每一層聚合層中共用一個β\beta,最後通過softmax使權重總和爲1。最後一個公式在最後一層輸出前再進行一次全連接。 矩陣P元素如下:
在這裏插入圖片描述

在這裏插入圖片描述
由此AGNN的訓練參數僅僅只有兩個權重矩陣W0W1,以及Lβ\beta
5.實驗結果
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
前兩個圖是在數據預處理方式不同的情況下的效果對比,第三個圖是AGNN效果與層數的關係,可以看到層數加深後,效果有一定提高。

二:源碼分析

用的是Pytorch-Geometric官方庫中實現的代碼:

代碼鏈接:https://github.com/rusty1s/pytorch_geometric/blob/master/torch_geometric/nn/conv/agnn_conv.py

1.forward過程

def forward(self, x, edge_index):
    """"""
    edge_index, _ = remove_self_loops(edge_index)
    edge_index, _ = add_self_loops(edge_index,
                                   num_nodes=x.size(self.node_dim))

    x_norm = F.normalize(x, p=2, dim=-1)

    return self.propagate(edge_index, x=x, x_norm=x_norm,
                          num_nodes=x.size(self.node_dim))

首先清理下個別的自環,算是數據清洗吧,然後全部增加自環;計算當前矩陣X特徵向量的正則化結果(用於後面求餘弦相似度);調用propagate函數開始信息聚合。
2.message過程

def message(self, edge_index_i, x_j, x_norm_i, x_norm_j, num_nodes):
     # Compute attention coefficients.
     beta = self.beta if self.requires_grad else self._buffers['beta']
     alpha = beta * (x_norm_i * x_norm_j).sum(dim=-1)
     alpha = softmax(alpha, edge_index_i, num_nodes)

     return x_j * alpha.view(-1, 1)

首先定義一個訓練參數β\beta,代碼第二行計算餘弦相似度並且乘以β\beta,然後求和(參考AGNN五條公式第四條),最後進行softmax

三:實際應用

代碼鏈接:https://github.com/rusty1s/pytorch_geometric/blob/master/examples/agnn.py

def __init__(self):
    super(Net, self).__init__()
    self.lin1 = torch.nn.Linear(dataset.num_features, 16)
    self.prop1 = AGNNConv(requires_grad=False)
    self.prop2 = AGNNConv(requires_grad=True)
    self.lin2 = torch.nn.Linear(16, dataset.num_classes)

def forward(self):
    x = F.dropout(data.x, training=self.training)
    x = F.relu(self.lin1(x))
    x = self.prop1(x, data.edge_index)
    x = self.prop2(x, data.edge_index)
    x = F.dropout(x, training=self.training)
    x = self.lin2(x)
    return F.log_softmax(x, dim=1)

首先第一個是全連接層即W0配合Relu,然後兩層聚合層即L=2,最後再加一個全連接層W1,通過softmax獲得結果。後面訓練的時候,損失函數爲F.nll_loss,事實上,在Pytorch中,交叉熵CrossEntropyLosslog_softmax+nll_loss效果是一樣的(這個以後再說)。

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