Graph Neural Network(GAE,GVAE,ARGA)

前面几次的整理GCNGATGraphSAGE等等都适合在半监督,监督的场景下,而有没有图方法可以使用于在无监督的场景下使用呢?去发现节点的内在结果,挖掘隐藏关系如链接预测等等任务。

答案是:自编码器(AE) /变分自编码器(VAE)+Graph
在这里插入图片描述
Graph Auto-Encoders (GAE)
GAE的目的是通过encoder-decoder 的结构去获取到图中节点的 embedding,然后再去做具体的下游任务比如链接预测。

首先回顾一下自编码器,它是利用神经网络将数据逐层降维压缩,相当于让每层神经网络之间的激活函数就起到了将"线性"转化为"非线性"的作用,然后尝试还原输入即让输出==输出以捕捉到数据的隐含信息。整体的结构分编码器Decoder和解码器Encoder,编码器负责压缩,解码器负责还原。同样的,想要在Graph上也完成这种操作,也是使用encoder-decoder 的结构,具体操作如上图:

  • Encoder。直接使用 GCN 作为 encoder,来得到节点的 latent representations(即关于每个节点的 embedding)
    Z = G C N ( A ) Z=GCN(A) Z=GCN(A) 其中A是邻接矩阵,Z代表的就是所有节点的表示,如果接下来要做下游任务也是直接使用这个表示就可以。

  • Decoder。这里和原来的AE不一样,不是对称结构的网络,而是直接采用内积 inner-product 作为 decoder 来重构(reconstruct)原始的Graph
    A ′ = σ ( Z T Z ) A'=\sigma (Z^TZ) A=σ(ZTZ)这里的A’就是重构(reconstruct)出来的邻接矩阵,可以被理解为两个节点的独立事件概率相乘。

  • 最后的目标是使重构出的邻接矩阵与原始的邻接矩阵尽可能的相似,因为邻接矩阵决定了图的结构。所以直接采用交叉熵作为损失函数衡量A和A’就可以了
    L = − 1 N ∑ y l o g y ′ + ( 1 − y ) l o g ( 1 − y ′ ) L=-\frac{1}{N}\sum ylogy'+(1-y)log(1-y') L=N1ylogy+(1y)log(1y)
    其中y代表邻接矩阵 A 中某个元素的值(0 或 1),y’ 代表重构的邻接矩阵A’中相应元素的值(概率值)。

pytorch_geomatric的实现:

class EncoderGCN(nn.Module): #编码器
    def __init__(self, n_total_features, n_latent, p_drop=0.):
        super(EncoderGCN, self).__init__()
        self.n_total_features = n_total_features
        self.conv1 = GCNConv(self.n_total_features, 11)
        self.act1=nn.Sequential(nn.ReLU(),
                              nn.Dropout(p_drop))
        self.conv2 = GCNConv(11, 11)
        self.act2 = nn.Sequential(nn.ReLU(),
                              nn.Dropout(p_drop))
        self.conv3 = GCNConv(11, n_latent)

    def forward(self, data): #实践中一般采取多层的GCN来编码
        x, edge_index = data.x, data.edge_index
        x = self.act1(self.conv1(x, edge_index))
        x = self.act2(self.conv2(x, edge_index))
        x = self.conv3(x, edge_index) #经过三层GCN后得到节点的表示
        return x
        
class DecoderGCN(nn.Module): #解码器
    def __init__(self):
        super(DecoderGCN, self).__init__()
        
    def forward(self, z):
        A = torch.mm(z, torch.t(z)) #直接算点积
        A = torch.sigmoid(A) #映射成分数
        return A

完整逐行的中文源码阅读笔记可以参考:https://github.com/nakaizura/Source-Code-Notebook/tree/master/GAE

GAE和AE的区别

  • GAE在encoder过程中使用了 n∗n 矩阵的卷积核
  • GAE在decoder部分实际上没有解码,直接计算内积算邻接矩阵的相似度,然后用loss来约束

