前阵子对百度AI Studio很感兴趣,业余时间断断续续地学着AI studio的用法,毕竟每天10小时的算力卡很香~
这次看到开了图神经网络的课程,就很激动地报名参加了,因为我自己在研究生阶段的研究方向就是复杂网络分析,虽然跟图打了几年交道,有一定的图基础,但做的科研以贝叶斯图模型为主,对图神经网络了解不多,而且自身的深度学习功力也不深。所以看到课程里安排了很多实战hands-on,觉得很适合我这样的新手入门,既能学GNN,又能学如何炼丹。一周的课跟下来,的确是受益匪浅。
前几个月我也做过一些GNN的调研,从论文、综述、工具等方面做了一些整理。但自学毕竟还是会漏掉很多内容,也不够扎实,这次听百度的小斯妹老师讲课,真是为我好好地梳理了一遍基础知识。(夸夸可爱的小斯妹~)课后我还对着课程的PPT回顾了一遍,官方也给出了每节课的PPT的链接:课程讲义地址
另外,学习图神经网络绝对不可错过的另一个好课是斯坦福的CS224w,授课教师是网络分析领域无人不知无人不晓的Jure大神。(然鹅渣渣如我,还没学完……)
我在调研的时候接触的第一个图神经网络框架是亚马逊的DGL,后来逐步了解了PyG等框架,这些框架的介绍可以参考这篇不错的文章:「紫禁之巅」四大图神经网络框架
PaddlePaddle的PGL框架与上面几个对比来看,也是很有优势的。尤其是并行消息聚合和分布式的存储方式,非常有利于图神经网络的落地应用。
对于PGL的使用,还是更推荐在AI studio上运行,我为了本地运行PaddlePaddle+PGL折腾了好久,CUDA版本、CUDNN版本和PaddlePaddle版本之间的对应还是挺麻烦的……
关于paddlepaddle与cuda/cudnn的适配问题,这里有一个可参考的解决方案。
要用PGL跑GNN,一个最简单的例子就像是这样:
pip install pgl # 安装PGL
git clone --depth=1 https://github.com/PaddlePaddle/PGL #下载PGL代码库
cd PGL/examples/gcn; python train.py --epochs 100 # 切换到gcn的目录,运行train.py在cora数据集上训练
课程在讲解图基础知识之后,又引入了embedding算法的讲解。deepwalk和node2vec都是很经典的node embedding方法了,课上不仅对这两个方法做了介绍,还布置了作业,让我对算法中的随机游走、负采样等关键概念有了进一步的了解。
作业的难度不大,但选取的代码片段都是算法的精髓部分,这一点非常的好。
在正式进入GNN算法后,讲解的重点就放在了GCN和GAT这两个经典又实用的方法上。这里值得一提的是,不论是课上的讲解,还是课后的作业,代码的注释都非常的用心,PGL团队真的很棒。
依据作业提供的示例,我稍加修改的GCN的核心代码如下所示:
import paddle.fluid as fluid
def gcn_layer(gw, feature, hidden_size, activation, name, norm=None):
# send函数
def send_func(src_feat, dst_feat, edge_feat):
'''
src_feat 为源节点特征
src_feat
{
"h": Tensor形状为 [边数目, hidden_size]
}
dst_feat 为目标节点特征
dst_feat
{
"h": Tensor形状为 [边数目, hidden_size]
}
这里没有边特征,所以 edge_feat 为 None
'''
feat = src_feat["h"]
# recv函数
def recv_func(msg):
'''
接受到的消息是一个变长Tensor,在Paddle里被称为LodTensor
例如:
msg = [
[1, 2], # 节点0 接受的特征
[1], # 节点1 接受的特征
[2, 3, 4] # 节点2 接受的特征
]
对于不定长Tensor,我们可以使用一系列的sequence操作。例如sequence_pool
例如: 对上述msg进行sequence_pool求和的操作, 我们会得到
msg = [
[3], # 节点0 接受的特征
[1], # 节点1 接受的特征
[9] # 节点2 接受的特征
]
'''
fluid.layers.sequence_pool(msg, "sum")
# 消息传递机制执行过程
msg = gw.send(send_func, nfeat_list=[("h", feature)])
output = gw.recv(msg, recv_func)
# 通过以activation为激活函数的全连接输出层
output = fluid.layers.fc(output,
size=hidden_size,
bias_attr=False,
act=activation,
name=name)
return output
GraphSAGE (SAmple & aggreGatE),是对节点的邻居进行了采样后再做聚合的算法。之前我对该方法没怎么了解,只粗略看过PinSAGE的论文。(插播一下PinSAGE:这是第一个将图卷积(GCN)在工业级超大规模数据集上实现落地应用(pinterest内容推荐)的图算法,论文链接)
在经过课上讲解后,我终于体会到了SAGE的优势所在。作业中还给出了GraphSAGE代码的梳理,分别实现了关键的采样和聚合函数。
上课还要打比赛,PGL团队的课程设计的确很有心了。我跟着课上的讲解复现了baseline,后来尝试调整了一些配置,用APPNP模型跑,由于时间有限,ACC刚够到0.7。
这个比赛在课程结束后还继续开放着:常规赛:论文引用网络节点分类,有兴趣可以继续刷。
榜一大佬都刷到0.76了,膜拜……后浪可畏
新冠疫苗项目拔高实战
这是一个很有意思也很有意义的项目,目的是找到最稳定的疫苗化学分子结构,本质上是基于图结构的多分类任务。听完课,目前我对该项目的理解还是很浅,虽然跟着老师跑了一遍代码,但各个模块之间的关联还不太明白,最后的输出结果也还没时间做更多的分析。但这个项目我后面一定会好好研究一下,因为我将来可能会做一做涉及到化学分子式相关的任务。
上课的这一周过的很充实,听听课做做作业,时间好像一下子就过去了。在脑海里回顾一下各种算法的话,有了不少能完全get的点,但也有很多还需学习的点。很感谢百度AI Studio能开这样一次课,让GNN小白从自己瞎摸索的状态快速找到了学习和成长的感觉,好像终于是推开新世界的大门了(
这篇文章主要是我对课程总体的感受和实战项目的总结,并没有太多涉及GNN的知识概念。而我自己平时习惯用某雀做日常笔记,记录每天学到的零零散散的知识点,也没形成个系统体系。趁着这次课程带给我的满满收获,后面我争取挤时间把完整的GNN学习笔记整理出来。
最后,因为我近期在做知识图谱,对GNN与NLP、知识图谱的结合也是非常感兴趣,接下来我应该会往这个方向深入探索,希望能有所得。给自己打个气~