#Deep Graph

Pytorch Geometric 系列将结合 pytorch geometric 类库,从原理结合实践来讲解深度图神经网络。和前几期一样,这一系列所有环境已经为大家封装成了 docker image。预制的 image 中既包含了 pytorch 1.8 和对应的 geometric,networkx,Jubyter notebook 还有画图涉及到的 matplotlib 和 hvplot 类库。除此之外,也包含了预下载的 geometric dateset 和所用到的代码。方便大家一键开始 coding。

获取预制 Docker Image

获取docker image 环境的方式,小伙伴们可以通过关注 MyEncyclopedia 公众号并在公众号对话框中回复

docker-geometric 后获得

wechat_docker

关于具体使用我制作的 docker image 这个主题,大家可以再公众号或者同名 B站账号,找到 docker 封装工程依赖 一集, 其中包括如下高级用法

  • 在 VS Code 中运行 Jupyter notebook
  • Remote X Window 主机显示渲染图片
  • docker container 中启动 Jupyter notebook 服务器
  • 共享文件保存文件改动
  • 添加类库后保存镜像改动
bili-docker-adv

如果觉得下载镜像麻烦的小伙伴们,也可以自己准备对应的 python package,再拷贝下方链接的代码直接运行。

https://mydoc.myencyclopedia.top/pub/code/cora-plot

这个系列涉及到的 python package 包括 - torch-geometric

  • networkx

  • hvplot

  • livelossplot

启动 Jupyter Notebook

当预制的 docker image 下载并装载完毕后,通过下面命令来启动 container 内置的 Jupyter notebook 服务器,这样可以使得主机种的浏览器访问到 container 中的服务器。

1
docker run -p 8888:8888 -it env-conda-x jupyter notebook --allow-root --ip 0.0.0.0

内置 Cora 数据集

下一步,我们会通过 geometric 类库加载 cora 数据集。这一步通常来说需要从网上下载,但是预制的 docker image 已经为大家下载好了 planetoid 图数据集。Planetoid 包含了 Cora,Pubmed 和 Citeseer。

因此,加载数据集这一步执行非常快

1
2
3
4
5
6
7
8
9
10
11
12
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F

from torch_geometric.data import Data
from torch_geometric.nn import GATConv
from torch_geometric.datasets import Planetoid
import torch_geometric.transforms as T

name_data = 'Cora'
dataset = Planetoid(root='./data/', name=name_data)

然后我们将 cora 转换成 networkx 格式。networkx 是 python 中一个比较流行的图类库。我们在后面 visualization 中也会利用networkx 的功能。

Cora 有 7 种节点类型,我们将每种节点类型赋予不同颜色,有助于更好 visualization。

1
2
3
4
5
6
7
8
9
10
from torch_geometric.utils import to_networkx
cora = to_networkx(dataset.data)

print(cora.is_directed())

node_classes = dataset.data.y.data.numpy()
print(node_classes)

node_color = ["red","blue","green","yellow","peru","violet","cyan"]
node_label = np.array(list(cora.nodes))

接着,调用 networkx 的 spring_layout 计算每个节点的弹簧布局下的位置,这一步执行会比较耗时。

1
2
3
4
import matplotlib.pyplot as plt
import networkx as nx

pos = nx.layout.spring_layout(cora)

我们首先来看一下 matplotlib 的渲染效果。

1
2
3
4
5
6
7
8
9
10
11
plt.figure(figsize=(16,12))

for i in np.arange(len(np.unique(node_classes))):
node_list = node_label[node_classes == i]
nx.draw_networkx_nodes(cora, pos, nodelist=list(node_list),
node_size=50,
node_color=node_color[i],
alpha=0.8)

nx.draw_networkx_edges(cora, pos,width=1,edge_color="black")
plt.show()

因为 matplotlib 只能画出一张静态图片, 无法做 interaction,也无法动态缩放。因此渲染效果不是特别好,尤其是对于 cora 这种数据量比较大的 graph 尤为显著。

我们看到图片种尽管有七种颜色的节点,但是当中存在的这块密集的点,我们很难看出节点和节点之间的关系。 cora_networkx

我们换一个类库 hvplot,它的渲染和交换效果如下。 hvplot

代码和 matplotlib 大致一致。注意渲染的时候 hvplot 需要将多个图片数据以乘法形式返回,借助 reduce 函数我们将 7 种节点的图相乘,再乘以描绘边的图,呈现出叠加的完整图片。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import hvplot.networkx as hvnx
options = {
'width': 800,
'height': 1000
}

plt_nodes = []
for i in np.arange(len(np.unique(node_classes))):
nodelist = node_label[node_classes == i]
plt = hvnx.draw_networkx_nodes(cora, pos, nodelist=list(nodelist), node_color=node_color[i], **options)
plt_nodes.append(plt)

plt_edges = hvnx.draw_networkx_edges(cora, pos, arrowstyle='->', edge_width=2, colorbar=True, **options)

import functools
import operator
plt_edges * functools.reduce(operator.mul, plt_nodes)

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×