在这里插入图片描述
GVAE
上面的 GAE 用于重建(数据压缩和还原)效果还不错,但是如果用于直接的图生成就不够了,所以同样的AE不行,那VAE来试一下。VGAE 的思想和变分自编码器(VAE)很像,博主已经仔细推导过就不再赘述,大致的想法是:利用隐变量(latent variables),让模型学习出一些分布(distribution),再从这些分布中采样得到z,通过这样的z就会有多样化的结果,而不仅仅是还原,重建。

如上图,其与GAE的不同只在Encoder的部分,后面的Decoder还是用内积基本是一样的,对于编码器即在GAE中是直接使用GCN作为编码器,它是一个确定的函数所以只能得到确定的结果。而在VGAE中,不再使用这样的函数得到Z,而是从一个多维的高斯分布中采样得到,即用GCN确定分布,再从分布中采样Z。

  • Encoder。而这样的分布,使用两个GCN来分别得到高斯分布的均值和方差就行了,即VGAE 利用GCN来分别计算均值和方差:
    u = G C N u ( X , A ) u=GCN_u(X,A) u=GCNu(X,A) σ = G C N σ ( X , A ) \sigma=GCN_{\sigma}(X,A) σ=GCNσ(X,A) 再将使其与 noise(随机生成的变量)相乘,相加,便得到高斯分布上采样到的一个Z z = u + ϵ × σ z=u+\epsilon \times \sigma z=u+ϵ×σ
  • Decoder和GAE是一样的,只是由于使用了变分的思想,所以损失函数变成了: l o s s = E q ( Z ∣ X , A ) [ l o g p ( A ∣ Z ) ] − K L [ Q ( Z ∣ X , A ) ∣ ∣ p ( Z ) ] loss=E_{q(Z|X,A)} [log p(A|Z)]-KL[Q(Z|X,A)||p(Z)] loss=Eq(ZX,A)[logp(AZ)]KL[Q(ZX,A)p(Z)]变分下界写出的优化目标,第一项是期望,第二项是 KL 散度,详细推导在这里
class EncoderGCN(nn.Module): #和GAE的一样
    def __init__(self, n_total_features, n_latent, p_drop=0.):
        super(EncoderGCN, self).__init__()
        self.n_total_features = n_total_features
        self.conv1 = GCNConv(self.n_total_features, 11)
        self.act1=nn.Sequential(nn.ReLU(),
                              nn.Dropout(p_drop))
        self.conv2 = GCNConv(11, 11)
        self.act2 = nn.Sequential(nn.ReLU(),
                              nn.Dropout(p_drop))
        self.conv3 = GCNConv(11, n_latent)

    def forward(self, data):
        x, edge_index = data.x, data.edge_index
        x = self.act1(self.conv1(x, edge_index))
        x = self.act2(self.conv2(x, edge_index))
        x = self.conv3(x, edge_index)
        return x

def reparametrize(self, mean, log_std): #通过mean和std得到z
    if self.training:
        return mean + torch.randn_like(log_std) * torch.exp(log_std)
    else:
        return mean

def encode(self, *args, **kwargs):
    self.mean, self.log_std = self.encoder(*args, **kwargs) #两个GCN分别得到mean和std
    z = self.reparametrize(self.mean, self.log_std) #得到z
    return z

ARGA
编码器是否真的能够习得一个高斯分布?上GAN吧…即把模型分为生成器和判别器两部分,让两者对抗训练。

  • 生成器直接使用GAE,输出还原的图A’
  • 判别器使用成对比较咯,即将正例和负例同时输入到神经网络中,由判别器直接尝试区分这两者
class Discriminator(nn.Module):
    def __init__(self, n_input):
        super(Discriminator, self).__init__()
        # 判别器是3层FC
        self.fcs = nn.Sequential(nn.Linear(n_input,40),
                                 nn.ReLU(),
                                 nn.Linear(40,30),
                                 nn.ReLU(),
                                 nn.Linear(30,1),
                                 nn.Sigmoid())
        
    def forward(self, z):
        return self.fcs(z)
    
