这个系列的所有代码我都会放在git上,欢迎造访
GNN考虑的事当前的点和周围点之间的关系
邻接矩阵是对称的稀疏矩阵,表示图中各个点之间的关系
图神经网络的输入是每个节点的特征和邻接矩阵
文本数据可以用图的形式表示吗?
文本数据也可以表示图的形式,邻接矩阵表示连接关系
信息传递神经网络:每个点的特征如何更新??
——考虑他们的邻居,更新的方式可以自己设置:最大,最小,平均,求和等
GNN可以有多层,图的结构不发生改变,即当前点所连接的点不发生改变(邻接矩阵不发生变化)【卷积中存在感受野的概念,在GNN中同样存在,GNN的感受野也随着层数的增大变大】
GNN输出的特征可以干什么?
利用图结构得到特征,最终做什么自定义!
为什么CV和NLP中不用GNN?
GNN输入格式比较随意,是不规则的数据结构, 主要用于输入数据不规则的时候
图卷积和卷积完全不同
它实现了各种GNN的方法
注意:安装过程中不要pip install,会失败!根据自己的device和python版本去下载scatter,pattern等四个依赖,先安装他们然后再pip install torch_geometric==2.0
这里记得是2.0版本否则会出现 TypeError: Expected ‘Iterator‘ as the return annotation for __iter__
of SMILESParser, but found ty
献上github地址:这里
下面是一个demo
这里使用的是和这个package提供的数据,具体参考:club
from torch_geometric.datasets import KarateClub
dataset = KarateClub()
print(f'Dataset: {dataset}:')
print('======================')
print(f'Number of graphs: {len(dataset)}')
print(f'Number of features: {dataset.num_features}')
print(f'Number of classes: {dataset.num_classes}')
data = dataset[0] # Get the first graph object.
在torch_geometric中图用Data的格式,Data的对象:可以在文档中详细了解
其中的属性
from torch_geometric.utils import to_networkx
G = to_networkx(data, to_undirected=True)
visualize_graph(G, color=data.y)
import torch
from torch.nn import Linear
from torch_geometric.nn import GCNConv
class GCN(torch.nn.Module):
def __init__(self):
super().__init__()
torch.manual_seed(1234)
self.conv1 = GCNConv(dataset.num_features, 4) # 只需定义好输入特征和输出特征即可
self.conv2 = GCNConv(4, 4)
self.conv3 = GCNConv(4, 2)
self.classifier = Linear(2, dataset.num_classes)
def forward(self, x, edge_index):
h = self.conv1(x, edge_index) # 输入特征与邻接矩阵(注意格式,上面那种)
h = h.tanh()
h = self.conv2(h, edge_index)
h = h.tanh()
h = self.conv3(h, edge_index)
h = h.tanh()
# 分类层
out = self.classifier(h)
return out, h
model = GCN()
print(model)
_, h = model(data.x, data.edge_index)
print(f'Embedding shape: {list(h.shape)}')# 输出最后分类前的中间特征shape
visualize_embedding(h, color=data.y)
import time
model = GCN()
criterion = torch.nn.CrossEntropyLoss() # Define loss criterion.
optimizer = torch.optim.Adam(model.parameters(), lr=0.01) # Define optimizer.
def train(data):
optimizer.zero_grad()
out, h = model(data.x, data.edge_index) #h是两维向量,主要是为了画图方便
loss = criterion(out[data.train_mask], data.y[data.train_mask]) # semi-supervised
loss.backward()
optimizer.step()
return loss, h
for epoch in range(401):
loss, h = train(data)
if epoch % 10 == 0:
visualize_embedding(h, color=data.y, epoch=epoch, loss=loss)
time.sleep(0.3)
然后就可以看到一系列图,看点的变化情况了