开启生长之旅!这是我参与「日新方案 12 月更文挑战」的第3天
本文首发于CSDN。
诸神沉默不语-个人CSDN博文目录 cs224w(图机器学习)2021冬天课程学习笔记集合
@[toc]
YouTube 视频观看地址1 视频观看地址2 视频观看地址3
本章主要内容: 本章继续上一章1内容,讲design space剩下的两部分:图增强,怎么练习一个GNN模型(GNN练习全流程)。
在图增强方面: 首先介绍图增强的原因和分类。 然后别离介绍: graph feature augmentation的办法:使用常数特征、独热编码、图结构信息 graph structure augmentation的办法: 对稀少图:添加虚拟边或虚拟节点 对稠密图:节点街坊抽样
接下来讲GNN模型练习的学习方针。 首先介绍不同粒度使命下的prediction head(将节点嵌入转化为终究猜测向量):节点等级的使命能够直接进行线性转化。链接等级的使命能够将节点对的嵌入进行concatenation或点积后进行线性转化。图等级的使命是将图中一切节点嵌入作池化操作,能够通过hierarchical global pooling办法来进行优化(实际使用:DiffPool)。 接下来介绍了猜测值和标签的问题:有监督/无监督学习状况下的标签来源。 然后介绍丢失函数:分类常用穿插熵2,回归使命常用MSE(L2 loss)。 接下来介绍评价方针:回归使命常用RMSE和MAE,分类使命常用accuracy和ROC AUC。 最后讲了设置GNN猜测使命(将图数据拆分为练习/验证/测验集)的办法,分为transductive和inductive两种。
1. Graph Augmentation for GNNs
这一部分在 Lecture 71 的slides中写过,但是在 Lecture 8(本章)课程中讲的,所以我笔记也放在这一部分来做。
- 回忆一遍在 Lecture 71 第一节中讲过的GNN图增强部分:
- 为什么要进行图增强?
咱们在之前的学习进程中都假设原始数据和使用于GNN的核算图一致,但许多状况下原始数据或许不适宜于GNN:
- 特征层面:输入图或许短少特征(也或许是特征很难编码)→特征增强
- 结构层面:
- 图或许过度稀少→导致message passing功率低(边不可嘛)
- 图或许过度稠密→导致message passing价值太高(每次做message passing都需求对好几个节点做运算)
- 图或许太大→GPU装不下
- 事实上输入图很难恰好是适宜于GNN(图数据嵌入)的最优核算图
- 图增强办法
- 图特征:输入图短少特征→特征增强
- 图结构:
- 图过于稀少→添加虚拟节点/边
- 图过于稠密→在message passing时抽样街坊
- 图太大→在核算嵌入时抽样子图(在后续课程中会专门介绍怎么将GNN办法泛化到大型数据上scale up)
1.1 图特征增强Feature Augmentation
- 应对图上短少特征的问题(比方只要邻接矩阵),标准办法:
- constant:给每个节点赋常数特征
- one-hot:给每个节点赋仅有ID,将ID转化为独热编码向量的办法(即ID对应索引的元素为1,其他元素都为0)
- 两种办法的比较:
constant node feature | one-hot node feature | |
---|---|---|
表明才能 | 中等:一切节点都相同,但是GNN依然能够学到图结构信息 | 高:每个节点ID仅有,所以能够储存节点特有的信息 |
inductive才能 | 高:对新节点再赋这个常数就行 | 低:无法泛化到新节点上,由于对新节点再赋ID的话,GNN无法嵌入这个新ID |
核算力价值 | 低:只要一维特征 | 高:O(∥V∥)O(\|V\|) 维特征,无法使用到大型图上 |
适用状况 | 一切图,inductive | 小图,transductive |
- 应对GNN很难学到特定图结构的问题(假如不必特征专门加以区分,GNN就学不到这些特征):
- 举例:节点所处环上节点数cycle count这一属性 问题:由于度数相同(都是2),所以不管环上有多少个节点,GNN都会得到相同的核算图(二叉树),无法别离。 处理办法:加上cycle count这一特征(独热编码向量,节点数对应索引的元素为1,其他元素为0)。
- 其他常用于数据增强的特征:clustering coefficient,centrality(及任何 Lecture 23 中讲过的特征),PageRank4等
1.2 图结构增强Structure Augmentation
- 对稀少图:添加虚拟边virtual nodes或虚拟节点virtual edges
- 虚拟边:在2-hop街坊之间添加虚拟边 直觉:在GNN核算时不必邻接矩阵 AA,而用 A+A2A+A^2(A2A^2 的每个元素是对应节点对之间长度为2的途径数量3)5 适用典范:bipartite graphs6 如作者-论文组成的bipartite graph,添加虚拟边能够在协作作者或许同作者论文之间添加链接。 这样GNN能够浅一些,练习也会更快一些(由于在同类节点之间能够直接交互了) 但假如添的边太多了也会添加复杂性
- 虚拟节点:添加一个虚拟节点,这个虚拟节点与图(或许一个从图中选出的子图)上的一切节点相连 这会导致一切节点最长间隔变成2(节点A-虚拟节点-节点B) 长处:稀少图上message passing大幅提升
- 对稠密图:节点街坊抽样node neighborhood sampling7
在message passing的进程中,不使用一个节点的悉数街坊,而改为抽样一部分街坊。
举例来说,对每一层,在传播信息时随机选2个街坊,核算图就会从上图变成下图:
长处:核算图变小 缺点:或许会丢失重要信息(由于有的街坊直接不必了嘛)
能够每次抽样不同的街坊,以添加模型鲁棒性: - 节点街坊抽样示例8 咱们期望经抽样后,成果跟使用一切街坊的成果相似,但还能高效削减核算价值(在后续课程中会专门介绍怎么将GNN办法泛化到大型数据上scale up)。 实践证明效果很好。
2. Learning Objective
- 回忆一遍在 Lecture 71 第一节中讲过的学习方针部分:咱们怎么练习一个GNN模型?
- GNN练习pipeline 输入数据→用GNN练习数据→得到节点嵌入→prediction head(在不同粒度的使命下,将节点嵌入转化为终究需求的猜测向量)→得到猜测向量和标签→选取丢失函数→选取评价方针 (前三部分已经在本章及上章前文叙述过)
2.1 Prediction Head
- 不同粒度下的prediction head:节点等级,边等级,图等级
- 节点等级:直接用节点嵌入做猜测 GNN得到的节点嵌入 hv(L)\mathbf{h}_v^{(L)}:d维 猜测方针向量:k维(k-way prediction) 分类使命:在k个类别之间做分类 回归使命:在k个方针target / characteristic 上做回归 yv=Headnode(hv(L))=W(H)hv(L)\hat{\mathbf{y}}_v=\text{Head}_{\text{node}}(\mathbf{h}_v^{(L)})=\mathbf{W}^{(H)}\mathbf{h}_v^{(L)} W(H)∈Rk∗d\mathbf{W}^{(H)}\in\mathbb{R}^{k*d},将d维嵌入映射到k维输出
- 边等级:用节点嵌入对来做猜测
k-way prediction
yuv=Headedge(hu(L),hv(L))\hat{\mathbf{y}}_{uv}=\text{Head}_{\text{edge}}(\mathbf{h}_u^{(L)},\mathbf{h}_v^{(L)})
Headedge(hu(L),hv(L))\text{Head}_{\text{edge}}(\mathbf{h}_u^{(L)},\mathbf{h}_v^{(L)}) 的可选办法:
- concatenation+linear 这种办法在讲GAT1的时分介绍过,留意力机制 aa 能够用这种办法将节点对信息转化为留意力系数 ee。 yuv=Linear(Concat(hu(L),hv(L)))\hat{\mathbf{y}}_{uv}=\text{Linear}(\text{Concat}(\mathbf{h}_u^{(L)},\mathbf{h}_v^{(L)})) Linear(⋅)\text{Linear}(\cdot) 将2d维嵌入映射到k维输出
- 点积:yuv=(hu(L))Thv(L)\hat{\mathbf{y}}_{uv}=(\mathbf{h}_u^{(L)})^T\mathbf{h}_v^{(L)}
这种办法只能使用于1-way prediction(由于点积输出成果就一维嘛),例如链接猜测使命(猜测边是否存在)
使用到k-way prediction上:跟GAT中的多头留意力机制1相似,多算几组然后兼并(公式中的 W(1),…,W(k)\mathbf{W}^{(1)},…,\mathbf{W}^{(k)} 是可学习的参数):
… \\ \textcolor{brown}{\hat{\mathbf{y}}_{uv}^{(k)}}=(\mathbf{h}_u^{(L)})^T\textcolor{red}{\mathbf{W}^{(k)}}\mathbf{h}_v^{(L)} \\ \hat{\mathbf{y}}_{uv}=Concat(\textcolor{brown}{\hat{\mathbf{y}}_{uv}^{(1)}},…,\textcolor{brown}{\hat{\mathbf{y}}_{uv}^{(k)}})\textcolor{blue}{\in\mathbb{R}^k}$$![在这里刺进图片描绘](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/14da87253a37436cb49a5952e015ee36~tplv-k3u1fbpfcp-zoom-1.image) - 图等级:用图中一切节点的嵌入向量来做猜测
k-way prediction
yG=Headgraph({hv(L)∈Rd,∀v∈G})\hat{\mathbf{y}}_G=\text{Head}_{\text{graph}}(\{\mathbf{h}_v^{(L)}\in\mathbb{R}^d,\forall v\in G\})
Headgraph(⋅)\text{Head}_{\text{graph}}(\cdot) 与GNN单层中的 AGG(⋅)\text{AGG}(\cdot)1 相似,都是将若干嵌入聚合为一个嵌入。
Headgraph({hv(L)∈Rd,∀v∈G)\text{Head}_{\text{graph}}(\{\mathbf{h}_v^{(L)}\in\mathbb{R}^d,\forall v\in G) 的可选办法9:
- global mean pooling:yG=Mean({hv(L)∈Rd,∀v∈G})\hat{\mathbf{y}}_G=\textcolor{red}{\text{Mean}}(\{\mathbf{h}_v^{(L)}\in\mathbb{R}^d,\forall v\in G\})
- global max pooling:yG=Max({hv(L)∈Rd,∀v∈G})\hat{\mathbf{y}}_G=\textcolor{red}{\text{Max}}(\{\mathbf{h}_v^{(L)}\in\mathbb{R}^d,\forall v\in G\})
- global sum pooling:yG=Sum({hv(L)∈Rd,∀v∈G})\hat{\mathbf{y}}_G=\textcolor{red}{\text{Sum}}(\{\mathbf{h}_v^{(L)}\in\mathbb{R}^d,\forall v\in G\})
- 假如想比较不同巨细的图,mean办法或许比较好(由于成果不受节点数量的影响);假如关怀图的巨细等信息,sum办法或许比较好。
这些办法都在小图上表现很好。
但是在大图上的global pooling办法或许会面临丢失信息的问题。
举例:使用一维节点嵌入。 G1G_1 的节点嵌入为 {−1,−2,0,1,2}\{-1,-2,0,1,2\},G2G_2 的节点嵌入为 {−10,−20,0,10,20}\{-10,-20,0,10,20\},显然两个图的节点嵌入不同很大,图结构很不相同。 但是通过global sum pooling后: yG1=Sum({−1,−2,0,1,2})=0\hat{\mathbf{y}}_{G_1}=\text{Sum}(\{-1,-2,0,1,2\})=0 yG2=Sum({−10,−20,0,10,20})=0\hat{\mathbf{y}}_{G_2}=\text{Sum}(\{-10,-20,0,10,20\})=0 就这两个图的表明向量相同了,无法做出区分,这是不可的。 为了处理这一问题,处理办法是hierarchical global pooling:分层聚合节点嵌入。 举例:使用 ReLU(Sum(⋅))\text{ReLU}(\text{Sum}(\cdot)) 做聚合,先别离聚合前两个节点和后三个节点的嵌入,然后再聚合这两个嵌入。 G1G_1: 第一轮:ya=ReLU(Sum({−1,−2}))=0,yb=ReLU(Sum({0,1,2}))=3\textcolor{blue}{\hat{\mathbf{y}_a}=\text{ReLU}(\text{Sum}(\{-1,-2\}))=0},\textcolor{orange}{\hat{\mathbf{y}_b}=\text{ReLU}(\text{Sum}(\{0,1,2\}))=3} 第二轮:yG=ReLU(Sum({ya,yb}))=3\textcolor{red}{\hat{\mathbf{y}_G}=\text{ReLU}(\text{Sum}(\{\mathbf{y}_a,\mathbf{y}_b\}))=3} G2G_2: 第一轮:ya=ReLU(Sum({−10,−20}))=0,yb=ReLU(Sum({0,10,20}))=30\textcolor{blue}{\hat{\mathbf{y}_a}=\text{ReLU}(\text{Sum}(\{-10,-20\}))=0},\textcolor{orange}{\hat{\mathbf{y}_b}=\text{ReLU}(\text{Sum}(\{0,10,20\}))=30} 第二轮:yG=ReLU(Sum({ya,yb}))=30\textcolor{brown}{\hat{\mathbf{y}_G}=\text{ReLU}(\text{Sum}(\{\mathbf{y}_a,\mathbf{y}_b\}))=30} 这样咱们就能够将 G1G_1 和 G2G_2 作出区分了 一个hierarchical pooling的实际使用:DiffPool10(常规,我又没咋看懂) 大致来说,就是每一次先用一个GNN核算节点嵌入,然后用另一个GNN(这两个GNN能够同步运算)(两个GNN联合练习jointly train)核算节点归于哪一类,然后依照每一类对图进行池化。每一类得到一个表明向量,保留类间的链接,产生一个新的图。重复这一进程,直至得到终究的表明向量。 将图池化问题与社区发现问题相结合,用节点嵌入辨认社区→聚合社区内的节点得到community embeddings→用community embeddings辨认supercommunity→聚合supercommunity内的节点得到supercommunity embeddings……
2.2 Predictions & Labels
- 有监督问题的标签 & 无监督问题的信号
- 有监督学习supervise learning:直接给出标签(如一个分子图是药的概率) 无监督学习unsupervised learning / self-supervised learning:使用图自身的信号(如链接猜测:猜测两节点间是否有边) 有时这两种状况下的别离比较含糊,在无监督学习使命中也或许有“有监督使命”,如练习GNN以猜测节点clustering coefficient3
- 有监督学习的标签:依照实际状况而来
举例:
节点等级——引用网络中,节点(论文)归于哪一学科
边等级——交易网络中,边(交易)是否有欺诈行为
图等级——图(分子)是药的概率
主张将无监督学习使命规约到三种粒度下的标签猜测使命,由于这种猜测使命有许多已做过的工作可资参阅,会好做些。 例如聚类使命可视为节点归于某一类的猜测使命。 - 无监督学习的信号: 在没有外部标签时,能够使用图自身的信号来作为有监督学习的标签。举例来说,GNN能够猜测: 节点等级:节点统计量(如clustering coefficient3, PageRank4 等) 边等级:链接猜测(隐藏两节点间的边,猜测此处是否存在链接) 图等级:图统计量(如猜测两个图是否同构) 这些都是不需求外部标签的
2.3 丢失函数Loss Function
- 分类使命常用穿插熵,回归使命常用MSE
- 咱们用 y(i)\mathbf{\hat{y}}^{(i)} 和 y(i)\mathbf{y}^{(i)} 来统一指代各等级的猜测值和标签(ii 是观测编号)
- 分类使命的标签 y(i)\mathbf{y}^{(i)} 是离散数值,如节点分类使命的标签是节点归于哪一类。 回归使命的标签 y(i)\mathbf{y}^{(i)} 是接连数值,如猜测分子图是药的概率。 两种使命都能用GNN。其差异主要在于丢失函数和评价方针。
- 分类使命的丢失函数穿插熵 CE(y(i),y(i))=−∑j=1K(yj(i)logyj(i))\text{CE}\left(\mathbf{y}^{(i)},\mathbf{\hat{y}}^{(i)}\right)=-\sum_{j=1}^K\left(\mathbf{y}^{(i)}_j\log{\mathbf{\hat y}^{(i)}_j}\right)(ii 是观测序号,jj 是类别对应的维度索引) Loss=∑i=1NCE(y(i),y(i))\text{Loss}=\sum_{i=1}^N\text{CE}\left(\mathbf{y}^{(i)},\mathbf{\hat y}^{(i)}\right)
- 回归使命的丢失函数MSE / L2 loss MSE(y(i),y(i))=∑j=1K(yj(i)−yj(i))2\text{MSE}\left(\mathbf{y}^{(i)},\mathbf{\hat y}^{(i)}\right)=\sum_{j=1}^K\left(\mathbf{y}^{(i)}_j-\mathbf{\hat y}_j^{(i)}\right)^2(ii 是观测序号,jj 是类别对应的维度索引) Loss=∑i=1NMSE(y(i),y(i))\text{Loss}=\sum\limits_{i=1}^N\text{MSE}\left(\mathbf{y}^{(i)},\mathbf{\hat y}^{(i)}\right) MSE的长处:接连、易于微分……等
- 此外还有其他丢失函数,如maximum margin loss,适用于咱们关怀节点次序、不关怀具体数值而关怀其排行的状况11。
2.4 评价方针Evaluation Metrics
- evaluation metrics12:Accuracy和ROC AUC
- 回归使命 root mean square error (RMSE):∑i=1N(y(i)−y(i))2N\sqrt{\sum^N_{i=1}\dfrac{\left(\mathbf{y}^{(i)}-\mathbf{\hat y}^{(i)}\right)^2}{N}} mean absolute error (MAE):∑i=1N∣y(i)−y(i)∣N\dfrac{\sum^N_{i=1}\left|\mathbf{y}^{(i)}-\mathbf{\hat y}^{(i)}\right|}{N}
- 分类使命
- 多分类使命 accuracy:1[arg max(y(i))=y(i)]N\dfrac{1\left[\argmax(\mathbf{\hat y}^{(i)})=\mathbf{y}^{(i)}\right]}{N}
- 二分类使命
对分类阈值灵敏的评价方针:
(假如输出范围为 [0,1][0,1],咱们用0.5作为阈值)
accuracy
precision / recall
(由于数据不平衡时或许会呈现accuracy虚高的状况。比方99%的样本都是负样本,那么分类器只要猜测一切样本为负就能够获得99%的accuracy,但这没有意义。所以需求其他评价方针来处理这一问题)
对分类阈值不灵敏的评价方针:ROC AUC 二元分类的评价方针(可参阅 sklearn.metrics.classification_report — scikit-learn 0.24.2 documentation): accuracy(分类正确的观测占一切观测的份额) precision(猜测为正的样本中真的为正(猜测正确)的样本所占份额) recall(真的为正的样本中猜测为正(猜测正确)的样本所占份额) F1-Score(precision和recall的谐和平均值,信息抽取、文本挖掘等范畴常用) 混淆矩阵
ROC曲线:TPR(recall)和FPR之间的权衡(对角斜线说明是随机分类器) ROC AUC ROC曲线下面积。越高越好,0.5是随机分类器,1是完美分类器。 随机抽取一个正样本和一个负样本,正样本被辨认为正样本的概率比负样本被辨认为正样本的概率高的概率。
2.5 切分数据集
- 将数据集切分为练习集、验证集、测验集
- fixed / random split fixed split:只切分一次数据集,此后一向使用这种切分办法 random split:随机切分数据集,使用多次随机切分后核算成果的平均值
- 咱们期望三部分数据之间没有穿插,即留出法hold-out data13。 但由于图结构的特殊性,假如直接像一般数据相同切分图数据集,咱们或许不能保证测验集阻隔于练习集:就是说,测验集里边的数据或许与练习集里边的数据有边相连,在message passing的进程中就会相互影响,导致信息走漏。
- 处理办法1:transductive setting 输入全图在一切split中可见。仅切分(节点)标签。
- 处理办法2:inductive setting 去掉各split之间的链接,得到多个相互无关的图。这样不同split之间的节点就不会相互影响。
- transductive setting / inductive setting
transductive setting:
①测验集、验证集、练习集在同一个图上,整个数据集由一张图构成
②全图在一切split中可见。
③仅适用于节点/边猜测使命。
inductive setting: ①测验集、验证集、练习集别离在不同图上,整个数据集由多个图构成。 ②每个split只能看到split内的图。成功的模型应该能够泛化到没见过的图上。 ③适用于节点/边/图猜测使命。 - 示例:节点分类使命 transductive:各split可见全图结构,但只能观察到所属节点的标签 inductive:切分多个图,假如没有多个图就将一个图切分红3部分、并去除各部分之间连接的边
- 示例:图猜测使命 只适用inductive setting,将不同的图划分到不同的split中。
- 示例:链接猜测使命
使命方针:猜测出缺失的边。
这是个 unsupervised / self-supervised 使命,需求自行树立标签、自主切分数据集。
需求隐藏一些边,然后让GNN猜测边是否存在。
在切分数据集时,咱们需求切分两次。 第一步:在原图中将边分为message edges(用于GNN message passing)和supervision edges(作为GNN的猜测方针)。只留下message edges,不将supervision edges传入GNN。 第二步:切分数据集 办法1:inductive link prediction split 划分出3个不同的图组成的split,每个split里的边依照第一步分红message edges和supervision edges 办法2:transductive link prediction split(链接猜测使命的默认设置办法) 在一张图中进行切分:在练习时要留出验证集/测验集的边,并且留意边既是图结构又是标签,所以还要留出supervision edges(要不然还搞啥呢……) 具体来说: 练习:用 training message edges 猜测 training supervision edges 验证:用 training message edges 和 training supervision edges 猜测 validation edges 测验:用 training message edges 和 training supervision edges 和 validation edges 猜测 test edges 是个链接越来越多,图变得越来越稠密的进程。这是由于在练习进程之后,supervision edges就被GNN获知了,所以在验证时就要使用 supervision edges 来进行 message passing(测验进程逻辑相似) 不同论文中链接猜测的数据集切分办法或许不同。
2.6 GNN Training Pipeline
3. GNN design space 总结
Footnotes
-
可参阅我撰写的笔记:cs224w(图机器学习)2021冬天课程学习笔记9 Graph Neural Networks 2: Design Space ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7
-
可参阅我撰写的笔记:cs224w(图机器学习)2021冬天课程学习笔记7 Graph Neural Networks 1: GNN Model ↩
-
可参阅我撰写的笔记:cs224w(图机器学习)2021冬天课程学习笔记2: Traditional Methods for ML on Graphs ↩ ↩2 ↩3 ↩4
-
可参阅我撰写的笔记:cs224w(图机器学习)2021冬天课程学习笔记4 Link Analysis: PageRank (Graph as Matrix) ↩ ↩2
-
教师在课上讲,假如邻接矩阵不是方阵,就用 AATAA^T 或 ATAA^TA ……我妹搞懂,邻接矩阵还能不是方阵??? ↩
-
可参阅我撰写的笔记:cs224w(图机器学习)2021冬天课程学习笔记1 Introduction; Machine Learning for Graphs ↩
-
Hamilton et al. Inductive Representation Learning on Large Graphs, NeurIPS 2017 ↩
-
Ying et al. Graph Convolutional Neural Networks for Web-Scale Recommender Systems, KDD 2018 ACM网址 论文下载地址 ↩
-
K. Xu*, W. Hu*, J. Leskovec, S. Jegelka. How Powerful Are Graph Neural Networks, ICLR 2019 ↩
-
Ying et al. Hierarchical Graph Representation Learning with Differentiable Pooling, NeurIPS 2018 其他参阅资料: ①[DIFFPOOL] – Hierarchical Graph Representation Learning with Differentiable Pooling 图分类 NeurIPS 2018_知行合一,止于至善-CSDN博客_diffpool ↩
-
这个我查了一下,如同专门有个ranking loss,还有hinge loss什么的,我简略看了一下感觉有点难,由于在这里没用到所以我还没看。今后看。 ↩
-
可参阅sklearn官方文档:3.3. Metrics and scoring: quantifying the quality of predictions — scikit-learn 0.24.2 documentation ↩
-
可参阅:模型评价办法之held-out data(留出法)_上帝是个娘们的博客-CSDN博客_held-out ↩