class ARGA(nn.Module):
    def __init__(self, n_total_features, n_latent):
        super(ARGA, self).__init__()
        #这里的encode和decoder都是GAE的东西,一起作为生成器
        self.encoder = EncoderGCN(n_total_features, n_latent)
        self.decoder = DecoderGCN()
        self.discriminator = Discriminator(n_latent)
        
    def forward(self, x):
        z_fake = self.encoder(x)
        z_real=torch.randn(z_fake.size())
        A = self.decoder(z_fake) #得到生成的A
        # 让判别器区分真 与 假。
        d_real=self.discriminator(z_real)
        d_fake=self.discriminator(z_fake)
        return A, d_real, d_fake
    
    def simulate(self, x): #训练完成后可以用来生成更好的A
        z_fake = self.encoder(x)
        A = self.decoder(z_fake)
        return A

其实除了这几份工作外,可以无监督的表示学习方法还有SDNE这种,而使用GAN的思想,其实也有做的更充分的工作比如GraphGAN,所以好像相比较之下,这三个算法更适合做链接预测,用于推荐系统之类的,比如GCMC

  • 23
    点赞
  • 114
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
### 回答1: 神经网络 (Graph Neural Network) 是一种特殊的深度学习模型,专门用于处理结构数据。它能够学习中节点之间的关系,并用于预测、分类和聚类等任务。神经网络通常由多层节点卷积和卷积层组成。 ### 回答2: 神经网络Graph Neural Network,GNN)是一种能够对数据进行分类、预测和嵌入学习的机器学习模型。数据包括节点、边和孤立的子,将它们组成一个网络结构,每个节点和边都带有相应的特征信息。 与传统的人工神经网络不同,神经网络的输入不仅仅是简单的向量,而是形结构本身。通过对节点和边进行信息传递和聚合,GNN能够对整个进行全局性的推断和预测。常见的GNN模型有Graph Convolutional Networks(GCN)、Graph Attention Networks(GAT)、GraphSAGE等。 GNN具有以下特点: 1. 局部性:GNN通过每个节点的邻居信息消除了数据中的局部性质,实现了节点之间的信息传递和聚合,能够快速学习到具有相似特征的节点之间的关系。 2. 结构性:GNN能够充分利用中的结构信息,包括节点的邻居信息、度数分布等,实现了对数据的有效利用。 3. 可扩展性:GNN可以处理大规模的数据,对于具有高维特征的节点和边,也能够进行有效的特征提取和计算。 由于GNN能够有效地处理高维、复杂的数据,近年来被广泛应用于社交网络分析、化学分子编码、语言模型等领域。尤其在社交关系分析、推荐系统等领域,GNN已经成为一种非常流行的机器学习模型。 ### 回答3: 神经网络是一种针对非欧几里德结构数据建模和推理的神经网络框架。传统的神经网络只能有效处理欧几里德结构数据,而对于更具复杂性质的非欧几里德结构数据如、网络、句法树等则存在不足。神经网络的主要目标是捕捉上的结构信息和节点之间的关系,以便更好地推理和预测上的节点属性、边属性和全局属性。 神经网络可以由三个部分组成:节点表示、边表示、以及聚合函数。节点表示可以使用传统的基于节点的特征,例如离散特征、连续特征、形特征。边表示通常是通过将节点特征组合来获得的边表征。聚合函数是在每个节点处执行的算法,这使得网络可以聚合邻居节点,从而输出每个节点的嵌入表示。 有多种类型的神经网络,其中最常见的是卷积神经网络(GCN)和注意力网络(GAT)。GCN使用卷积操作聚合节点邻居,然后通过多层GCN堆叠来输出节点嵌入。而GAT使用注意力机制对节点和边进行加权,得到相应的嵌入表示。另外,还有GraphSAGE、Graph Convolutional Policy Network (GCPP)等多种神经网络模型,其适用范围和性能各异。 总体而言,神经网络是一种新颖的深度学习模型,可用于处理非欧几里德结构数据。它们已在像分类、推荐系统、社交网络和分子化学等领域中取得了成功,并且在未来的研究中有很大的潜力。
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值