最近在参加飞桨图神经网络7日打卡训练营,这是第三次课的内容。下面记录以下自己的学习心得。这些知识比较契合我的研究方向,这个训练营资源很多,对自己很有帮助,祝自己顺利!祝大家身体健康,开开心心!
一、GCN
GCN是经典一个经典的图卷积网络模型。
推广形式的GCN公式:
H
(
l
+
1
)
=
σ
(
D
^
−
1
2
A
^
D
^
−
1
2
H
(
l
)
W
(
l
)
)
H^{(l+1)}=\sigma(\hat {D}^{-\frac{1}{2}}\hat{A}\hat {D}^{-\frac{1}{2}}H^{(l)}W^{(l)})
H(l+1)=σ(D^−21A^D^−21H(l)W(l))
σ
\sigma
σ是激活函数,
A
^
\hat{A}
A^是加了加了自环的邻接矩阵,
A
^
=
A
+
I
N
\hat{A}=A+I_{N}
A^=A+IN,
D
^
\hat{D}
D^是
A
^
\hat{A}
A^对应的邻接矩阵。
二、GAT
利用注意力机制把注意力分配到目标节点的邻居节点集上。下图左边为目标节点特征的线性变换,右边为目标节点特征的线性变换,通过
e
i
j
=
a
(
W
h
→
i
,
W
h
→
j
)
e_{ij}=a(W\overrightarrow{h}_{i},W\overrightarrow{h}_{j})
eij=a(Whi,Whj)计算注意力系数,然后用softmax函数归一化:
α
i
j
=
s
o
f
t
m
a
x
j
(
e
i
j
)
=
e
x
p
(
e
i
j
)
∑
k
∈
N
i
e
x
p
(
e
i
k
)
\alpha_{ij}=softmax_{j}(e_{ij})=\frac{exp(e_{ij})}{\sum_{k\in N_{i}}exp(e_{ik})}
αij=softmaxj(eij)=∑k∈Niexp(eik)exp(eij)
从每一头聚合特征,得到
h
→
i
′
\overrightarrow{h}_{i}^{'}
hi′
代码实现
利用pgl实现GAT算法
下面我用pytorch来实现一下
// pytorh 实现GAT
import numpy as np
from torch_geometric.nn import GATConv
import torch_geometric.nn as tnn
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from torch_geometric.datasets import Planetoid
dataset = Planetoid(root = './tmp/Cora',name = 'Cora')
learning_rate = 0.01
class Net(nn.Module):
def __init__(self):
super(Net,self).__init__()
self.gat1 = GATConv(dataset.num_features,64,dropout = 0.2)
self.gat2 = GATConv(64,dataset.num_classes,dropout = 0.2)
self.dropout = nn.Dropout(p = 0.2)
def forward(self,input):
x,edge_index = input.x , input.edge_index
x = self.dropout(x)
x = self.gat1(x,edge_index)
x = self.dropout(x)
x = self.gat2(x,edge_index)
out = F.softmax(x,dim = 1)
return out
model = Net()
optimizer = optim.Adam(model.parameters(),lr = learning_rate,weight_decay = 5e-4)
epochs = 1000
data = dataset[0]
model.train()
for i in range(epochs):
optimizer.zero_grad()
logits = model(data)
loss = F.nll_loss(logits[data.train_mask],data.y[data.train_mask])
_,logit = logits.max(dim = 1)
score = float(logit[data.train_mask].eq(data.y[data.train_mask]).sum().item())
print('epoch:{},train Acc:{:.4f},loss:{:.4f}'.format(i,score/data.train_mask.sum().item(),loss.item()))
loss.backward()
optimizer.step()
model.eval()
_,pred=model(data).max(dim=1)
correct=float(pred[data.test_mask].eq(data.y[data.test_mask]).sum().item())
acc=correct/data.test_mask.sum().item()
print('Accuracy:{:.4f}'.format(acc))
torch_geometric已经把gat封装成了GATConv类,不用自己过多编写什么。同样的pgl里面也封装了很多经典的算法模型,如gcn,gat,gin等,确实强大,可以帮助自己快速复现一些算法,里面有很多优化,速度也快,以后要多加琢磨这个库。